Flutter Web构建模式下printing包无法正常工作求助
解决方案:Web环境下PDF打印报错
Uncaught Unsupported operation: Platform._operatingSystem 这个错误源于Flutter Web不支持Platform._operatingSystemAPI,而printing包的部分实现依赖了该API,导致构建后的Web版本运行失败。以下是具体解决步骤:
1. 调整index.html中的脚本位置
确保你添加的dartPdfJsVersion脚本放在main.dart.js之前,保证pdf.js在Flutter代码加载前完成初始化:
<script> var dartPdfJsVersion = "3.2.146"; </script> <script src="main.dart.js" type="application/javascript"></script>
2. 添加平台判断,针对Web使用兼容的打印逻辑
导入Flutter基础库的kIsWeb常量,区分Web和原生平台,替换为Web兼容的打印方法:
修改PdfService代码:
import 'package:flutter/foundation.dart' show kIsWeb; // 新增导入 import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:printing/printing.dart'; import 'package:sostituzione_docenti/providers/gestione_docenti_provider.dart'; import '../classes/control.dart'; class PdfService { static Future<void> printOrario( List<List>? orario, DatoDocente docente) async { final doc = pw.Document(); List<String> header = ["Ora/Giorno", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"]; // PDF构建逻辑(与原代码一致) doc.addPage(pw.Page( pageFormat: PdfPageFormat.a4, orientation: pw.PageOrientation.landscape, margin: const pw.EdgeInsets.only(top: 50, right: 100, left: 50, bottom: 100), build: (pw.Context context) { return pw.Column( children: [ pw.Text("Orario di ${docente.cognome} ${docente.nome}"), pw.SizedBox(height: 10), pw.Row( children: [ for (int a = 0; a < header.length; a++) ...{ pw.Expanded( child: pw.SizedBox( height: 50, child: pw.Container( decoration: pw.BoxDecoration( border: pw.Border.all(color: PdfColors.black), color: PdfColors.green100), child: pw.Center(child: pw.Text(header[a]))), )), } ], ), for (int i = 0; i < Control.maxH; i++) ...{ pw.Row( children: [ pw.Expanded( child: pw.SizedBox( height: 70, child: pw.Container( decoration: pw.BoxDecoration( border: pw.Border.all(color: PdfColors.black), color: PdfColors.green100), child: pw.Center(child: pw.Text("${i + 1} ora")))), ), for (int j = 0; j < 6; j++) ...{ pw.Expanded( child: pw.SizedBox( height: 70, child: pw.Container( decoration: pw.BoxDecoration( border: pw.Border.all(color: PdfColors.black), color: orario![i][j] != null ? PdfColors.amber100 : PdfColors.white), child: pw.Center( child: orario[i][j] == null ? pw.Text(" ") : pw.Text(orario[i][j]))), )), } ], ) } ], ); })); // 修改打印逻辑,区分平台 final pdfBytes = await doc.save(); if (kIsWeb) { // Web环境使用兼容的打印/分享方法 await Printing.printPdf(bytes: pdfBytes); // 也可使用分享功能:await Printing.sharePdf(bytes: pdfBytes, filename: 'orario_${docente.cognome}.pdf'); } else { // 原生平台保留原逻辑 await Printing.layoutPdf(onLayout: (PdfPageFormat format) async => pdfBytes); } } }
3. 升级依赖包保证兼容性
将printing和pdf包更新到最新稳定版,确保Web支持的完善性:
修改pubspec.yaml:
dependencies: pdf: ^3.10.0 printing: ^5.1.1 # 其他依赖项...
执行flutter pub get更新依赖。
原理说明
Flutter Web环境没有dart:io中Platform类的实现,旧版printing包的部分方法会间接调用该API导致报错。通过kIsWeb区分平台后,使用Web兼容的printPdf方法,避免触发依赖原生平台的API调用。
内容的提问来源于stack exchange,提问作者enrico cristaudo
相关产品推荐
相关产品推荐

