sunmi_task_printer
Important
THIS PACKAGE WILL WORK ONLY IN ANDROID!
It supports Sunmi devices and Null Safety. I developed this Flutter plugin based on the following: Official Sunmi Inner Printer Doc.
However, not all methods from the documentation were included in this package because I don't have access to all the equipment. If you have the equipment and can assist, please contact me on GitHub!
Installation
flutter pub add sunmi_task_printer
What this package does
xWrite text (with or without style)xChange font sizexInsert line breaksxDraw horizontal linesxEnable or disable bold modexPrint various types of barcodes (see enum below)xPrint QR codes with custom width and error levelxPrint images from assets or the web (example demonstrates both)xPrint rows like receipts with custom width and alignmentxCombine with existing ESC/POS codexCut paper - Dedicated method for cutting paperxGet the printer's serial numberxGet the printer's versionxGet the paper size (0: 80mm, 1: 58mm)xLCD: Print an imagexLCD: Print a string with multiple lines (double lines)xOpen the cash drawerxCheck if the cash drawer is connectedxGet the number of times the cash drawer was openedReal-time device status listener for hardware failures (Out of paper, overheating, etc.)
Tested Devices
Sunmi V2 Pro
Sunmi T2 mini
Sunmi V2S
Setup & Initialization
Note: As of
v0.1.0, this package utilizes a robust, non-blocking asynchronous queue. You * must*awaityour commands to ensure the hardware processes the transaction buffer correctly.
import 'package:sunmi_task_printer/sunmi_task_printer.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Bind the hardware printer layer immediately upon startup
await SunmiTaskPrinter.bindingService();
runApp(const MyApp());
}
Fetching Device Info
// Fetching hardware metadata
final int paperSize = await SunmiTaskPrinter.paperSize();
final String version = await SunmiTaskPrinter.printerVersion();
final String serial = await SunmiTaskPrinter.serialNumber();
print('Size: $paperSize, Version: $version, Serial: $serial');
Printing a Transaction (Receipt)
To prevent the printer from pausing between commands, wrap your layout inside a transaction buffer:
await SunmiTaskPrinter.initPrinter();
await SunmiTaskPrinter.startTransactionPrint(true);
await SunmiTaskPrinter.setAlignment(SunmiPrintAlign.CENTER);
await SunmiTaskPrinter.printText('CUSTOMER RECEIPT', style: const SunmiStyle(bold: true));
await SunmiTaskPrinter.line();
await SunmiTaskPrinter.printRow(cols: [
ColumnMaker(text: 'Item', width: 12, align: SunmiPrintAlign.LEFT),
ColumnMaker(text: 'Qty', width: 6, align: SunmiPrintAlign.CENTER),
ColumnMaker(text: 'Total', width: 6, align: SunmiPrintAlign.RIGHT),
]);
await SunmiTaskPrinter.lineWrap(2);
// Force the printer to commit and push the paper out
await SunmiTaskPrinter.submitTransactionPrint();
Listening to Hardware Errors (EventChannel) (WIP)
You can listen to real-time mechanical failures (e.g., printer ran out of paper mid-receipt) by subscribing to the hardware stream:
late StreamSubscription _hardwareErrorSubscription;
@override
void initState() {
super.initState();
_hardwareErrorSubscription = SunmiTaskPrinter.hardwareErrorStream.listen((error) {
final errorType = error['type'];
final errorMessage = error['message'];
print("[PRINTER FAULT]: $errorType - $errorMessage");
// Show an alert dialog to the cashier to fix the paper roll!
});
}
@override
void dispose() {
_hardwareErrorSubscription.cancel();
super.dispose();
}
ESC/POS Compatibility
You can also combine this package with the esc_pos_utils package.
With this package, you can create custom ESC/POS commands, eliminating the need for additional commands. This is beneficial if you already have code that is compatible with other printers, as you can reuse that code effortlessly.
final Uint8List escPosData = // ... generate your ESC/POS bytes
await SunmiTaskPrinter.printRawData(escPosData);
Inspiration
This package is a modernized fork of sunmi_printer_plus.