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!
flutter pub add sunmi_task_printer- Write text (with or without style)
- Change font size
- Insert line breaks
- Draw horizontal lines
- Enable or disable bold mode
- Print various types of barcodes (see enum below)
- Print QR codes with custom width and error level
- Print images from assets or the web (example demonstrates both)
- Print rows like receipts with custom width and alignment
- Combine with existing ESC/POS code
- Cut paper - Dedicated method for cutting paper
- Get the printer's serial number
- Get the printer's version
- Get the paper size (0: 80mm, 1: 58mm)
- LCD: Print an image
- LCD: Print a string with multiple lines (double lines)
- Open the cash drawer
- Check if the cash drawer is connected
- Get the number of times the cash drawer was opened
- Real-time device status listener for hardware failures (Out of paper, overheating, etc.)
Sunmi V2 Pro
Sunmi T2 mini
Sunmi V2S
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 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');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();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();
}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);This package is a modernized fork of sunmi_printer_plus.