bluetooth_thermal_printer
空安全
https://pub.dev/packages/esc_pos_utils_plus
空安全
https://pub.dev/packages/bluetooth_thermal_printer
两个配合, 还是无法打印图片, 结论: 打印机不支持,这个方式.
bluetooth_thermal_printer: ^0.0.6
esc_pos_utils: ^1.0.0
import 'dart:async';import 'package:bluetooth_thermal_printer/bluetooth_thermal_printer.dart';import 'package:esc_pos_utils/esc_pos_utils.dart';import 'package:flutter/material.dart';void main() {runApp(MyApp());}class MyApp extends StatefulWidget {@override_MyAppState createState() => _MyAppState();}class _MyAppState extends State<MyApp> {@overridevoid initState() {super.initState();}bool connected = false;List availableBluetoothDevices = [];Future<void> getBluetooth() async {final List bluetooths = await BluetoothThermalPrinter.getBluetooths;print("Print $bluetooths");setState(() {availableBluetoothDevices = bluetooths;});}Future<void> setConnect(String mac) async {final String result = await BluetoothThermalPrinter.connect(mac);print("state conneected $result");if (result == "true") {setState(() {connected = true;});}}Future<void> printTicket() async {String isConnected = await BluetoothThermalPrinter.connectionStatus;if (isConnected == "true") {List<int> bytes = await getTicket();final result = await BluetoothThermalPrinter.writeBytes(bytes);print("Print $result");} else {//Hadnle Not Connected Senario}}Future<void> printGraphics() async {String isConnected = await BluetoothThermalPrinter.connectionStatus;if (isConnected == "true") {List<int> bytes = await getGraphicsTicket();final result = await BluetoothThermalPrinter.writeBytes(bytes);print("Print $result");} else {//Hadnle Not Connected Senario}}Future<List<int>> getGraphicsTicket() async {List<int> bytes = [];CapabilityProfile profile = await CapabilityProfile.load();final generator = Generator(PaperSize.mm80, profile);// Print QR Code using native functionbytes += generator.qrcode('example.com');bytes += generator.hr();// Print Barcode using native functionfinal List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];bytes += generator.barcode(Barcode.upcA(barData));bytes += generator.cut();return bytes;}Future<List<int>> getTicket() async {List<int> bytes = [];CapabilityProfile profile = await CapabilityProfile.load();final generator = Generator(PaperSize.mm80, profile);// Print image// final ByteData data = await rootBundle.load('assets/rabbit_black.jpg');// final Uint8List bytes = data.buffer.asUint8List();// final Image image = decodeImage(bytes);// ticket.image(image);bytes += generator.text("////=========================================================================================///",styles: PosStyles(align: PosAlign.center,height: PosTextSize.size2,width: PosTextSize.size2,),linesAfter: 1);bytes += generator.text("18th Main Road, 2nd Phase, J. P. Nagar, Bengaluru, Karnataka 560078",styles: PosStyles(align: PosAlign.center));bytes += generator.text('Tel: +919591708470',styles: PosStyles(align: PosAlign.center));bytes += generator.hr();bytes += generator.row([PosColumn(text: 'No',width: 1,styles: PosStyles(align: PosAlign.left, bold: true)),PosColumn(text: 'Item',width: 5,styles: PosStyles(align: PosAlign.left, bold: true)),PosColumn(text: 'Price',width: 2,styles: PosStyles(align: PosAlign.center, bold: true)),PosColumn(text: 'Qty',width: 2,styles: PosStyles(align: PosAlign.center, bold: true)),PosColumn(text: 'Total',width: 2,styles: PosStyles(align: PosAlign.right, bold: true)),]);bytes += generator.row([PosColumn(text: "1", width: 1),PosColumn(text: "Tea",width: 5,styles: PosStyles(align: PosAlign.left,)),PosColumn(text: "10",width: 2,styles: PosStyles(align: PosAlign.center,)),PosColumn(text: "1", width: 2, styles: PosStyles(align: PosAlign.center)),PosColumn(text: "10", width: 2, styles: PosStyles(align: PosAlign.right)),]);bytes += generator.row([PosColumn(text: "2", width: 1),PosColumn(text: "Sada Dosa",width: 5,styles: PosStyles(align: PosAlign.left,)),PosColumn(text: "30",width: 2,styles: PosStyles(align: PosAlign.center,)),PosColumn(text: "1", width: 2, styles: PosStyles(align: PosAlign.center)),PosColumn(text: "30", width: 2, styles: PosStyles(align: PosAlign.right)),]);bytes += generator.row([PosColumn(text: "3", width: 1),PosColumn(text: "Masala Dosa",width: 5,styles: PosStyles(align: PosAlign.left,)),PosColumn(text: "50",width: 2,styles: PosStyles(align: PosAlign.center,)),PosColumn(text: "1", width: 2, styles: PosStyles(align: PosAlign.center)),PosColumn(text: "50", width: 2, styles: PosStyles(align: PosAlign.right)),]);bytes += generator.row([PosColumn(text: "4", width: 1),PosColumn(text: "Rova Dosa",width: 5,styles: PosStyles(align: PosAlign.left,)),PosColumn(text: "70",width: 2,styles: PosStyles(align: PosAlign.center,)),PosColumn(text: "1", width: 2, styles: PosStyles(align: PosAlign.center)),PosColumn(text: "70", width: 2, styles: PosStyles(align: PosAlign.right)),]);bytes += generator.hr();bytes += generator.row([PosColumn(text: 'TOTAL',width: 6,styles: PosStyles(align: PosAlign.left,height: PosTextSize.size4,width: PosTextSize.size4,)),PosColumn(text: "160",width: 6,styles: PosStyles(align: PosAlign.right,height: PosTextSize.size4,width: PosTextSize.size4,)),]);bytes += generator.hr(ch: '=', linesAfter: 1);// ticket.feed(2);bytes += generator.text('Thank you!',styles: PosStyles(align: PosAlign.center, bold: true));bytes += generator.text("26-11-2020 15:22:45",styles: PosStyles(align: PosAlign.center), linesAfter: 1);bytes += generator.text('Note: Goods once sold will not be taken back or exchanged.',styles: PosStyles(align: PosAlign.center, bold: false));bytes += generator.cut();return bytes;}@overrideWidget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text('Bluetooth Thermal Printer Demo'),),body: Container(padding: EdgeInsets.all(20),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text("Search Paired Bluetooth"),TextButton(onPressed: () {this.getBluetooth();},child: Text("Search"),),Container(height: 200,child: ListView.builder(itemCount: availableBluetoothDevices.length > 0? availableBluetoothDevices.length: 0,itemBuilder: (context, index) {return ListTile(onTap: () {String select = availableBluetoothDevices[index];List list = select.split("#");// String name = list[0];String mac = list[1];this.setConnect(mac);},title: Text('${availableBluetoothDevices[index]}'),subtitle: Text("Click to connect"),);},),),SizedBox(height: 30,),TextButton(onPressed: connected ? this.printGraphics : null,child: Text("Print"),),TextButton(onPressed: connected ? this.printTicket : null,child: Text("Print Ticket"),),],),),),);}}
esc_pos_bluetooth
非空安全
https://pub.dev/packages/bluetooth_print
测试 无法启动.
网络打印, 不支持蓝牙, pdf 可转图片
https://pub.dev/packages/printing
