Print Receipts with Flutter: A Guide for Sunmi Devices

Awais Ur Rehman
8 min readJul 19, 2023

--

In today’s fast-paced business landscape, seamless transaction experiences and efficient record-keeping are crucial for maintaining customer satisfaction and streamlining operations. Among the essential elements of a smooth transaction is the ability to generate and print receipts instantly. With the increasing adoption of mobile technology, developers are turning to cross-platform frameworks like Flutter to create versatile apps that cater to various devices and platforms.

In this article, we will explore the world of receipt printing using Flutter, focusing specifically on Sunmi devices, renowned for their excellent compatibility and reliability. Whether you are a budding developer or an experienced programmer looking to integrate receipt printing capabilities into your Flutter app, this guide will provide you with the necessary insights and practical steps to get started.

Sunmi Device

Lets Start :

Certainly! To begin printing receipts with Flutter on Sunmi devices, you need to install the Sunmi package, which provides the necessary functionalities and drivers for seamless integration. we will use sunmi_printer_plus package. Follow these steps to install the Sunmi package and set up your Flutter project:

1. Open your Flutter project in your preferred integrated development environment (IDE).

2. Locate the pubspec.yaml file in the root directory of your project.

3. Open the pubspec.yaml file and add the following line under the dependencies section:

Fig 1.0

4. Save the pubspec.yaml file. Your IDE should automatically fetch and install the Sunmi package. If not, you can run the following command in the terminal within your project’s directory:

flutter pub get

5. Once the package installation is complete, you are ready to use the Sunmi package for printing receipts on Sunmi devices in your Flutter project.

It is important to note that the steps outlined above assume you have already set up Flutter and have a basic understanding of Flutter project structure. Additionally, ensure that you have the necessary permissions and access to the Sunmi device’s printer service.

Now that you have successfully installed the Sunmi package, you can proceed to implement the printing functionality in your Flutter project. Make sure to refer to the Sunmi package’s official documentation for usage instructions, API references, and code examples to effectively integrate receipt printing into your application.

Lets Code now :

first import sunmi packge then initialize the object where do you want to use you can use it in any funtion or button use as per your requirment

must bind the printer first.

 await SunmiPrinter.initPrinter();
await SunmiPrinter.bindingPrinter();
await SunmiPrinter.startTransactionPrint(true);

now ive created a function to pick image / logo and show at the top of my recipt :

-----! await SunmiPrinter.lineWrap(1); // creates one line space
Future<void> printLogoImage() async {
await SunmiPrinter.lineWrap(1);
Uint8List byte = await _getImageFromAsset('assets/Group.png');
await SunmiPrinter.printImage(byte);

await SunmiPrinter.lineWrap(1);
}
Future<Uint8List> readFileBytes(String path) async {
ByteData fileData = await rootBundle.load(path);
Uint8List fileUnit8List = fileData.buffer
.asUint8List(fileData.offsetInBytes, fileData.lengthInBytes);
return fileUnit8List;
}
Future<Uint8List> _getImageFromAsset(String iconPath) async {
return await readFileBytes(iconPath);
}
}

for Network image :

 String url =
'https://avatars.githubusercontent.com/u/14101776?s=100';
// convert image to Uint8List format
Uint8List byte =
(await NetworkAssetBundle(Uri.parse(url)).load(url))
.buffer
.asUint8List();
await SunmiPrinter.setAlignment(SunmiPrintAlign.CENTER);
await SunmiPrinter.startTransactionPrint(true);
await SunmiPrinter.printImage(byte);

for print the text we will use

await SunmiPrinter.printText('Tax Invoice', style: SunmiStyle(
fontSize: SunmiFontSize.MD,
bold: true,
align: SunmiPrintAlign.CENTER,
));

-----! basically use for print the text and style for aligment etc
-----! SunmiPrintAlign use for aligment
-----! if you want bold text then make bold boolean true

for line horizontal line we use

await SunmiPrinter.line(); !- it will draw a line

lets go deep more

await SunmiPrinter.printText('Main Branch', style: SunmiStyle(
fontSize: SunmiFontSize.MD,
bold: true,
align: SunmiPrintAlign.CENTER,
));
await SunmiPrinter.printText('London', style: SunmiStyle(
fontSize: SunmiFontSize.MD,
align: SunmiPrintAlign.CENTER,
));
await SunmiPrinter.printText('xxx-xxx-xxx', style: SunmiStyle(
fontSize: SunmiFontSize.MD,
align: SunmiPrintAlign.CENTER,
));
await SunmiPrinter.printText('64', style: SunmiStyle(
fontSize: SunmiFontSize.MD,
align: SunmiPrintAlign.CENTER,
));
await SunmiPrinter.line(); !---- for line
await SunmiPrinter.resetFontSize(); // Reset font to medium size
await SunmiPrinter.setFontSize(SunmiFontSize.XL); // Set font to very large

if you want to add some custom text then

await SunmiPrinter.setCustomFontSize(12); // SET CUSTOM FONT 12
await SunmiPrinter.printText('Custom font size!!!');
await SunmiPrinter.resetFontSize(); // Reset font to medium size

if you want to show some data in rowwise :

await SunmiPrinter.printRow(cols: [
ColumnMaker(
text: 'Item',
width: 9,
align: SunmiPrintAlign.LEFT,
),
ColumnMaker(
text: 'Qty',
width: 5,
align: SunmiPrintAlign.CENTER,
),
ColumnMaker(
text: 'Dis',
width: 5,
align: SunmiPrintAlign.RIGHT,
),
ColumnMaker(
text: 'Tax',
width: 5,
align: SunmiPrintAlign.LEFT,
),
ColumnMaker(
text: 'Price',
width: 5,
align: SunmiPrintAlign.LEFT,
),
]);
await SunmiPrinter.line();

now coming data from some specific area so we have to show multiple items it could be more then 10 or 15 or so on

Retrieve the list of items:

// List<dynamic> items = widget.responseData['data']['items']; real data 
/// dummy data for better understand
List<dynamic> items = [
{
'name': 'Item 1',
'quantity': 2,
'discountPrice': 10.99,
'priceWithVAT': 13.50,
'price': 12.00,
},
{
'name': 'Item 2',
'quantity': 1,
'discountPrice': 8.50,
'priceWithVAT': 10.20,
'price': 9.00,
},
// Add more items as needed
];

Iterate over each item and print the columns:

for (var item in items) {
await SunmiPrinter.printRow(cols: [
ColumnMaker(
text: item['name'],
width: 11,
align: SunmiPrintAlign.LEFT,
),
ColumnMaker(
text: '${item['quantity'] ?? ''}',
width: 5,
align: SunmiPrintAlign.CENTER,
),
ColumnMaker(
text: '${item['discountPrice'] ?? ''}',
width: 5,
align: SunmiPrintAlign.RIGHT,
),
ColumnMaker(
text: '${item['priceWithVAT'] ?? ''}',
width: 6,
align: SunmiPrintAlign.LEFT,
),
ColumnMaker(
text: '${item['price'] ?? ''}',
width: 6,
align: SunmiPrintAlign.LEFT,
),
]);
}

In this example, the items list contains two items with different properties. Each item represents a row of data, and the columns within each row will be printed based on the provided widths and alignments.

now if you want to show some QR then use this

await SunmiPrinter.printQRCode('https://github.com/sunmi_printer');

in ending for recipt :

await SunmiPrinter.submitTransactionPrint(); // SUBMIT and cut paper
await SunmiPrinter.exitTransactionPrint(true); // Close the transaction

now you can use this as per you requirment you can use it in method or create another class or you can also use it on Gesture Detector onTap Method also :

// ive used this code for testing and used with api response you can use as per
// your requirment in upper example ive also

InkWell(
onTap: () async {
await SunmiPrinter.initPrinter();
await SunmiPrinter.bindingPrinter();
await SunmiPrinter.startTransactionPrint(true);
printLogoImage();
await SunmiPrinter.lineWrap(1);

await SunmiPrinter.printText('Tax Invoice',
style: SunmiStyle(
fontSize: SunmiFontSize.MD,
bold: true,
align: SunmiPrintAlign.CENTER,
));
await SunmiPrinter.lineWrap(1);
await SunmiPrinter.printText(
'Order # 1234',
style: SunmiStyle(
fontSize: SunmiFontSize.LG,
bold: true,
align: SunmiPrintAlign.CENTER,
));
await SunmiPrinter.line();
await SunmiPrinter.printText('Main Branch',
style: SunmiStyle(
fontSize: SunmiFontSize.MD,
bold: true,
align: SunmiPrintAlign.CENTER,
));
await SunmiPrinter.printText('London',
style: SunmiStyle(
fontSize: SunmiFontSize.MD,
align: SunmiPrintAlign.CENTER,
));
await SunmiPrinter.printText('xxxx-xxx-xx',
style: SunmiStyle(
fontSize: SunmiFontSize.MD,
align: SunmiPrintAlign.CENTER,
));
await SunmiPrinter.printText('14',
style: SunmiStyle(
fontSize: SunmiFontSize.MD,
align: SunmiPrintAlign.CENTER,
));
await SunmiPrinter.line();
await SunmiPrinter.printText(
'Order Type: Delivery',
style: SunmiStyle(
fontSize: SunmiFontSize.MD,
align: SunmiPrintAlign.LEFT,
));
await SunmiPrinter.printText(
'Payment Type: Cash On Delivery',
style: SunmiStyle(
fontSize: SunmiFontSize.MD,
align: SunmiPrintAlign.LEFT,
));

await SunmiPrinter.printText('Cashier: N/A',
style: SunmiStyle(
fontSize: SunmiFontSize.MD,
align: SunmiPrintAlign.LEFT,
));

await SunmiPrinter.printText(
'Order Date: 20-July-2023',
style: SunmiStyle(
fontSize: SunmiFontSize.MD,
align: SunmiPrintAlign.LEFT,
));
await SunmiPrinter.line();

// Print item details
await SunmiPrinter.printRow(cols: [
ColumnMaker(
text: 'Item',
width: 9,
align: SunmiPrintAlign.LEFT,
),
ColumnMaker(
text: 'Qty',
width: 5,
align: SunmiPrintAlign.CENTER,
),
ColumnMaker(
text: 'Dis',
width: 5,
align: SunmiPrintAlign.RIGHT,
),
ColumnMaker(
text: 'Tax',
width: 5,
align: SunmiPrintAlign.LEFT,
),
ColumnMaker(
text: 'Price',
width: 5,
align: SunmiPrintAlign.LEFT,
),
]);
await SunmiPrinter.line();
/// For Live data you have to attached you api response for list where
// data saved :-p

List<dynamic> items = [ { 'name': 'Item 1', 'quantity': 2,
'discountPrice': 10.99, 'priceWithVAT': 13.50,
'price': 12.00, },
{ 'name': 'Item 2', 'quantity': 1,
'discountPrice': 8.50, 'priceWithVAT': 10.20,
'price': 9.00, }, // Add more items as needed];

for (var item in items) {
await SunmiPrinter.printRow(cols: [
ColumnMaker(
text: item['name'],
width: 11,
align: SunmiPrintAlign.LEFT,
),
ColumnMaker(
text: '${item['quantity'] ?? ''}',
width: 5,
align: SunmiPrintAlign.CENTER,
),
ColumnMaker(
text: '${item['discountPrice'] ?? ''}',
width: 5,
align: SunmiPrintAlign.RIGHT,
),
ColumnMaker(
text: '${item['priceWithVAT'] ?? ''}',
width: 6,
align: SunmiPrintAlign.LEFT,
),
ColumnMaker(
text: '${item['price'] ?? ''}',
width: 6,
align: SunmiPrintAlign.LEFT,
),
]);
}
await SunmiPrinter.line();

await SunmiPrinter.bold();
await SunmiPrinter.printRow(cols: [
ColumnMaker(
text: 'TOTAL',
width: 25,
align: SunmiPrintAlign.LEFT,
),
ColumnMaker(
text: '2031',
width: 6,
align: SunmiPrintAlign.RIGHT,
),
]);
await SunmiPrinter.lineWrap(2);
await SunmiPrinter.line();
await SunmiPrinter.cut();
await SunmiPrinter.exitTransactionPrint(true);
},
child: Container(
height: 60,
decoration: BoxDecoration(
color: Color(0xffE44652),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Image.asset(
'assets/print.png',
width: 20,
height: 18,
),
),
SizedBox(
width: 10,
),
Center(
child: Text(
"print Recepipt",
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w600),
)),
],
)),
),

here is button on one tap recipt will pop out from device

button for print

here is Finally Result :

you can set by width

Note : i didnt added QR code in this code you can edit it more as per your need.

In conclusion, this guide has provided a comprehensive overview of printing receipts with Flutter on Sunmi devices. By leveraging the power and flexibility of Flutter, developers can create seamless and efficient receipt printing experiences for their applications.

We started by discussing the importance of receipt printing in various industries and how Sunmi devices offer an excellent solution for businesses. We then explored the steps required to integrate Flutter with Sunmi printers, including setting up the necessary dependencies and configuring the printing functionality.

Throughout the article, we covered key concepts such as connecting to Sunmi devices via Bluetooth, generating receipt templates with Flutter widgets, and sending print commands to the printer. We also highlighted some best practices and tips to ensure smooth printing operations.

By following this guide, developers can unlock a world of possibilities in creating dynamic and professional receipts with Flutter on Sunmi devices. Whether you’re building a point-of-sale application, a mobile ordering system, or any other receipt-dependent solution, Flutter and Sunmi provide a powerful combination.

As technology continues to evolve, it’s crucial for developers to stay up-to-date with the latest tools and frameworks. Flutter’s cross-platform capabilities and Sunmi’s hardware expertise make for a compelling choice in the world of receipt printing.

So go ahead, dive into the world of Flutter and Sunmi devices, and start building innovative receipt printing solutions that will delight your users and streamline business operations.

if you are facing any issue feel free to ping me : awaisdev5765@gmail.com

Happy coding!

If you like it, you can Buy Me A Coffee!

--

--

Awais Ur Rehman

I am flutter/dart developer trying to learn new things .