Flutter热敏打印机控制插件esc_pos_gen的使用

Flutter热敏打印机控制插件esc_pos_gen的使用

esc_pos_gen 是一个用于生成热敏打印机 ESC/POS 命令的库。该库提供了声明式的风格来创建打印内容。

特性

  • 📝 声明式风格(就像创建 Flutter 小部件一样)
  • 📰 表格打印(使用 PosRow
  • 😎 文本样式:
    • 大小、对齐方式、加粗、反向、下划线、不同字体、旋转 90°
  • 📸 打印图像
  • 🔠 打印条形码:
    • UPC-A, UPC-E, JAN13 (EAN13), JAN8 (EAN8), CODE39, ITF (Interleaved 2 of 5), CODABAR (NW-7), CODE128
  • ✂️ 纸张切割(部分切割、全切割)
  • 🚗 发出蜂鸣声(不同持续时间)
  • 📃 纸张进纸、回退

注意:您的打印机可能不支持所有上述功能(如某些样式、部分或全纸张切割、条形码等)。

创建打印内容

简单的带样式的打印内容

List<int> generatePaper() {
  final CapabilityProfile profile = await CapabilityProfile.load();
  final Generator generator = Generator(
    PaperSize.mm58,
    profile,
  );

  final List<PosComponent> components = [
    const PosText.center('My Store'),
    const PosSeparator(),
    PosList.builder(
      count: 20,
      builder: (int i) {
        return PosList(
          [
            PosRow.leftRightText(
              leftText: 'Product $i',
              rightText: 'US\$ $i',
            ),
            PosRow.leftRightText(
              leftText: '1 x US\$ $i',
              leftTextStyles: const PosStyles.defaults(
                fontType: PosFontType.fontB,
              ),
              rightText: 'US\$ $i',
              rightTextStyles: const PosStyles.defaults(
                align: PosAlign.right,
                fontType: PosFontType.fontB,
              ),
            ),
          ],
        );
      },
    ),
    const PosSeparator(),
    PosBarcode.code128('{A12345'.split('')),
    const PosSeparator(),
    const PosFeed(1),
    const PosCut(),
  ];

  final Paper paper = Paper(
    generator: generator,
    components: components,
  );

  return paper.bytes;
}

使用组件委托的简单打印内容

class StoreSocialMediaLinks extends PosDelegate {
  const StoreSocialMediaLinks();

  PosComponent build(Generator generator) {
    return PosList([
      PosRow.leftRightText(
        leftText: 'Instagram',
        leftTextStyles: const PosStyles.defaults(
          fontType: PosFontType.fontB,
        ),
        rightText: '@iandi.s',
        rightTextStyles: const PosStyles.defaults(
          align: PosAlign.right,
          fontType: PosFontType.fontB,
        ),
      ),
      PosRow.leftRightText(
        leftText: 'Github',
        leftTextStyles: const PosStyles.defaults(
          fontType: PosFontType.fontB,
        ),
        rightText: 'github.com/iandi.s',
        rightTextStyles: const PosStyles.defaults(
          align: PosAlign.right,
          fontType: PosFontType.fontB,
        ),
      ),
    ]);
  }
}

List<int> generatePaper() {
  final CapabilityProfile profile = await CapabilityProfile.load();
  final Generator generator = Generator(
    PaperSize.mm58,
    profile,
  );

  final List<PosComponent> components = [
    const PosText.center('My Social Media Links'),
    const PosSeparator(),
    const PosComponent.delegate(StoreSocialMediaLinks()),
    const PosSeparator(),
    const PosFeed(1),
    const PosCut(),
  ];

  final Paper paper = Paper(
    generator: generator,
    components: components,
  );

  return paper.bytes;
}

打印表格行

PosRow([
  PosColumn(
    text: 'col3',
    width: 3,
    styles: PosStyles(
      align: PosAlign.center,
      underline: true,
    ),
  ),
  PosColumn(
    text: 'col6',
    width: 6,
    styles: PosStyles(
      align: PosAlign.center,
      underline: true,
    ),
  ),
  PosColumn(
    text: 'col3',
    width: 3,
    styles: PosStyles(
      align: PosAlign.center,
      underline: true,
    ),
  ),
]);

打印图像

此包实现了三种 ESC/POS 函数:

  • ESC * - 列格式打印
  • GS v 0 - 位图格式打印(已过时)
  • GS ( L - 位图格式打印

注意,您的打印机可能只支持其中的一些函数。

import 'dart:io';

import 'package:esc_pos_gen/esc_pos_gen.dart';
import 'package:image/image.dart';

final ByteData data = await rootBundle.load('assets/logo.png');
final Uint8List bytes = data.buffer.asUint8List();
final Image image = decodeImage(bytes);
// 使用 `ESC *`
PosImage(image: image);
// 使用 `GS v 0` (已过时)
PosImage.raster(image: image);
// 使用 `GS ( L`
PosImage.raster(
  image: image,
  imageFn: PosImageFn.graphics,
);

打印条形码

final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
PosBarcode(Barcode.upcA(barData));
// 或者
// PosBarcode.upcA(barData);

打印二维码

使用原生 ESC/POS 命令:

PosQRCode('example.com');

如果您的打印机不支持原生命令,则可以将二维码作为图像打印。首先添加依赖项:

dependencies:
  qr_flutter: ^4.0.0
  path_provider: ^2.0.0

然后使用以下代码:

String qrData = "google.com";
const double qrSize = 200;
try {
  final uiImg = await QrPainter(
    data: qrData,
    version: QrVersions.auto,
    gapless: false,
  ).toImageData(qrSize);
  final dir = await getTemporaryDirectory();
  final pathName = '${dir.path}/qr_tmp.png';
  final qrFile = File(pathName);
  final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List());
  final img = decodeImage(imgFile.readAsBytesSync());

  return PosImage(image: img);
} catch (e) {
  print(e);
}

使用代码表

不同的打印机支持不同的代码表集。一些打印机型号在 CapabilityProfile 类中定义。因此,如果您想更改默认代码表,重要的是选择正确的配置文件:

// Xprinter XP-N160I
final profile = await CapabilityProfile.load('XP-N160I');
final generator = Generator(PaperSize.mm80, profile);
bytes += generator.setGlobalCodeTable('CP1252');

所有可用的配置文件可以通过调用获取:

final profiles = await CapabilityProfile.getAvailableProfiles();

更多关于Flutter热敏打印机控制插件esc_pos_gen的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter热敏打印机控制插件esc_pos_gen的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何使用Flutter中的esc_pos_gen插件来控制热敏打印机的示例代码。esc_pos_gen是一个Flutter插件,用于通过ESC/POS命令集控制热敏打印机。这个插件支持蓝牙、USB和网络连接的打印机。

首先,确保你已经在pubspec.yaml文件中添加了esc_pos_gen依赖:

dependencies:
  flutter:
    sdk: flutter
  esc_pos_gen: ^x.y.z  # 替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来是一个简单的示例代码,展示如何通过蓝牙连接打印机并发送打印指令:

import 'package:flutter/material.dart';
import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
import 'package:esc_pos_printer/esc_pos_printer.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('ESC/POS Printer Example'),
        ),
        body: Center(
          child: PrintButton(),
        ),
      ),
    );
  }
}

class PrintButton extends StatefulWidget {
  @override
  _PrintButtonState createState() => _PrintButtonState();
}

class _PrintButtonState extends State<PrintButton> {
  EscPosBluetooth? _bluetooth;
  EscPosPrinter? _printer;

  @override
  void initState() {
    super.initState();
    _bluetooth = EscPosBluetooth();
    _initPrinter();
  }

  Future<void> _initPrinter() async {
    // 扫描蓝牙设备(实际项目中应添加用户选择设备的逻辑)
    List<EscPosDevice> devices = await _bluetooth!.scanDevices();
    if (devices.isNotEmpty) {
      EscPosDevice device = devices.first; // 选择第一个设备作为示例
      _printer = await EscPosPrinter.connectBluetooth(device.address, device.name);
    } else {
      print("No devices found");
    }
  }

  Future<void> _printReceipt() async {
    if (_printer != null) {
      await _printer!.printText('Hello, ESC/POS!\n');
      await _printer!.cutPaper();
    } else {
      print("Printer not initialized");
    }
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _printReceipt,
      child: Text('Print Receipt'),
    );
  }

  @override
  void dispose() {
    _printer?.disconnect();
    _bluetooth?.close();
    super.dispose();
  }
}

注意事项:

  1. 权限处理:在实际应用中,需要处理蓝牙权限和设备扫描请求。
  2. 设备选择:上述示例中直接选择了扫描到的第一个设备。在实际应用中,应添加用户选择设备的界面。
  3. 错误处理:示例代码中没有添加详细的错误处理逻辑,实际项目中应添加适当的错误处理。
  4. 打印指令esc_pos_gen插件支持多种ESC/POS指令,可以根据需要发送不同的指令来实现复杂的打印功能。

蓝牙权限配置(Android):

AndroidManifest.xml中添加蓝牙权限:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

并在build.gradle(app级别)中添加对AndroidX蓝牙库的依赖:

dependencies {
    implementation 'androidx.bluetooth:bluetooth-common:1.0.5'
    implementation 'androidx.bluetooth:bluetooth-le:1.1.0'
}

蓝牙权限请求(Flutter代码):

在实际应用中,你需要请求蓝牙权限,特别是在Android 6.0及以上版本。可以使用permission_handler插件来处理权限请求。

希望这个示例代码能帮助你理解如何使用esc_pos_gen插件来控制热敏打印机。如果有更多具体需求或问题,欢迎继续提问!

回到顶部