从dart/flutter在POS USB打印机上打印



在一个Android Flutter项目上,我需要在USB POS打印机上打印,为了测试,我有一个Epson TM-T20。发送原始字节将是理想的选择。flutter_usb_write包不工作(write返回false(,其状态有点令人担忧(还没有健全的零安全,主页是克罗地亚语,没有问题跟踪器(。

还有其他选择吗?

Future<void> printOnPOS(String text) async {
// text = String.fromCharCodes([27, 64]) + text; // Initialize printer
text += "rn";
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);
}
}

输出:

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

经过多次尝试,我找到了在连接到设备的POS打印机上打印的有效解决方案(在Windows和Android上测试(。

首先,我使用过:

  1. https://pub.dev/packages/pdf-用于生成带有收据的pdf文件
  2. https://pub.dev/packages/printing-用于获取可用打印机的信息并在终端上打印收据

因此逻辑如下:首先,你需要获取有关连接的打印机的信息,为此你可以写这样的东西:

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

接下来,感谢PDF包的开发人员,您需要一个准备PDF文档的函数,因为我们可以使用常量来调整文档大小(mm、cm、英寸等(,请注意">pw"是">导入"包:PDF/widgets.dart"作为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);

此外,如果你想让你的">pdf"文档根据其内容采用任何高度,你也应该使用pw.MultiPage((,但让我们来看看完整的例子:

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");
}
}

我已经在rong ta rp58上测试过了,运行良好

事实证明,一个小的更改就能使flutter_usb_write工作。

FlutterUsbWritePlugin.java中,我们在方法write:中有这个

if (this.ep != null && this.mInterface != null && this.m_Connection != null) {
transferResult = this.m_Connection.bulkTransfer(this.ep, bytes, bytes.length, 0);
} else {
if (this.m_Connection.claimInterface(this.mInterface, true)) {
transferResult = this.m_Connection.bulkTransfer(this.ep, bytes, bytes.length, 0);
}
}

if中的表达式计算为true,然后对bulkTransfer的调用失败。

如果我们强制执行else块,字节将被发送到打印机。

我对claimInterface文档的理解是,在写入设备之前需要使用此方法。

这个包的一个分支,迁移到听起来为null的安全性,现在就在这里了。

最新更新