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");
  }
} 
        
       
             
             
            

