Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing on POS USB printer from dart/flutter

On an Android Flutter project I need to print on USB POS printers and for testing I have an Epson TM-T20. Sending raw bytes would be ideal. flutter_usb_write package does not work (write returns false) and its status is a bit concerning (no sound null-safety yet, the homepage is in Croatian and there is no issue tracker).

Are there any other options?

Future<void> printOnPOS(String text) async {
  // text = String.fromCharCodes([27, 64]) + text; // Initialize printer
  text += "\r\n";
  try {
    var flutterUsbWrite = FlutterUsbWrite();
    List<UsbDevice> devices = await flutterUsbWrite.listDevices();
    print("devices: $devices");
    var device = devices[1]; // this picks the printer, checked correct
    var port = await flutterUsbWrite.open(
      vendorId: device.vid,
      productId: device.pid,
    );
    print("port: $port");
    var rw = await flutterUsbWrite.write(Uint8List.fromList(text.codeUnits));
    print("rw: $rw");
    await flutterUsbWrite.close();
  } on PlatformException catch (e) {
    print(e.message);
  }
}

Output:

I/flutter ( 7763): devices: [UsbDevice: e0f-3 VMware Virtual USB Mouse, VMware null, UsbDevice: 4b8-e03 TM-T20, EPSON 405551460005550000]
I/flutter ( 7763): port: UsbDevice: 4b8-e03 TM-T20, EPSON 405551460005550000
I/flutter ( 7763): rw: false
D/UsbDeviceConnectionJNI( 7763): close
like image 572
user643005 Avatar asked Sep 01 '25 10:09

user643005


1 Answers

after many attempts I found the working solution for printing on POS printers connected to the device (tested on Windows and Android).

First of all, I've used:

  1. https://pub.dev/packages/pdf - for generating pdf's files with receipts;
  2. https://pub.dev/packages/printing - for getting information about available printers and print the receipt on the terminal;

So the logic is next: First of all, you need to fetch information about connected printers, for that you can write something like that:

Future<List<Printer>> findPrinters() async {
   return await Printing.listPrinters();
}

Next, you need a function that will prepare a PDF document, thanks to the developers of the pdf package, because we can use constants for sizing our document (mm, cm, inches, etc), note that 'pw' is 'import 'package:pdf/widgets.dart' as pw;':

 final doc = pw.Document();
 // 58mm width receipt
 const width = 2.28346457 * PdfPageFormat.inch;
 const height = 300.0 * PdfPageFormat.mm;
 const pageFormat = PdfPageFormat(width, height);

Also if you want to make your 'pdf' document take any height, based on its content, you should also use pw.MultiPage(), but lets take a look on the full example:

Future<void> print(Printer? printer) async {
   if (printer == null) return;

   final doc = pw.Document();
   const width = 2.28346457 * PdfPageFormat.inch;
   const height = 300.0 * PdfPageFormat.mm;
   const pageFormat = PdfPageFormat(width, height);

   final textStyle = pw.TextStyle(
      fontSize: 12.0,
      color: PdfColor.fromHex("#000000"),
   );

   doc.addPage(
      pw.MultiPage(
         pageFormat: pageFormat,
         build: (pw.Context context) {
            return [
               pw.Row(
                  children: [
                     pw.Expanded(
                        child: pw.Text(
                           'Testing',
                            style: textStyle,
                        ),
                     ),
                  ],
               ),
            ];
         },
      ),
   );

   final res = await Printing.directPrintPdf(
     printer: printer!,
     // don't use doc.document.save() - it's not working, even with MS pdf printers
     onLayout: (_) => doc.save(),
     format: pageFormat,
     usePrinterSettings: true,
   );

   if (res) {
      Logger().i("Printed!");
   } else {
      Logger().i("Error");
   }
}

I've tested it on rongta rp58, working fine

like image 138
Dmytro Stefurak Avatar answered Sep 02 '25 22:09

Dmytro Stefurak