Flutter打印功能插件rav_printer的使用

发布于 1周前 作者 phonegap100 来自 Flutter

Flutter打印功能插件rav_printer的使用

rav_printer 插件用于实现标签打印机的TSPL命令和收据打印机的ESC/POS命令。

测试设备

  • 标签打印机:型号 IW-C8LP -> IWARE
  • 收据打印机:型号 C5813 -> IWARE

示例代码

以下是一个完整的示例代码,展示了如何在 Flutter 应用程序中使用 rav_printer 插件来实现标签和收据的打印功能。

import 'package:flutter/material.dart';
import 'package:bluetooth_print/bluetooth_print.dart';
import 'package:bluetooth_thermal_printer_plus/bluetooth_thermal_printer_plus.dart';
import 'package:esc_pos_utils_plus/esc_pos_utils_plus.dart';
import 'package:rav_printer/rav_printer.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyWidget(),
    );
  }
}

class ListWidth {
  LabelWidth lw;
  String screen;

  ListWidth({
    required this.lw,
    required this.screen,
  });
}

class MyWidget extends StatefulWidget {
  const MyWidget({super.key});

  [@override](/user/override)
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  BluetoothPrint bluetoothPrint = BluetoothPrint.instance;
  TextEditingController controllerHeight = TextEditingController(text: "100");
  TextEditingController controllerGap = TextEditingController(text: "3");

  List<ListWidth> lw = [
    ListWidth(lw: LabelWidth.mm40, screen: "40mm"),
    ListWidth(lw: LabelWidth.mm58, screen: "58mm"),
    ListWidth(lw: LabelWidth.mm80, screen: "80mm"),
  ];

  bool _connected = false;
  String tips = 'no device connect';
  String mac = "";
  List<dynamic>? bds;
  LabelWidth? labelWidth;

  [@override](/user/override)
  void initState() {
    super.initState();
    initBluetooth();
  }

  Future<void> doPrint({required bool isPrintLabel}) async {
    String? isConnected = await BluetoothThermalPrinter.connectionStatus;
    if (isConnected == "true" && labelWidth != null) {
      int labelHeight = int.tryParse(controllerHeight.text) ?? 100;
      int labelGap = int.tryParse(controllerGap.text) ?? 3;
      RavPrinter printer = RavPrinter(
        heightLabel: labelHeight,
        gapLabel: labelGap,
        widthLabel: labelWidth!,
      );
      List<RavTextStyle> texts = [];
      texts.add(RavTextStyle(text: "LEFT", align: RavAlign.left));
      texts.add(RavTextStyle(text: "CENTER", align: RavAlign.center));
      texts.add(RavTextStyle(text: "RIGHT", align: RavAlign.right));
      texts.add(RavTextStyle(text: "QRCODE", align: RavAlign.center, isQrCode: true));
      texts.add(RavTextStyle(text: "", align: RavAlign.right, lineEnter: 2));
      texts.add(RavTextStyle(text: "BARCODE", align: RavAlign.center, isBarCode: true));
      if (isPrintLabel) {
        await printer.doPrintLabel(
          texts: texts,
        );
      } else {
        await printer.doPrintReceipt(
          texts: texts,
          paperSize: labelWidth == LabelWidth.mm58 ? PaperSize.mm58 : PaperSize.mm80,
        );
      }
    } else {
      tips = "Label or bluetooth no connect";
      setState(() {});
    }
  }

  Future<void> initBluetooth() async {
    bds = await BluetoothThermalPrinter.getBluetooths;
    setState(() {});
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    Size size = MediaQuery.sizeOf(context);
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        minimum: EdgeInsets.zero,
        child: Column(
          children: [
            const SizedBox(
              height: 20,
            ),
            Text("Information: $tips"),
            Expanded(
              child: SingleChildScrollView(
                child: Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 20),
                  child: Column(
                    children: [
                      const Divider(),
                      Container(
                        width: size.width,
                        height: 250,
                        padding: const EdgeInsets.symmetric(horizontal: 20),
                        child: ListView.builder(
                            itemCount: bds?.length ?? 0,
                            itemBuilder: (context, index) {
                              return ListTile(
                                title: Text(bds?[index] ?? ""),
                                subtitle: Text(bds?[index].split("#")[1] ?? ""),
                                onTap: () async {
                                  setState(() {
                                    mac = bds?[index].split("#")[1] ?? "";
                                    tips = "mac selected $mac";
                                  });
                                },
                                trailing: mac != "" && mac == bds?[index].split("#")[1]
                                    ? Icon(Icons.check, color: Colors.green)
                                    : null,
                              );
                            }),
                      ),
                      const Divider(),
                      Text("Select Width"),
                      Container(
                        width: size.width,
                        height: 200,
                        padding: const EdgeInsets.symmetric(horizontal: 20),
                        child: ListView.builder(
                            itemCount: lw.length,
                            itemBuilder: (context, index) {
                              return ListTile(
                                title: Text(lw[index].screen),
                                onTap: () async {
                                  setState(() {
                                    labelWidth = lw[index].lw;
                                  });
                                },
                                trailing: labelWidth != null && labelWidth == lw[index].lw
                                    ? Icon(Icons.check, color: Colors.green)
                                    : null,
                              );
                            }),
                      ),
                      const Divider(),
                      Text("Label Height (mm)"),
                      SizedBox(
                        height: 10,
                      ),
                      TextField(
                        controller: controllerHeight,
                        keyboardType: TextInputType.number,
                      ),
                      SizedBox(
                        height: 10,
                      ),
                      Text("Label Gap (mm)"),
                      TextField(
                        controller: controllerGap,
                        keyboardType: TextInputType.number,
                      ),
                      SizedBox(
                        height: 10,
                      ),
                      const Divider(),
                      ElevatedButton(
                        onPressed: _connected
                            ? null
                            : () async {
                                String? isConnected = await BluetoothThermalPrinter.connectionStatus;
                                if (isConnected != "true") {
                                  setState(() {
                                    tips = 'connecting...';
                                  });
                                  String? result = await BluetoothThermalPrinter.connect(mac);
                                  if (result == "true") {
                                    setState(() {
                                      _connected = true;
                                      tips = "Connected";
                                    });
                                  }
                                } else {
                                  setState(() {
                                    tips = 'please select device';
                                  });
                                }
                              },
                        child: Text("Connect"),
                      ),
                      ElevatedButton(
                        onPressed: _connected
                            ? () async {
                                setState(() {
                                  tips = 'disconnecting...';
                                });
                                await BluetoothThermalPrinter.disconnect();
                                String? res = await BluetoothThermalPrinter.disconnect();
                                if (res == "true") {
                                  setState(() {
                                    _connected = false;
                                    tips = "Disconnected";
                                  });
                                }
                              }
                            : null,
                        child: Text("Disconnect"),
                      ),
                      Divider(),
                      ElevatedButton(
                        onPressed: () async {
                          if (_connected) {
                            doPrint(isPrintLabel: true);
                          } else {
                            setState(() {
                              tips = "Printer not connect";
                            });
                          }
                        },
                        child: Text("Print Label"),
                      ),
                      ElevatedButton(
                        onPressed: () async {
                          if (_connected) {
                            doPrint(isPrintLabel: false);
                          } else {
                            setState(() {
                              tips = "Printer not connect";
                            });
                          }
                        },
                        child: Text("Print Receipt"),
                      ),
                      SizedBox(height: 100,)
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

代码解释

  1. 导入必要的库

    import 'package:flutter/material.dart';
    import 'package:bluetooth_print/bluetooth_print.dart';
    import 'package:bluetooth_thermal_printer_plus/bluetooth_thermal_printer_plus.dart';
    import 'package:esc_pos_utils_plus/esc_pos_utils_plus.dart';
    import 'package:rav_printer/rav_printer.dart';
    
  2. 定义主应用类

    void main() {
      runApp(const MyApp());
    }
    
  3. 定义应用程序主题和主页面

    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      [@override](/user/override)
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
            useMaterial3: true,
          ),
          home: const MyWidget(),
        );
      }
    }
    
  4. 定义标签宽度列表

    class ListWidth {
      LabelWidth lw;
      String screen;
    
      ListWidth({
        required this.lw,
        required this.screen,
      });
    }
    
  5. 定义状态管理类

    class MyWidget extends StatefulWidget {
      const MyWidget({super.key});
    
      [@override](/user/override)
      State<MyWidget> createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      BluetoothPrint bluetoothPrint = BluetoothPrint.instance;
      TextEditingController controllerHeight = TextEditingController(text: "100");
      TextEditingController controllerGap = TextEditingController(text: "3");
    
      List<ListWidth> lw = [
        ListWidth(lw: LabelWidth.mm40, screen: "40mm"),
        ListWidth(lw: LabelWidth.mm58, screen: "58mm"),
        ListWidth(lw: LabelWidth.mm80, screen: "80mm"),
      ];
    
      bool _connected = false;
      String tips = 'no device connect';
      String mac = "";
      List<dynamic>? bds;
      LabelWidth? labelWidth;
    
  6. 初始化蓝牙连接

    [@override](/user/override)
    void initState() {
      super.initState();
      initBluetooth();
    }
    
    Future<void> initBluetooth() async {
      bds = await BluetoothThermalPrinter.getBluetooths;
      setState(() {});
    }
    
  7. 打印逻辑

    Future<void> doPrint({required bool isPrintLabel}) async {
      String? isConnected = await BluetoothThermalPrinter.connectionStatus;
      if (isConnected == "true" && labelWidth != null) {
        int labelHeight = int.tryParse(controllerHeight.text) ?? 100;
        int labelGap = int.tryParse(controllerGap.text) ?? 3;
        RavPrinter printer = RavPrinter(
          heightLabel: labelHeight,
          gapLabel: labelGap,
          widthLabel: labelWidth!,
        );
        List<RavTextStyle> texts = [];
        texts.add(RavTextStyle(text: "LEFT", align: RavAlign.left));
        texts.add(RavTextStyle(text: "CENTER", align: RavAlign.center));
        texts.add(RavTextStyle(text: "RIGHT", align: RavAlign.right));
        texts.add(RavTextStyle(text: "QRCODE", align: RavAlign.center, isQrCode: true));
        texts.add(RavTextStyle(text: "", align: RavAlign.right, lineEnter: 2));
        texts.add(RavTextStyle(text: "BARCODE", align: RavAlign.center, isBarCode: true));
        if (isPrintLabel) {
          await printer.doPrintLabel(
            texts: texts,
          );
        } else {
          await printer.doPrintReceipt(
            texts: texts,
            paperSize: labelWidth == LabelWidth.mm58 ? PaperSize.mm58 : PaperSize.mm80,
          );
        }
      } else {
        tips = "Label or bluetooth no connect";
        setState(() {});
      }
    }
    
  8. 构建UI界面

    [@override](/user/override)
    Widget build(BuildContext context) {
      Size size = MediaQuery.sizeOf(context);
      return Scaffold(
        backgroundColor: Colors.white,
        body: SafeArea(
          minimum: EdgeInsets.zero,
          child: Column(
            children: [
              const SizedBox(
                height: 20,
              ),
              Text("Information: $tips"),
              Expanded(
                child: SingleChildScrollView(
                  child: Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 20),
                    child: Column(
                      children: [
                        const Divider(),
                        Container(
                          width: size.width,
                          height: 250,
                          padding: const EdgeInsets.symmetric(horizontal: 20),
                          child: ListView.builder(
                              itemCount: bds?.length ?? 0,
                              itemBuilder: (context, index) {
                                return ListTile(
                                  title: Text(bds?[index] ?? ""),
                                  subtitle: Text(bds?[index].split("#")[1] ?? ""),
                                  onTap: () async {
                                    setState(() {
                                      mac = bds?[index].split("#")[1] ?? "";
                                      tips = "mac selected $mac";
                                    });
                                  },
                                  trailing: mac != "" && mac == bds?[index].split("#")[1]
                                      ? Icon(Icons.check, color: Colors.green)
                                      : null,
                                );
                              }),
                        ),
                        const Divider(),
                        Text("Select Width"),
                        Container(
                          width: size.width,
                          height: 200,
                          padding: const EdgeInsets.symmetric(horizontal: 20),
                          child: ListView.builder(
                              itemCount: lw.length,
                              itemBuilder: (context, index) {
                                return ListTile(
                                  title: Text(lw[index].screen),
                                  onTap: () async {
                                    setState(() {
                                      labelWidth = lw[index].lw;
                                    });
                                  },
                                  trailing: labelWidth != null && labelWidth == lw[index].lw
                                      ? Icon(Icons.check, color: Colors.green)
                                      : null,
                                );
                              }),
                        ),
                        const Divider(),
                        Text("Label Height (mm)"),
                        SizedBox(
                          height: 10,
                        ),
                        TextField(
                          controller: controllerHeight,
                          keyboardType: TextInputType.number,
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Text("Label Gap (mm)"),
                        TextField(
                          controller: controllerGap,
                          keyboardType: TextInputType.number,
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        const Divider(),
                        ElevatedButton(
                          onPressed: _connected
                              ? null
                              : () async {
                                  String? isConnected = await BluetoothThermalPrinter.connectionStatus;
                                  if (isConnected != "true") {
                                    setState(() {
                                      tips = 'connecting...';
                                    });
                                    String? result = await BluetoothThermalPrinter.connect(mac);
                                    if (result == "true") {
                                      setState(() {
                                        _connected = true;
                                        tips = "Connected";
                                      });
                                    }
                                  } else {
                                    setState(() {
                                      tips = 'please select device';
                                    });
                                  }
                                },
                          child: Text("Connect"),
                        ),
                        ElevatedButton(
                          onPressed: _connected
                              ? () async {
                                  setState(() {
                                    tips = 'disconnecting...';
                                  });
                                  await BluetoothThermalPrinter.disconnect();
                                  String? res = await BluetoothThermalPrinter.disconnect();
                                  if (res == "true") {
                                    setState(() {
                                      _connected = false;
                                      tips = "Disconnected";
                                    });
                                  }
                                }
                              : null,
                          child: Text("Disconnect"),
                        ),
                        Divider(),
                        ElevatedButton(
                          onPressed: () async {
                            if (_connected) {
                              doPrint(isPrintLabel: true);
                            } else {
                              setState(() {
                                tips = "Printer not connect";
                              });
                            }
                          },
                          child: Text("Print Label"),
                        ),
                        ElevatedButton(
                          onPressed: () async {
                            if (_connected) {
                              doPrint(isPrintLabel: false);
                            } else {
                              setState(() {
                                tips = "Printer not connect";
                              });
                            }
                          },
                          child: Text("Print Receipt"),
                        ),
                        SizedBox(height: 100,)
                      ],
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      );
    }
    

更多关于Flutter打印功能插件rav_printer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter打印功能插件rav_printer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用rav_printer插件来实现打印功能的示例代码。rav_printer是一个用于Flutter的打印插件,支持多种类型的打印机。

1. 添加依赖

首先,你需要在你的pubspec.yaml文件中添加rav_printer依赖:

dependencies:
  flutter:
    sdk: flutter
  rav_printer: ^最新版本号  # 请替换为实际的最新版本号

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

2. 导入插件

在你的Dart文件中导入rav_printer插件:

import 'package:rav_printer/rav_printer.dart';

3. 初始化打印机

在使用打印机之前,你需要初始化打印机实例。这通常是在应用的某个初始化阶段完成的。

final RavPrinter _printer = RavPrinter();

4. 打印文本

下面是一个简单的示例,展示如何使用rav_printer打印文本:

void printText() async {
  try {
    // 打印机配置,可以根据实际情况调整
    PrinterConfig config = PrinterConfig(
      printerType: PrinterType.bluetooth, // 蓝牙打印机
      bluetoothName: '你的蓝牙打印机名称', // 蓝牙打印机名称
      bluetoothAddress: '你的蓝牙打印机地址', // 蓝牙打印机地址
      // 其他配置参数...
    );

    // 打印内容
    String content = "Hello, Flutter Printing!\nThis is a test.";

    // 调用打印方法
    await _printer.printText(content, config: config);
    print("Print successful!");
  } catch (e) {
    print("Print failed: $e");
  }
}

5. 打印图片

如果需要打印图片,可以使用printImage方法。这里是一个示例:

void printImage() async {
  try {
    // 打印机配置
    PrinterConfig config = PrinterConfig(
      printerType: PrinterType.bluetooth, // 蓝牙打印机
      bluetoothName: '你的蓝牙打印机名称', // 蓝牙打印机名称
      bluetoothAddress: '你的蓝牙打印机地址', // 蓝牙打印机地址
      // 其他配置参数...
    );

    // 图片路径(可以是本地路径或网络图片URL)
    String imagePath = "assets/images/sample.png"; // 本地图片示例
    // String imagePath = "https://example.com/sample.png"; // 网络图片示例

    // 调用打印方法
    await _printer.printImage(imagePath, config: config);
    print("Image print successful!");
  } catch (e) {
    print("Image print failed: $e");
  }
}

6. 打印自定义布局

对于更复杂的打印需求,你可以使用printCustom方法来打印自定义布局。这通常涉及将内容转换为打印机可以理解的格式(如ESC/POS命令)。

void printCustomLayout() async {
  try {
    // 打印机配置
    PrinterConfig config = PrinterConfig(
      printerType: PrinterType.bluetooth, // 蓝牙打印机
      bluetoothName: '你的蓝牙打印机名称', // 蓝牙打印机名称
      bluetoothAddress: '你的蓝牙打印机地址', // 蓝牙打印机地址
      // 其他配置参数...
    );

    // 自定义打印命令(ESC/POS命令示例)
    List<int> commands = [
      0x1B, 0x40, // 初始化打印机
      // 其他ESC/POS命令...
      0x0A, // 换行
    ];

    // 调用打印方法
    await _printer.printCustom(commands, config: config);
    print("Custom layout print successful!");
  } catch (e) {
    print("Custom layout print failed: $e");
  }
}

注意事项

  1. 权限:确保你的应用有访问蓝牙和其他必要硬件的权限。
  2. 打印机配置:根据你的打印机类型和配置调整PrinterConfig参数。
  3. 错误处理:在生产环境中,添加适当的错误处理和用户反馈。

这个示例展示了如何使用rav_printer插件进行基本的打印操作。根据你的具体需求,你可能需要调整配置和打印内容。

回到顶部