Flutter扩展打印机功能插件sunmi_ext_printer的使用
Flutter扩展打印机功能插件sunmi_ext_printer的使用
支持Sunmi外部打印机,基于Sunmi官方SDK文档。
主要功能
- 打印文本
- 打印图像
- 打印二维码
- 打印条形码
- 打印表格
- 纸张切割
- 纸张进纸
- 对齐方式:
- 左对齐,居中对齐,右对齐
- 样式:
- 加粗,X轴和Y轴坐标缩放
- 发送原始数据
- 查找蓝牙打印机
- 对于蓝牙权限,应在Flutter应用内处理,例如使用
permission_handler
插件
- 对于蓝牙权限,应在Flutter应用内处理,例如使用
示例
查找已配对的蓝牙设备
Set<String> _bluetoothIds = {};
void findBleDevices() async {
var res = await pos.findBleDevice();
Set<String> ids = {};
if (res != null) {
for (var i = 0; i < res.length; i++) {
ids.add('${res[i]}');
}
}
setState(() {
_bluetoothIds = ids;
});
}
打印文本
// 请将deviceID更改为扫描结果中的蓝牙地址
var deviceID = '74:F7:F:FD:41:0D';
final pos = SunmiExtPrinter();
await pos.setPrinter(SunmiPrinter.SunmiBlueToothPrinter, deviceID);
await pos.connectPrinter();
await pos.setAlignMode(AlignMode.Center);
await pos.printText("Rubybear\n");
打印二维码
await pos.lineWrap();
await pos.printQrCode("https://edesoft.com/en.html");
await pos.lineWrap();
打印图像
var bytes = await rootBundle.load('images/logo.png');
var buf = bytes.buffer.asUint8List();
await pos.printImage(buf);
await pos.lineWrap();
确保在pubspec.yaml
中定义了资产:
assets:
- images/logo.png
确保images/logo.png
文件存在于正确的文件夹中。
[可选] 您可能需要在发送到打印机之前调整图像大小,以防止打印过大。可以使用image
包来完成此操作。例如:
import 'package:image/image.dart' as img;
Future<Uint8List> _convertImage(Uint8List imageBytes, int? printWidth, int? printHeight, bool invert) async {
var cmd = img.Command()
..decodeImage(imageBytes)
..grayscale();
await cmd.executeThread();
if (printWidth == null && printHeight == null) {
printWidth = 256;
}
cmd.copyResize(width: printWidth, height: printHeight);
if (invert) {
cmd.invert();
}
cmd.encodeBmp();
await cmd.executeThread();
var bitmapBytes = cmd.outputBytes ?? imageBytes;
return bitmapBytes;
}
打印表格
await pos.enableBold(true);
await pos.printColumnsText(["Item", "Qty", "Amt"], [18, 6, 8], [0, 2, 2]);
await pos.enableBold(false);
await pos.printColumnsText(["Carlsberg Bottle", "2", "20.00"], [18, 6, 8], [0, 2, 2]);
await pos.printColumnsText(["Milk 2L", "1", "3.50"], [18, 6, 8], [0, 2, 2]);
页面切割
await pos.cutPaper(PaperCutMode.FullCut);
刷新
await pos.flush();
示例代码
以下是完整的示例代码,展示了如何使用sunmi_ext_printer
插件进行打印机操作:
import 'package:flutter/material.dart';
import 'package:sunmi_ext_printer/enums.dart';
import 'package:sunmi_ext_printer/sunmi_ext_printer.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter/services.dart' show PlatformException, rootBundle;
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Set<String> _bluetoothIds = {};
[@override](/user/override)
void initState() {
super.initState();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Printer example app'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(
height: 20,
),
ElevatedButton.icon(
onPressed: () => permitBleThenFind(context),
icon: const Icon(Icons.search),
label: const Text("搜索蓝牙打印机")),
for (var id in _bluetoothIds) BluetoothRow(id),
],
)),
),
);
}
void permitBleThenFind(BuildContext context) async {
var ok = await Permission.bluetooth.request().isGranted &&
await Permission.bluetoothConnect.request().isGranted;
if (ok) {
findBleDevices();
}
}
void findBleDevices() async {
var res = await SunmiExtPrinter().findBleDevice();
Set<String> ids = {};
if (res != null) {
for (var i = 0; i < res.length; i++) {
ids.add('${res[i]}');
}
}
setState(() {
_bluetoothIds = ids;
});
}
}
class BluetoothRow extends StatefulWidget {
final String deviceID;
const BluetoothRow(this.deviceID, {super.key});
[@override](/user/override)
State<BluetoothRow> createState() => _BluetoothRowState();
}
class _BluetoothRowState extends State<BluetoothRow> {
bool _isRunning = false;
_BluetoothRowState();
Future<void> _print() async {
setState(() {
_isRunning = true;
});
try {
printReceipt(widget.deviceID);
} on PlatformException catch (ex) {
_showMyDialog(context, 'Error', ex.message);
} catch (ex) {
_showMyDialog(context, 'Unknown Error', ex);
} finally {
setState(() {
_isRunning = false;
});
}
}
Future<void> printReceipt(deviceID) async {
final pos = SunmiExtPrinter();
await pos.setPrinter(SunmiPrinter.SunmiBlueToothPrinter, deviceID);
await pos.connectPrinter();
await pos.setAlignMode(AlignMode.Center);
await pos.setFontZoom(2, 2);
await pos.enableBold(true);
await pos.printText("Rubybear\n");
await pos.lineWrap();
await pos.setFontZoom(1, 1);
await pos.enableBold(false);
await pos.printText("1888 Super Road\nWanda Plaza\nShanghai, China\n");
await pos.lineWrap();
var bytes = await rootBundle.load('images/logo.png');
var buf = bytes.buffer.asUint8List();
await pos.printImage(buf);
await pos.lineWrap();
await pos.enableBold(true);
await pos.printText("Retail Invoice\n");
await pos.lineWrap();
await pos.enableBold(false);
await pos.setAlignMode(AlignMode.Left);
await pos.printText("Date: 09/15/2022, 15:35\n");
await pos.printText("Payment Mode: AliPay\n");
await pos.printText("--------------------------------\n");
await pos.enableBold(true);
await pos.printColumnsText(["Item", "Qty", "Amt"], [18, 6, 8], [0, 2, 2]);
await pos.enableBold(false);
await pos.printColumnsText(
["Carlsberg Bottle", "2", "20.00"], [18, 6, 8], [0, 2, 2]);
await pos.printColumnsText(["Milk 2L", "1", "3.50"], [18, 6, 8], [0, 2, 2]);
await pos
.printColumnsText(["Ice Cream", "5", "20.00"], [18, 6, 8], [0, 2, 2]);
await pos.printText("--------------------------------\n");
await pos.enableBold(true);
await pos.printColumnsText(["TOTAL", "43.50"], [16, 16], [0, 2]);
await pos.setAlignMode(AlignMode.Center);
await pos.enableBold(false);
await pos.lineWrap();
await pos
.printText("This is your official receipt\nThank you come again!\n");
await pos.printText("Please scan and check more\n");
await pos.lineWrap();
await pos.printQrCode("https://edesoft.com/en.html");
await pos.lineWrap(n: 4);
await pos.cutPaper(PaperCutMode.FullCut);
await pos.flush();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10),
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(widget.deviceID),
const SizedBox(
width: 5,
),
ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colors.purple),
onPressed: _isRunning ? null : _print,
child:
Text(_isRunning ? 'Connecting...' : 'Connect and Print')),
],
)));
}
}
Future<void> _showMyDialog(BuildContext context, String title, body,
[String okText = "OK", cancelText = "Cancel", bool showCancel = false]) {
return showDialog<String>(
context: context,
builder: (BuildContext context) => AlertDialog(
title: Text(title),
content: Text(body),
actions: [
Visibility(
visible: showCancel,
child: TextButton(
onPressed: () => Navigator.pop(context, cancelText),
child: Text(cancelText),
)),
TextButton(
onPressed: () => Navigator.pop(context, okText),
child: Text(okText),
),
],
),
);
}
更多关于Flutter扩展打印机功能插件sunmi_ext_printer的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter扩展打印机功能插件sunmi_ext_printer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
sunmi_ext_printer
是一个用于在 Flutter 应用程序中与商米(Sunmi)打印机进行交互的插件。它允许开发者通过 Flutter 应用程序控制商米打印机的打印功能,例如打印文本、图像、条形码等。
以下是如何在 Flutter 项目中使用 sunmi_ext_printer
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 sunmi_ext_printer
插件的依赖:
dependencies:
flutter:
sdk: flutter
sunmi_ext_printer: ^1.0.0 # 请根据实际情况使用最新版本
然后运行 flutter pub get
以安装依赖。
2. 初始化打印机
在使用打印机之前,需要先初始化打印机。你可以在应用程序启动时或需要使用打印机时进行初始化。
import 'package:sunmi_ext_printer/sunmi_ext_printer.dart';
void initPrinter() async {
bool isPrinterReady = await SunmiExtPrinter.initPrinter();
if (isPrinterReady) {
print("Printer initialized successfully");
} else {
print("Failed to initialize printer");
}
}
3. 打印文本
初始化打印机后,你可以使用 printText
方法打印文本。
void printText() async {
bool isPrinted = await SunmiExtPrinter.printText("Hello, World!");
if (isPrinted) {
print("Text printed successfully");
} else {
print("Failed to print text");
}
}
4. 打印图像
你还可以使用 printImage
方法打印图像。图像需要转换为 Uint8List
格式。
import 'dart:typed_data';
import 'package:flutter/services.dart';
void printImage(String imagePath) async {
ByteData imageData = await rootBundle.load(imagePath);
Uint8List imageBytes = imageData.buffer.asUint8List();
bool isImagePrinted = await SunmiExtPrinter.printImage(imageBytes);
if (isImagePrinted) {
print("Image printed successfully");
} else {
print("Failed to print image");
}
}
5. 打印条形码
使用 printBarcode
方法可以打印条形码。
void printBarcode(String barcode) async {
bool isBarcodePrinted = await SunmiExtPrinter.printBarcode(barcode);
if (isBarcodePrinted) {
print("Barcode printed successfully");
} else {
print("Failed to print barcode");
}
}
6. 切纸
打印完成后,你可以使用 cutPaper
方法进行切纸操作。
void cutPaper() async {
bool isPaperCut = await SunmiExtPrinter.cutPaper();
if (isPaperCut) {
print("Paper cut successfully");
} else {
print("Failed to cut paper");
}
}
7. 设置打印样式
你可以设置文本的字体、对齐方式、大小等样式。
void setPrintStyle() async {
await SunmiExtPrinter.setAlign(SunmiExtPrinterAlign.CENTER);
await SunmiExtPrinter.setFontSize(24);
await SunmiExtPrinter.setBold(true);
}
8. 清理资源
在不再使用打印机时,可以调用 destroyPrinter
方法来释放资源。
void destroyPrinter() async {
bool isDestroyed = await SunmiExtPrinter.destroyPrinter();
if (isDestroyed) {
print("Printer resources released");
} else {
print("Failed to release printer resources");
}
}
9. 错误处理
在实际使用中,可能会遇到打印失败的情况。你可以通过捕获异常来处理这些错误。
void printWithErrorHandling() async {
try {
await SunmiExtPrinter.printText("Hello, World!");
} catch (e) {
print("Failed to print: $e");
}
}