Flutter中如何通过热敏打印机打印后端返回的POS收据PDF
解决方案:Flutter 打印后端返回的PDF热敏收据
针对你已有后端生成的PDF收据,需要通过热敏打印机打印的需求,提供以下几种可行方案:
方案1:使用printing包调用系统打印服务
这个包可以直接加载PDF文件并调用系统打印框架,适配已被系统识别的热敏打印机(包括USB、蓝牙、网络打印机),无需额外处理PDF内容。
实现步骤:
- 添加依赖到
pubspec.yaml:
dependencies: printing: ^5.12.0 path_provider: ^2.1.1 http: ^1.1.0
- 核心代码示例:
import 'dart:io'; import 'dart:typed_data'; import 'package:http/http.dart' as http; import 'package:path_provider/path_provider.dart'; import 'package:printing/printing.dart'; Future<void> printReceipt(String pdfBackendUrl) async { // 1. 从后端下载PDF字节数据 final response = await http.get(Uri.parse(pdfBackendUrl)); if (response.statusCode != 200) throw Exception('PDF下载失败'); final Uint8List pdfBytes = response.bodyBytes; // 2. 配置热敏纸自定义尺寸(示例为80mm宽,高度自适应) await Printing.layoutPdf( name: 'POS交易收据', onLayout: (PdfPageFormat defaultFormat) async { return pdfBytes; }, format: PdfPageFormat( width: 80 * PdfPageFormat.mm, height: PdfPageFormat.infinite, marginLeft: 0, marginRight: 0, marginTop: 5 * PdfPageFormat.mm, marginBottom: 5 * PdfPageFormat.mm, ), ); }
方案2:蓝牙热敏打印机专用方案(转图片打印)
如果使用的是不支持系统打印服务的蓝牙热敏打印机,可将PDF转成图片后,用ESC/POS指令打印。
实现步骤:
- 添加依赖:
dependencies: esc_pos_bluetooth: ^0.2.4 printing: ^5.12.0 http: ^1.1.0
- 核心代码示例:
import 'dart:typed_data'; import 'package:http/http.dart' as http; import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart'; import 'package:printing/printing.dart'; Future<void> printPdfToBluetoothThermal(String pdfUrl) async { // 下载PDF final response = await http.get(Uri.parse(pdfUrl)); final Uint8List pdfBytes = response.bodyBytes; // 将PDF每页转成高清图片(适配热敏打印机DPI) final pdfPages = await Printing.raster(pdfBytes, dpi: 200); // 搜索蓝牙打印机 final printerManager = PrinterBluetoothManager(); final devices = await printerManager.scan(); if (devices.isEmpty) throw Exception('未找到蓝牙打印机'); // 选择目标打印机(这里取第一个,可改为用户选择) final targetPrinter = devices.first; // 生成打印任务并执行 final ticket = Ticket(); for (final page in pdfPages) { final img = await page.toImage(); ticket.image(img, align: PosAlign.center); ticket.cut(); // 每页后切纸 } final result = await printerManager.printTicket(targetPrinter, ticket); if (result != PosPrintResult.success) throw Exception('打印失败:$result'); }
方案3:平台通道调用原生打印能力
如果需要更定制化的控制,可以通过Flutter平台通道直接调用Android/iOS原生API打印PDF:
- Android:使用
PrintManager加载本地PDF文件发起打印请求 - iOS:使用
UIPrintInteractionController处理PDF打印
这种方案需要分别编写Android和iOS的原生代码,适合对打印流程有高度自定义需求的场景。
内容的提问来源于stack exchange,提问作者Mohammed Hussein
相关产品推荐
相关产品推荐

