如何使用Flutter及Flutter Web实现Word文件转PDF文件?
在Flutter Web中实现Word转PDF的可行方案
方案1:借助前端JavaScript库(纯客户端)
由于Flutter生态中暂无直接支持Word转PDF的纯Dart包,可通过dart:js或js包调用浏览器端的JS库实现转换,适合简单格式的Word文档。步骤如下:
- 添加依赖:在
pubspec.yaml中加入js包:
dependencies: js: ^0.6.7
- 引入JS库:下载
mammoth.js(解析Word为HTML)、jsPDF(生成PDF)、html2canvas(将HTML转为图片)的最新版本,放入项目web目录后,在web/index.html中引入:
<script src="mammoth.browser.min.js"></script> <script src="jspdf.umd.min.js"></script> <script src="html2canvas.min.js"></script>
- Dart侧实现转换逻辑:
import 'dart:js' as js; import 'dart:typed_data'; import 'package:js/js.dart'; @JS() external js.JsObject get mammoth; @JS() external js.JsObject get jsPDF; Future<void> convertWordToPdf(Uint8List wordBytes) async { // 解析Word内容为HTML final htmlResult = await mammoth.callMethod('convertToHtml', [ js.JsObject.jsify({'arrayBuffer': wordBytes.buffer}) ]); final htmlContent = htmlResult['value'] as String; // 创建临时DOM元素加载HTML内容 final tempDiv = js.context['document'].callMethod('createElement', ['div']); tempDiv['innerHTML'] = htmlContent; js.context['document']['body'].callMethod('appendChild', [tempDiv]); // 将HTML转为图片后生成PDF final canvas = await js.context['html2canvas'].callMethod('call', [tempDiv]); final pdf = jsPDF.newInstance(['p', 'mm', 'a4']); final imgData = canvas.callMethod('toDataURL', ['image/png']); pdf.callMethod('addImage', [imgData, 'PNG', 0, 0, 210, 297]); // 触发PDF下载 pdf.callMethod('save', ['converted.pdf']); // 清理临时DOM元素 js.context['document']['body'].callMethod('removeChild', [tempDiv]); }
注意:此方案对复杂格式(如嵌套表格、公式、特殊样式)的支持有限,可能出现样式丢失。
方案2:后端转换(推荐,支持复杂格式)
如果需要完美保留Word文档格式,建议通过后端服务完成转换,Flutter Web负责上传Word文件和下载转换后的PDF。
- 后端可选技术栈:
- Python:
python-docx(解析Word) +ReportLab/pdfkit(生成PDF) - Java:
Apache POI(解析Word) +iText(生成PDF) - Node.js:
officegen+pdf-lib或unoconv
- Python:
- Flutter Web侧上传下载示例:
import 'dart:typed_data'; import 'dart:js' as js; import 'package:http/http.dart' as http; Future<Uint8List?> uploadAndConvertWord(Uint8List wordBytes) async { final request = http.MultipartRequest( 'POST', Uri.parse('你的后端转换接口地址'), ); request.files.add(http.MultipartFile.fromBytes( 'file', wordBytes, filename: 'input.docx', )); final response = await request.send(); if (response.statusCode == 200) { return response.stream.toBytes(); } return null; } // 下载转换后的PDF void downloadPdf(Uint8List pdfBytes) { final blob = js.context['Blob'].newInstance( [pdfBytes, js.JsObject.jsify({'type': 'application/pdf'})], ); final url = js.context['URL'].callMethod('createObjectURL', [blob]); final aTag = js.context['document'].callMethod('createElement', ['a']); aTag['href'] = url; aTag['download'] = 'converted.pdf'; js.context['document']['body'].callMethod('appendChild', [aTag]); aTag.callMethod('click'); js.context['URL'].callMethod('revokeObjectURL', [url]); js.context['document']['body'].callMethod('removeChild', [aTag]); }
关键注意事项
- 纯客户端方案仅适合简单文档,复杂场景优先选择后端转换
- 引入JS库时建议下载到本地,避免依赖外部CDN带来的稳定性问题
- 后端转换需注意文件大小限制、并发处理及格式兼容测试
内容的提问来源于stack exchange,提问作者Ahmed hussien
相关产品推荐
相关产品推荐

