You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何直接打印PDF?POS应用热敏打印需求咨询

实现Flutter直接打印现成PDF收据到热敏打印机的方案

方案一:使用printing包直接打印PDF字节流

printing是Flutter生态中适配多平台的打印工具,支持直接加载现成PDF的字节流发起打印,无需重新生成收据内容。

步骤:

  1. 向pubspec.yaml添加依赖:
    dependencies:
      printing: ^5.12.0
      pdf: ^3.10.0 # 包内部依赖,无需用来创建PDF
    
  2. 从后端获取PDF字节流(比如通过HTTP请求拿到Uint8List格式的数据)
  3. 调用打印方法:
    import 'package:printing/printing.dart';
    import 'package:pdf/pdf.dart';
    
    // 传入从后端获取到的pdfBytes执行打印
    Future<void> printPdfReceipt(Uint8List pdfBytes) async {
      try {
        await Printing.layoutPdf(
          onLayout: (PdfPageFormat format) async => pdfBytes,
        );
      } catch (e) {
        // 处理打印异常:打印机未连接、权限不足等
        print('打印失败:$e');
      }
    }
    
  4. 热敏打印机适配:确保打印机已通过蓝牙/WiFi/USB与设备配对,调用打印后会唤起系统打印选择界面,直接选中目标热敏打印机即可。

方案二:Android平台原生调用系统打印服务

若需要更底层的控制,Android可通过MethodChannel调用原生代码,直接传递PDF字节流给系统打印服务。

步骤:

  1. Flutter侧通过MethodChannel调用原生方法:
    import 'package:flutter/services.dart';
    
    class PrintService {
      static const MethodChannel _channel = MethodChannel('print_pdf');
    
      static Future<void> printPdfFromBytes(Uint8List pdfBytes) async {
        try {
          await _channel.invokeMethod('printPdf', {'bytes': pdfBytes});
        } on PlatformException catch (e) {
          print('打印错误:${e.message}');
        }
      }
    }
    
  2. Android原生(Kotlin)实现打印逻辑:
    class MainActivity : FlutterActivity() {
        private val CHANNEL = "print_pdf"
    
        override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
            super.configureFlutterEngine(flutterEngine)
            MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
                if (call.method == "printPdf") {
                    val bytes = call.argument<ByteArray>("bytes")
                    bytes?.let {
                        printPdf(it)
                        result.success(null)
                    } ?: result.error("NULL_ERROR", "PDF字节流为空", null)
                } else {
                    result.notImplemented()
                }
            }
        }
    
        private fun printPdf(pdfBytes: ByteArray) {
            val printManager = getSystemService(Context.PRINT_SERVICE) as PrintManager
            val jobName = "POS收据打印"
    
            val printAdapter = object : PrintDocumentAdapter() {
                override fun onWrite(pages: Array<out PageRange>?, destination: ParcelFileDescriptor?, cancellationSignal: CancellationSignal?, callback: WriteResultCallback?) {
                    val fileOutputStream = FileOutputStream(destination?.fileDescriptor)
                    fileOutputStream.write(pdfBytes)
                    fileOutputStream.close()
                    callback?.onWriteFinished(arrayOf(PageRange.ALL_PAGES))
                }
    
                override fun onLayout(oldAttributes: PrintAttributes?, newAttributes: PrintAttributes?, cancellationSignal: CancellationSignal?, callback: LayoutResultCallback?, extras: Bundle?) {
                    val info = PrintDocumentInfo.Builder(jobName)
                        .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                        .build()
                    callback?.onLayoutFinished(info, true)
                }
            }
    
            printManager.print(jobName, printAdapter, PrintAttributes.Builder().build())
        }
    }
    
  3. 权限配置:在AndroidManifest.xml中添加必要权限:
    <uses-permission android:name="android.permission.INTERNET" /> <!-- 从网络获取PDF时需要 -->
    <uses-permission android:name="android.permission.BLUETOOTH" /> <!-- 蓝牙打印机配对时需要 -->
    

方案三:集成品牌专属热敏打印机SDK

如果使用佳博、芯烨这类特定品牌的热敏打印机,可直接集成其官方Flutter SDK,这类SDK通常支持直接传入PDF字节流打印,兼容性和针对性更强。

示例逻辑:

  1. 向pubspec.yaml添加对应品牌SDK的依赖
  2. 初始化打印机连接(蓝牙/WiFi)
  3. 调用SDK打印方法:
    // 假设已完成打印机连接初始化
    Future<void> printReceiptWithSdk(Uint8List pdfBytes) async {
      try {
        // 调用SDK提供的PDF打印接口
        await PrinterSdk.printPdf(pdfBytes);
      } catch (e) {
        print('SDK打印失败:$e');
      }
    }
    

关键注意事项

  • PDF尺寸适配:热敏打印机多为窄幅(如80mm宽),需确保后端返回的PDF尺寸与打印机匹配,避免内容被截断。
  • 连接校验:打印前需确认蓝牙/WiFi/USB打印机已正常连接,可添加连接状态检测逻辑。
  • 异常处理:捕获打印机未找到、打印队列溢出、权限不足等异常,给用户明确提示。

内容的提问来源于stack exchange,提问作者Adi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:53:26