Flutter/Dart创建含指定文本的docx文件遇报错及疑问求助
Docx文件生成问题排查与替代方案
问题情况
我需要实现的功能是:创建新的Docx文件,插入指定字符串后分享给他人。使用docx_template库编写代码后,运行时遇到两个问题:
- 控制台打印Content对象时,显示
{content: {}, name: {}},明明已经添加了TextContent,但字段为空 - 执行文档生成操作时,抛出错误:
Unsupported operation: Cannot modify an unmodifiable list
我的代码
static Future<void> createDocx(String docText) async { print(docText); final data = await rootBundle.load('assets/docFile/docfile.docx'); final bytes = data.buffer.asUint8List(); var docx = await DocxTemplate.fromBytes(bytes); print(docx); Content c = Content(); c ..add(TextContent("content", "hi my name is yashi")) ..add(TextContent('name', 'yashi')); print('Content object: $c'); // Generate the document with replaced variables try { print('hiii'); final docGenerated = await docx.generate(c, tagPolicy: TagPolicy.saveText); print('hi2'); final directory = await getApplicationDocumentsDirectory(); final filePath = '${directory.path}/output.docx'; print(filePath); final file = File(filePath); if (docGenerated != null) await file.writeAsBytes(docGenerated); await Share.shareXFiles([XFile(filePath)]); print('Document created: $filePath'); } catch (e) { print('Error generating document: $e'); } }
控制台输出
I/flutter (14867): Instance of ‘DocxTemplate’ I/flutter (14867): Content object: {content: {}, name: {}} I/flutter (14867): hiii I/flutter (14867): Error generating document: Unsupported operation: Cannot modify an unmodifiable list
(注:传入的docText已正常打印)
问题原因分析
Content对象字段为空:
大概率是docx_template库的TextContent构造参数顺序错误。部分类似库的TextContent是TextContent(内容, 标签名)的顺序,而你写的是TextContent(标签名, 内容),导致标签和内容没对应上,所以Content对象显示为空。可以去查库的官方文档确认参数顺序。
另外也可能是Word模板里的占位符格式不对,比如库要求占位符是{{content}},但模板里用了其他格式(比如{content}或者<<content>>)。不可变列表修改错误:
这个错误一般是库内部代码尝试修改一个被标记为不可变的List集合。可能是库的版本存在bug,或者tagPolicy: TagPolicy.saveText的配置和模板内容冲突,也有可能是加载的模板本身存在格式问题,导致解析后生成了不可修改的元素列表。
替代实现方案
方案1:使用docx库直接生成文档(无需模板)
如果不需要基于现有Word模板,直接生成新的Docx文件,可以用docx库,代码更简洁:
- 先在
pubspec.yaml添加依赖:
dependencies: docx: ^1.0.0 # 替换为最新版本 path_provider: ^2.1.2 share_plus: ^7.2.2
- 实现代码:
import 'package:docx/docx.dart'; import 'package:path_provider/path_provider.dart'; import 'package:share_plus/share_plus.dart'; static Future<void> createDocx(String docText) async { // 初始化空的Docx文档 final doc = Docx(); // 添加段落和文本 doc.addParagraph().addText(docText); // 按需添加指定内容 doc.addParagraph().addText('hi my name is yashi'); doc.addParagraph().addText('yashi'); // 获取本地存储路径 final directory = await getApplicationDocumentsDirectory(); final filePath = '${directory.path}/output.docx'; // 保存文档到本地 await doc.save(filePath); // 分享生成的文件 await Share.shareXFiles([XFile(filePath)]); print('Document created: $filePath'); }
方案2:更换模板处理库
如果必须基于现有模板,可以尝试使用flutter_docx_template库,该库的API设计更直观,文档也更完善,能避免不少类似的坑。
内容的提问来源于stack exchange,提问作者Yashi Goyal
相关产品推荐
相关产品推荐

