amoLink / bluetooth_print_plus

A flutter plugin for bluetooth thermal printer support Android & iOS
MIT License
11 stars 4 forks source link

How to Print Text on Multiple Lines in Bluetooth Print Plus? #27

Closed seetherisingazeez closed 1 week ago

seetherisingazeez commented 2 weeks ago

Hello!

I'm currently using the Bluetooth Print Plus Flutter package to print text to my thermal printer. However, I'm encountering an issue where longer text is overflowing and not printing correctly.

Could you please provide guidance on how to format text to print on multiple lines? Any examples or best practices for handling text wrapping would be greatly appreciated.

Thank you for your help!

amoLink commented 2 weeks ago

What type of cmd

seetherisingazeez commented 1 week ago

I'm trying to print using the TSC command.

seetherisingazeez commented 1 week ago

UPDATE I wrote a helper class myself to address this issue. Here's the code if anyone needs it.

 
import 'dart:math';
import 'dart:typed_data';
import 'package:bluetooth_print_plus/bluetooth_print_plus.dart';

class PrintResolver {
  final int copies;

  // Constructor with bluetoothPrint and copies as required arguments
  const PrintResolver({
    required this.copies,
  });

  Future getPrintCommand(List items,
      {int fontWidth = 8, int paperWidth = 300}) async {
    final int lineHeight =
        20; // Approximate height for one line of text (you can adjust this based on your printer's text height)

    final tscCommand = TscCommand();
    await tscCommand.cleanCommand();

    // Calculate the number of characters that can fit in a single line
    final maxCharsPerLine = paperWidth ~/
        fontWidth; // Divide by fontWidth to get the max characters that fit on one line

    // Create a buffer to hold wrapped text
    String wrappedText = "";

    // Wrap each item
    for (var item in items) {
      wrappedText += "${wrapText(item, maxCharsPerLine)}\n";
    }

    // Calculate the height of the printout based on the number of lines
    int totalLines = wrappedText.split('\n').length;
    final height = totalLines * lineHeight;

    // Send the print command to the printer
    await tscCommand.size(width: paperWidth, height: height); // Dynamic height
    await tscCommand.cls();
    await tscCommand.speed(8);
    await tscCommand.density(8);

    int yPosition = 0; // Start printing from top (0, 0)

    // Print each line of wrapped text
    for (var line in wrappedText.split('\n')) {
      await tscCommand.text(content: line, x: 0, y: yPosition);
      yPosition += lineHeight; // Move down for the next line
    }

    await tscCommand.print(copies);
    final cmd = await tscCommand.getCommand();
    return cmd;
  }

// Helper function to wrap text based on the max characters per line
  String wrapText(String text, int maxCharsPerLine) {
    final List lines = [];
    int start = 0;

    while (start < text.length) {
      int end = min(start + maxCharsPerLine, text.length);
      lines.add(text.substring(start, end));
      start = end;
    }

    return lines.join('\n');
  }
}
 
amoLink commented 1 week ago

UPDATE I wrote a helper class myself to address this issue. Here's the code if anyone needs it.

import 'dart:math'; import 'dart:typed_data'; import 'package:bluetooth_print_plus/bluetooth_print_plus.dart';

class PrintResolver { final int copies;

// Constructor with bluetoothPrint and copies as required arguments const PrintResolver({ required this.copies, });

Future getPrintCommand(List items, {int fontWidth = 8, int paperWidth = 300}) async { final int lineHeight = 20; // Approximate height for one line of text (you can adjust this based on your printer's text height)

final tscCommand = TscCommand();
await tscCommand.cleanCommand();

// Calculate the number of characters that can fit in a single line
final maxCharsPerLine = paperWidth ~/
    fontWidth; // Divide by fontWidth to get the max characters that fit on one line

// Create a buffer to hold wrapped text
String wrappedText = "";

// Wrap each item
for (var item in items) {
  wrappedText += "${wrapText(item, maxCharsPerLine)}\n";
}

// Calculate the height of the printout based on the number of lines
int totalLines = wrappedText.split('\n').length;
final height = totalLines * lineHeight;

// Send the print command to the printer
await tscCommand.size(width: paperWidth, height: height); // Dynamic height
await tscCommand.cls();
await tscCommand.speed(8);
await tscCommand.density(8);

int yPosition = 0; // Start printing from top (0, 0)

// Print each line of wrapped text
for (var line in wrappedText.split('\n')) {
  await tscCommand.text(content: line, x: 0, y: yPosition);
  yPosition += lineHeight; // Move down for the next line
}

await tscCommand.print(copies);
final cmd = await tscCommand.getCommand();
return cmd;

}

// Helper function to wrap text based on the max characters per line String wrapText(String text, int maxCharsPerLine) { final List lines = []; int start = 0;

while (start < text.length) {
  int end = min(start + maxCharsPerLine, text.length);
  lines.add(text.substring(start, end));
  start = end;
}

return lines.join('\n');

} }

This is a solution. TSC has a block instruction that can wrap lines, but some printers do not support it, so I do not plan to add it