PavelS0 / docx_template_dart

A Docx template engine
Apache License 2.0
43 stars 31 forks source link

Unsupported operation: Cannot modify an unmodifiable list exception #53

Open irissmit-ockeloen opened 10 months ago

irissmit-ockeloen commented 10 months ago

An 'Unsupported operation: Cannot modify an unmodifiable list' is raised on arch.files[_index] = ArchiveFile(_name, data.length, data);

I created a unit test following the example.

    final file = File('test_resources/template.docx');
    final docx = await DocxTemplate.fromBytes(await file.readAsBytes());
    Content content = Content();
    content
      ..add(TextContent("header", "Nice header"))
      ..add(TextContent("footer", "Nice footer"))
      ..add(TextContent("docname", "Simple docname"))
      ..add(TextContent("passport", "Passport NE0323 4456673"));
    final docGenerated = await docx.generate(content);
    final fileGenerated = File('test_resources/generated.docx');
    if (docGenerated != null) await fileGenerated.writeAsBytes(docGenerated);
  });

In this example an unmodifiable list exception is raised:

dart:_internal UnmodifiableListMixin.[]= package:docx_template/src/docx_entry.dart 29:17 DocxEntry._updateData package:docx_template/src/docx_entry.dart 58:7 DocxXmlEntry._updateArchive package:docx_template/src/docx_entry.dart 185:13 DocxManager.updateArch. dart:collection _LinkedHashMapMixin.forEach package:docx_template/src/docx_entry.dart 184:10 DocxManager.updateArch package:docx_template/src/template.dart 95:14 DocxTemplate.generate test\utils\cv_generator_test.dart 18:37 main.

Unsupported operation: Cannot modify an unmodifiable list

I used version 0.3.6 of docx_template. I upgraded to 0.4.0 but that didn't solve the issue.

farzadjafari1996 commented 10 months ago

I struggled with the source code of the package. Imported it and then change void _updateData(Archive arch, List<int> data) function's body so I manually remove all elements from the Archive and then add modified list to the Archive. The mentioned problem solved but another problem seemed to be happening. Here is the new problem:

E/flutter (24023): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'List<int>' in type cast E/flutter (24023): #0 ZipEncoder.addFile (package:archive/src/zip_encoder.dart:215:29) E/flutter (24023): #1 ZipEncoder.encode (package:archive/src/zip_encoder.dart:90:7) E/flutter (24023): #2 DocxTemplate.generate (package:docx_template/src/template.dart:106:16)

Then I found several _manager.arch.files[i].content are null which ends in the mentioned exception. Any Idea on how can we fix this issue?

irissmit-ockeloen commented 10 months ago

I found out a workarround by overriding the dependency:

dependency_overrides:
  archive: 3.4.9

Then, it still doesn't work. The file is corrupted and can;t be openend: https://github.com/PavelS0/docx_template_dart/issues/37#issuecomment-1330462403

But when trying out the full example like https://github.com/Fiat2U/docx_template_flutter_sample to see a working sample. It did work. It seems that the file gets corrupted if not all tags are filled.

farzadjafari1996 commented 10 months ago

I tried and encountered Unhandled Exception: Unsupported operation: Cannot modify an unmodifiable list again.

feimenggo commented 10 months ago

https://github.com/feimenggo/docx_template_dart

dominikmucklow commented 10 months ago

I am encountering this issue as well. I've tried different versions of both the docx_template and archive packages, but always the same issue. Has anyone managed to make it work?

irissmit-ockeloen commented 9 months ago

I created another test. Since I noticed that if you won't fill all tags in your word document, the file get corrupted. I also noticed that if something is wrong with a tag in your template the file also get corrupted. So, to generated the documented I needed with my own template, I added tags step by step (tag by tag), till all tags were added and the template was complete.

Please find my working test:

  test('example cv', () async {
    final file = File('test_resources/template.docx');
    final docx = await DocxTemplate.fromBytes(await file.readAsBytes());
    final image = File('test_resources/test.png');
    final testFileContent = await image.readAsBytes();
    final listNormal = ['Foo', 'Bar', 'Baz'];
    final listBold = ['ooF', 'raB', 'zaB'];
    final contentList = <Content>[];
    final bold = listBold.iterator;
    for (var n in listNormal) {
      bold.moveNext();
      final plainContent = PlainContent('value')
        ..add(TextContent('normal', n))
        ..add(TextContent('bold', bold.current));
      contentList.add(plainContent);
    }

    Content content = Content();
    content
      ..add(TextContent('docname', 'Simple docname'))
      ..add(TextContent('passport', 'Passport NE0323 4456673'))
      ..add(TableContent('table', [
        RowContent()
          ..add(TextContent('key1', 'Paul'))
          ..add(TextContent('key2', 'Viberg'))
          ..add(TextContent('key3', 'Engineer'))
          ..add(ImageContent('img', testFileContent)),
        RowContent()
          ..add(TextContent('key1', 'Alex'))
          ..add(TextContent('key2', 'Houser'))
          ..add(TextContent('key3', 'CEO & Founder'))
          ..add(ListContent('tablelist', [
            TextContent('value', 'Mercedes-Benz C-Class S205'),
            TextContent('value', 'Lexus LX 570')
          ]))
          ..add(ImageContent('img', testFileContent))
      ]))
      ..add(ListContent('list', [
        TextContent('value', 'Engine')
          ..add(ListContent('listnested', contentList)),
        TextContent('value', 'Gearbox'),
        TextContent('value', 'Chassis')
      ]))
      ..add(ListContent('plainlist', [
        PlainContent('plainview')
          ..add(TableContent('table', [
            RowContent()
              ..add(TextContent('key1', 'Paul'))
              ..add(TextContent('key2', 'Viberg'))
              ..add(TextContent('key3', 'Engineer')),
            RowContent()
              ..add(TextContent('key1', 'Alex'))
              ..add(TextContent('key2', 'Houser'))
              ..add(TextContent('key3', 'CEO & Founder'))
              ..add(ListContent('tablelist', [
                TextContent('value', 'Mercedes-Benz C-Class S205'),
                TextContent('value', 'Lexus LX 570')
              ]))
          ])),
        PlainContent('plainview')
          ..add(TableContent('table', [
            RowContent()
              ..add(TextContent('key1', 'Nathan'))
              ..add(TextContent('key2', 'Anceaux'))
              ..add(TextContent('key3', 'Music artist'))
              ..add(ListContent(
                  'tablelist', [TextContent('value', 'Peugeot 508')])),
            RowContent()
              ..add(TextContent('key1', 'Louis'))
              ..add(TextContent('key2', 'Houplain'))
              ..add(TextContent('key3', 'Music artist'))
              ..add(ListContent('tablelist', [
                TextContent('value', 'Range Rover Velar'),
                TextContent('value', 'Lada Vesta SW Sport')
              ]))
          ])),
      ]))
      ..add(ListContent('multilineList', [
        PlainContent('multilinePlain')
          ..add(TextContent('multilineText', 'line 1')),
        PlainContent('multilinePlain')
          ..add(TextContent('multilineText', 'line 2')),
        PlainContent('multilinePlain')
          ..add(TextContent('multilineText', 'line 3'))
      ]))
      ..add(TextContent('multilineText2', 'line 1\nline 2\n line 3'))
      ..add(ImageContent('img', testFileContent));

    final docGenerated = await docx.generate(content);
    final outputFile = File('test_results/generated_example.docx');
    if (docGenerated != null) {
      await outputFile.writeAsBytes(docGenerated);
    }
  });

with test_resources/template.docx and test_resources/test.png

pubspec.lock

...
  docx_template:
    dependency: "direct dev"
    description:
      name: docx_template
      sha256: "70691589ec0d3f15a0c10d8b42cb1b6ce1fa968840a9fedb6373f6e4db8bc2c0"
      url: "https://pub.dev"
    source: hosted
    version: "0.3.6"
  archive:
    dependency: "direct overridden"
    description:
      name: archive
      sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b"
      url: "https://pub.dev"
    source: hosted
    version: "3.4.9"

generated from pubspec.yaml

...
dev_dependencies:
  flutter_test:
    sdk: flutter
  mockito: ^5.1.0
  build_runner: ^2.1.7
  flutter_gen: ^5.0.2
  test: ^1.19.5
  golden_toolkit: ^0.15.0
  flutter_lints: ^2.0.1
  flutter_launcher_icons: ^0.13.1
  docx_template: ^0.3.6

dependency_overrides:
  archive: 3.4.9

Keep in mind that the deendency override is just a workarround, not a fix.

Hamtiac commented 9 months ago

In my case, following this https://github.com/PavelS0/docx_template_dart/issues/37#issuecomment-1330462403 but putting the archive: 3.3.0 in the dev_dependencies: resolved my situation :/ .

dev_dependencies:
  archive: 3.3.0

and Working with docx_template: ^0.3.4.

My problem wasn't in a unit test, but I was using the normal way of doing things with this package (at least i think 😅)

Some samples :

DocxTemplate template = await DocxTemplate.fromBytes(byteData);
Content content = Content();

content
  ..add // adding all my tags...

List<int>? bytes = await template.generate(content);

The "Unsupported operation: Cannot modify an unmodifiable list exception" appeared on the last line, when I was trying to generate de doc.

Happy to find a solution, I hope this helps others !

imanpr commented 9 months ago

i have this error too, how to solve?

dominikmucklow commented 9 months ago

@PavelS0 are you still maintaining this repository?

tas-unn commented 9 months ago

I found a solution. I don’t know how correct it is, but at least it works: https://github.com/brendan-duncan/archive/issues/309

pub.dev\archive-3.4.10\lib\src\archive.dart Change one string:

//List get files => UnmodifiableListView(_files); List get files =>_files;

GeraldGZ commented 8 months ago

Solved: docx_entry.dart function _updateData in line 25 old:

void _updateData(Archive arch, List<int> data) {
    if (_index < 0) {
      arch.addFile(ArchiveFile(_name, data.length, data));
    } else {
      arch.files[_index] = ArchiveFile(_name, data.length, data);
    }
}

change to:

void _updateData(Archive arch, List<int> data) {
      arch.addFile(ArchiveFile(_name, data.length, data));
}

because lib "archive" is used and there is a change in archive.dart with new version:

class Archive extends IterableBase<ArchiveFile> {
List<ArchiveFile> get files => UnmodifiableListView(_files);    //  <-- problem

but the addFile has new behavior:

// Adding a file with the same path as one that's already in the archive
// will replace the previous file.
565537905qqcom commented 7 months ago

我找到了解决方案。我不知道它有多正确,但至少它有效: brendan-duncan/archive#309

pub.dev\archive-3.4.10\lib\src\archive.dart 更改一个字符串:

//获取文件列表 => UnmodifyingListView(_files); 列出获取文件=>_files;

你好!你所说的lib\src\archive.dart是在哪个目录中,为什么我的目录中找不到呢?

565537905qqcom commented 7 months ago

已解决: 第 25 行旧的 docx_entry.dart 函数 _updateData

void _updateData(Archive arch, List<int> data) {
    if (_index < 0) {
      arch.addFile(ArchiveFile(_name, data.length, data));
    } else {
      arch.files[_index] = ArchiveFile(_name, data.length, data);
    }
}

改成:

void _updateData(Archive arch, List<int> data) {
      arch.addFile(ArchiveFile(_name, data.length, data));
}

因为使用了 lib“archive”,并且新版本的 archive.dart 发生了变化:

class Archive extends IterableBase<ArchiveFile> {
List<ArchiveFile> get files => UnmodifiableListView(_files);    //  <-- problem

但 addFile 有新的行为:

// Adding a file with the same path as one that's already in the archive
// will replace the previous file.

你好!你所说的此方案在哪个文件中进行修改?你能帮我解决此问题吗?

565537905qqcom commented 7 months ago

有没有能帮忙解决此问题的大神?

GeraldGZ commented 7 months ago

docx_template_dart/lib/src/docx_entry.dart Line 25 change function to: 第 25 行将函数更改为:

void _updateData(Archive arch, List<int> data) {
      arch.addFile(ArchiveFile(_name, data.length, data));
}

C:\Users\user\AppData\Local\Pub\Cache\hosted\pub.dev\docx_template-0.4.0\lib\src

565537905qqcom commented 7 months ago

pub.dev

docx_template_dart/lib/src/docx_entry.dart 第 25 行将函数更改为: 第 25 行将函数更改为:

void _updateData(Archive arch, List<int> data) {
      arch.addFile(ArchiveFile(_name, data.length, data));
}

C:\Users\user\AppData\Local\Pub\Cache\hosted\pub.dev\docx_template-0.4.0\lib\src

您好!非常感谢您的回复!但您给的目录结构和我的目录结构不太一样,我的是(venv) niulei@niuleideMacBook-Air my_flutter_project % which flutter

/Users/niulei/Downloads/flutter/bin/flutter!请问是不是操作系统不一样的原因呢?我的电脑是mac笔记本,请问mac中对应的_updateData函数所在文件的完整的路径是多少?盼复!万分感谢!

GeraldGZ commented 7 months ago

docx_template is a separate package! It is not installed in the flutter folder. docx_template 是一个单独的包! 它没有安装在 flutter 文件夹中。

565537905qqcom commented 7 months ago

docx_template 是一个单独的包! 它没有安装在 flutter 文件夹中。 docx_template 是一个单独的包! 它没有安装在 flutter 文件夹中。

我怎样解决使用docx_template包时报错I/flutter (12503): Exception: Unsupported operation: Cannot modify an unmodifiable list的问题呢?您之前的建议修改docx_template_dart/lib/src/docx_entry.dart的第25行是解决此问题吗?我在mac里怎样确定您之前所述的目录并进入修改解决问题呢?并且我在pubspec.yaml中已经成功安装docx_template: ^0.3.6,但使用find ~/.pub-cache -name "docx_template" 为什么找不到此包?奇怪!盼复!万分感谢!

GeraldGZ commented 7 months ago

Code-Editor? VSCode?

565537905qqcom commented 7 months ago

VS代码? 你好!代码编辑器为Visual Studio Code. pubspec.yaml文件中:docx_template: ^0.3.6 archive: ^3.4.9 操作系统:mac笔记本 版本信息:Flutter 3.13.9 ,Dart 3.1.5

代码如下:import 'dart:io'; import 'package:flutter/material.dart'; import 'package:docx_template/docx_template.dart';

class PdfViewer extends StatefulWidget { final Map<String, dynamic> template; final List<Map<String, dynamic>> bankDetailsList;

const PdfViewer({Key? key, required this.template, required this.bankDetailsList}) : super(key: key);

@override _PdfViewerState createState() => _PdfViewerState(); }

class _PdfViewerState extends State {

@override void initState() { super.initState(); final contractNumber = widget.bankDetailsList.isNotEmpty ? widget.bankDetailsList.first['contract_number'] : ''; _generatePdfFromTemplate(); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('word Viewer'), ), body: Center(

  ),
);

}

Future _generatePdfFromTemplate() async { try {

final file = File(widget.template['pdfFilePath']);

final docx = await DocxTemplate.fromBytes(await file.readAsBytes());
final image = File(widget.template['sealImagePath']);
final testFileContent = await image.readAsBytes();
final listNormal = ['Foo', 'Bar', 'Baz'];
final listBold = ['ooF', 'raB', 'zaB'];
final contentList = <Content>[];
final bold = listBold.iterator;
for (var n in listNormal) {
  bold.moveNext();
  final plainContent = PlainContent('value')
    ..add(TextContent('normal', n))
    ..add(TextContent('bold', bold.current));
  contentList.add(plainContent);
}

Content content = Content();
content
  ..add(TextContent('docname', 'Simple docname'))
  ..add(TextContent('passport', 'Passport NE0323 4456673'))
  ..add(TableContent('table', [
    RowContent()
      ..add(TextContent('key1', 'Paul'))
      ..add(TextContent('key2', 'Viberg'))
      ..add(TextContent('key3', 'Engineer'))
      ..add(ImageContent('img', testFileContent)),
    RowContent()
      ..add(TextContent('key1', 'Alex'))
      ..add(TextContent('key2', 'Houser'))
      ..add(TextContent('key3', 'CEO & Founder'))
      ..add(ListContent('tablelist', [
        TextContent('value', 'Mercedes-Benz C-Class S205'),
        TextContent('value', 'Lexus LX 570')
      ]))
      ..add(ImageContent('img', testFileContent))
  ]))
  ..add(ListContent('list', [
    TextContent('value', 'Engine')
      ..add(ListContent('listnested', contentList)),
    TextContent('value', 'Gearbox'),
    TextContent('value', 'Chassis')
  ]))
  ..add(ListContent('plainlist', [
    PlainContent('plainview')
      ..add(TableContent('table', [
        RowContent()
          ..add(TextContent('key1', 'Paul'))
          ..add(TextContent('key2', 'Viberg'))
          ..add(TextContent('key3', 'Engineer')),
        RowContent()
          ..add(TextContent('key1', 'Alex'))
          ..add(TextContent('key2', 'Houser'))
          ..add(TextContent('key3', 'CEO & Founder'))
          ..add(ListContent('tablelist', [
            TextContent('value', 'Mercedes-Benz C-Class S205'),
            TextContent('value', 'Lexus LX 570')
          ]))
      ])),
    PlainContent('plainview')
      ..add(TableContent('table', [
        RowContent()
          ..add(TextContent('key1', 'Nathan'))
          ..add(TextContent('key2', 'Anceaux'))
          ..add(TextContent('key3', 'Music artist'))
          ..add(ListContent(
              'tablelist', [TextContent('value', 'Peugeot 508')])),
        RowContent()
          ..add(TextContent('key1', 'Louis'))
          ..add(TextContent('key2', 'Houplain'))
          ..add(TextContent('key3', 'Music artist'))
          ..add(ListContent('tablelist', [
            TextContent('value', 'Range Rover Velar'),
            TextContent('value', 'Lada Vesta SW Sport')
          ]))
      ])),
  ]))
  ..add(ListContent('multilineList', [
    PlainContent('multilinePlain')
      ..add(TextContent('multilineText', 'line 1')),
    PlainContent('multilinePlain')
      ..add(TextContent('multilineText', 'line 2')),
    PlainContent('multilinePlain')
      ..add(TextContent('multilineText', 'line 3'))
  ]))
  ..add(TextContent('multilineText2', 'line 1\nline 2\n line 3'))
  ..add(ImageContent('img', testFileContent));

final docGenerated = await docx.generate(content);
final outputFile = File('test_results/generated_example.docx');
if (docGenerated != null) {
  await outputFile.writeAsBytes(docGenerated);
}

} catch (e, stackTrace) { print('Exception: $e'); print('StackTrace: $stackTrace'); // 调用方法获取堆栈跟踪 } } }.运行以上代码后总是报错I/flutter ( 4164): Exception: Unsupported operation: Cannot modify an unmodifiable list I/flutter ( 4164): StackTrace: #0 UnmodifiableListMixin.[]= (dart:_internal/list.dart:90:5) I/flutter ( 4164): #1 DocxEntry._updateData (package:docx_template/src/docx_entry.dart:29:17) I/flutter ( 4164): #2 DocxXmlEntry._updateArchive (package:docx_template/src/docx_entry.dart:58:7) I/flutter ( 4164): #3 DocxManager.updateArch. (package:docx_template/src/docx_entry.dart:185:13) I/flutter ( 4164): #4 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:625:13) I/flutter ( 4164): #5 DocxManager.updateArch (package:docx_template/src/docx_entry.dart:184:10) I/flutter ( 4164): #6 DocxTemplate.generate (package:docx_template/src/template.dart:95:14) I/flutter ( 4164): #7 _PdfViewerState._generatePdfFromTemplate (package:my_flutter_project/erp/sales/contract/pdf_viewer.dart:132:37) I/flutter ( 4164): .请帮我看一下怎样解决此问题呢?万分感谢!

565537905qqcom commented 7 months ago

各位大神!之前的问题已解决!非常感谢! 但现在遇到了新问题,docx_template替换好占位符后怎样打开word查看呢?docx_template支持查看功能吗?还是必须转换为pdf进行查看呢?

GeraldGZ commented 7 months ago

docx_template is not intended for displaying a Word document. The document is opened and displayed with Word or OpenOffice. docx_template 不适用于显示 Word 文档。 使用 Word 或 OpenOffice 打开并显示文档。

565537905qqcom commented 7 months ago

docx_template 不适用于显示 Word 文档。使用 Word 或 OpenOffice 打开并显示文档。 docx_template 不用于显示Word文档。使用Word或OpenOffice打开并显示文档。

好的,我试一下,非常感谢你🙏

565537905qqcom commented 7 months ago

docx_template 不适用于显示 Word 文档。使用 Word 或 OpenOffice 打开并显示文档。 docx_template 不用于显示Word文档。使用Word或OpenOffice打开并显示文档。

你好!import 'dart:io'; import 'package:flutter/material.dart'; import 'package:docx_template/docx_template.dart'; import 'package:path_provider/path_provider.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:flutter_pdfview/flutter_pdfview.dart';

import 'dart:typed_data';

class PdfViewer extends StatefulWidget { final Map<String, dynamic> template; final List<Map<String, dynamic>> bankDetailsList;

const PdfViewer({Key? key, required this.template, required this.bankDetailsList}) : super(key: key);

@override _PdfViewerState createState() => _PdfViewerState(); }

class _PdfViewerState extends State { String? docxFilePath; String? pdfFilePath;

@override void initState() { super.initState(); final contractNumber = widget.bankDetailsList.isNotEmpty ? widget.bankDetailsList.first['contract_number'] : ''; _generatePdfFromTemplate(); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Word Viewer'), ), body: pdfFilePath == null ? Center(child: CircularProgressIndicator()) : PDFView( filePath: pdfFilePath!, enableSwipe: true, swipeHorizontal: true, autoSpacing: false, pageFling: false, onRender: (_pages) { setState(() {}); }, onError: (error) { print(error.toString()); }, onPageError: (page, error) { print('$page: ${error.toString()}'); }, onViewCreated: (PDFViewController pdfViewController) { // _controller.complete(pdfViewController); }, onPageChanged: (int? page, int? total) { print('page change: $page/$total'); }, ), ); } Future _generatePdfFromTemplate() async { try {

  // 从模板文件中创建 DocxTemplate 实例
  final docx = await DocxTemplate.fromBytes(await File(widget.template['pdfFilePath']).readAsBytes());

  // 准备图像数据
  final imageBytes = await File(widget.template['sealImagePath']).readAsBytes();

  final listNormal = ['Foo', 'Bar', 'Baz'];
  final listBold = ['ooF', 'raB', 'zaB'];
  final contentList = <Content>[];
  final bold = listBold.iterator;
  for (var n in listNormal) {
    bold.moveNext();
    final plainContent = PlainContent('value')
      ..add(TextContent('normal', n))
      ..add(TextContent('bold', bold.current));
    contentList.add(plainContent);
  }

  Content content = Content();
  content
    ..add(TextContent('docname', 'Simple docname'))
    ..add(TextContent('passport', 'Passport NE0323 4456673'))
    ..add(TableContent('table', [
      RowContent()
        ..add(TextContent('key1', 'Paul'))
        ..add(TextContent('key2', 'Viberg'))
        ..add(TextContent('key3', 'Engineer'))
        ..add(ImageContent('img', imageBytes)),
      RowContent()
        ..add(TextContent('key1', 'Alex'))
        ..add(TextContent('key2', 'Houser'))
        ..add(TextContent('key3', 'CEO & Founder'))
        ..add(ListContent('tablelist', [
          TextContent('value', 'Mercedes-Benz C-Class S205'),
          TextContent('value', 'Lexus LX 570')
        ]))
        ..add(ImageContent('img', imageBytes))
    ]))
    ..add(ListContent('list', [
      TextContent('value', 'Engine')
        ..add(ListContent('listnested', contentList)),
      TextContent('value', 'Gearbox'),
      TextContent('value', 'Chassis')
    ]))
    ..add(ListContent('plainlist', [
      PlainContent('plainview')
        ..add(TableContent('table', [
          RowContent()
            ..add(TextContent('key1', 'Paul'))
            ..add(TextContent('key2', 'Viberg'))
            ..add(TextContent('key3', 'Engineer')),
          RowContent()
            ..add(TextContent('key1', 'Alex'))
            ..add(TextContent('key2', 'Houser'))
            ..add(TextContent('key3', 'CEO & Founder'))
            ..add(ListContent('tablelist', [
              TextContent('value', 'Mercedes-Benz C-Class S205'),
              TextContent('value', 'Lexus LX 570')
            ]))
        ])),
      PlainContent('plainview')
        ..add(TableContent('table', [
          RowContent()
            ..add(TextContent('key1', 'Nathan'))
            ..add(TextContent('key2', 'Anceaux'))
            ..add(TextContent('key3', 'Music artist'))
            ..add(ListContent(
                'tablelist', [TextContent('value', 'Peugeot 508')])),
          RowContent()
            ..add(TextContent('key1', 'Louis'))
            ..add(TextContent('key2', 'Houplain'))
            ..add(TextContent('key3', 'Music artist'))
            ..add(ListContent('tablelist', [
              TextContent('value', 'Range Rover Velar'),
              TextContent('value', 'Lada Vesta SW Sport')
            ]))
        ])),
    ]))
    ..add(ListContent('multilineList', [
      PlainContent('multilinePlain')
        ..add(TextContent('multilineText', 'line 1')),
      PlainContent('multilinePlain')
        ..add(TextContent('multilineText', 'line 2')),
      PlainContent('multilinePlain')
        ..add(TextContent('multilineText', 'line 3'))
    ]))
    ..add(TextContent('multilineText2', 'line 1\nline 2\n line 3'))
    ..add(ImageContent('img', imageBytes));
  // 生成 Word 文档,根据传入的 Content 对象进行替换占位符
  final docGenerated = await docx.generate(content);

  // print('docGenerated的类型是:${docGenerated.runtimeType}');

  // 获取存储目录
  final directory = await getApplicationDocumentsDirectory();
  // 生成路径
  final outputFile = File('${directory.path}/generated_docx_with_replaced_content.docx');

  if (docGenerated != null) {
    // 写入文件
    await outputFile.writeAsBytes(docGenerated);

  // 创建 PDF 文档
  final pdf = pw.Document();

  // 从 Word 文件中读取内容,并添加到 PDF 文档中
  final wordFile = File(outputFile.path);

  print('Word 文件路径: ${wordFile.path}');

  // 将 Word 文件内容转换为 Uint8List
  final wordBytes = await wordFile.readAsBytes();

  print('Word 文件内容: $wordBytes');

  // 使用临时文件创建 pw.Image
    final tempImage = pw.MemoryImage(
      Uint8List.fromList(wordBytes),
    );

    // 添加图像到 PDF 文档中
    pdf.addPage(
      pw.Page(
        build: (pw.Context context) {
          return pw.Center(
            child: pw.Image(tempImage),
          );
        },
      ),
    );

    // 保存 PDF 文件路径以便稍后使用
    setState(() {
      pdfFilePath = outputFile.path;
    });
  }

} catch (e, stackTrace) { print('Exception: $e'); print('StackTrace: $stackTrace'); // 调用方法获取堆栈跟踪 } } } 我在把word转换为pdf的过程中此代码会报错I/flutter ( 3281): Exception: Exception: Unable to guess the image type 1311710 bytes!一直解决不了!请问您有办法解决吗?如果没有的话,请问flutter中怎样把此代码生成的替换好占位符的word文件显示到界面中呢?盼复!万分感谢!

GeraldGZ commented 7 months ago

This is the wrong place for your problems. 这是你的问题的错误地方。 --> https://stackoverflow.com

rrsaikat commented 7 months ago

Found same issue today :/ But wasted 2hours even if it's solved!

christenbc commented 6 months ago

https://github.com/feimenggo/docx_template_dart

@feimenggo your code does not work either

../../../../.pub-cache/git/docx_template_dart-bb29dfc155e25b346e58cf9b75958cde021bd58b/lib/src/docx_entry.dart:29:11: Error: The operator '[]=' isn't defined for the class 'Archive'.
 - 'Archive' is from 'package:archive/src/archive.dart' ('../../../../.pub-cache/hosted/pub.dev/archive-3.4.10/lib/src/archive.dart').
Try correcting the operator to an existing operator, or defining a '[]=' operator.
      arch[_index] = ArchiveFile(_name, data.length, data);
christenbc commented 6 months ago

Found same issue today :/ But wasted 2hours even if it's solved!

@rrsaikat could you share how did you manage at the end?

feimenggo commented 6 months ago

https://github.com/feimenggo/docx_template_dart

@feimenggo your code does not work either

../../../../.pub-cache/git/docx_template_dart-bb29dfc155e25b346e58cf9b75958cde021bd58b/lib/src/docx_entry.dart:29:11: Error: The operator '[]=' isn't defined for the class 'Archive'.
 - 'Archive' is from 'package:archive/src/archive.dart' ('../../../../.pub-cache/hosted/pub.dev/archive-3.4.10/lib/src/archive.dart').
Try correcting the operator to an existing operator, or defining a '[]=' operator.
      arch[_index] = ArchiveFile(_name, data.length, data);

Usage:

  docx_template:
    git:
      url: https://github.com/feimenggo/docx_template_dart
christenbc commented 6 months ago

https://github.com/feimenggo/docx_template_dart

@feimenggo your code does not work either

../../../../.pub-cache/git/docx_template_dart-bb29dfc155e25b346e58cf9b75958cde021bd58b/lib/src/docx_entry.dart:29:11: Error: The operator '[]=' isn't defined for the class 'Archive'.
 - 'Archive' is from 'package:archive/src/archive.dart' ('../../../../.pub-cache/hosted/pub.dev/archive-3.4.10/lib/src/archive.dart').
Try correcting the operator to an existing operator, or defining a '[]=' operator.
      arch[_index] = ArchiveFile(_name, data.length, data);

Usage:

  docx_template:
    git:
      url: https://github.com/feimenggo/docx_template_dart

That's what I did, @GeraldGZ's solution works however

rrsaikat commented 6 months ago

Found same issue today :/ But wasted 2hours even if it's solved!

@rrsaikat could you share how did you manage at the end?

image

Simply use these two at your pubspec.yml dependencies. @christenbc nb: I'm using Flutter 3.19.3 and Dart 3.3.1

lovelyJason commented 5 months ago

他拿的我也遇见这个错误了,flutter怎么连一个处理docx的库都没有啊,好操蛋啊

lovelyJason commented 5 months ago
  Future testGenerateDocxFromTemplate() async {
    try {
      // 从模板文件中创建 DocxTemplate 实例
      final docx = await DocxTemplate.fromBytes(
          await File('assets/template.docx').readAsBytes());

      Content content = Content();
      // 生成 Word 文档,根据传入的 Content 对象进行替换占位符
      content..add(TextContent('docname', 'Simple docname'));

      final docGenerated = await docx.generate(content);
      print('docGenerated的类型是:${docGenerated.runtimeType}');

      // 获取存储目录
      final directory = await getApplicationDocumentsDirectory();
      // 生成路径
      final outputFile =
          File('${directory.path}/generated_docx_with_replaced_content.docx');

      if (docGenerated != null) {
        // 写入文件
        print('生成成功: ${directory.path}');
        await outputFile.writeAsBytes(docGenerated);
      }
    } catch (e, stackTrace) {
      print('Exception: $e');
      print('StackTrace: $stackTrace'); // 调用方法获取堆栈跟踪
    }
  }

这个代码对我没效果,我的template.docx长这样

{{docname}},
{docname}
docname

生成的docx压根也没替换掉,还长这样

puranjanp commented 4 months ago

Found same issue :

  ....
  final templatedata = await rootBundle.load('assets/template.docx');
  final bytes = templatedata.buffer.asUint8List();
  final docx = await DocxTemplate.fromBytes(bytes);
  Content c = Content();
  c
    ..add(TextContent("docname", "my file"))
    ..add(TextContent("multilineText", "some data"));
  //on the below line of code
  final output = await docx.generate(c); 

Following are the Stack Trace output

I/flutter ( 708): Unsupported operation: Cannot modify an unmodifiable list I/flutter ( 708): StackTrace: #0 UnmodifiableListMixin.[]= (dart:_internal/list.dart:90:5) I/flutter ( 708): #1 DocxEntry._updateData (package:docx_template/src/docx_entry.dart:29:17) I/flutter ( 708): #2 DocxXmlEntry._updateArchive (package:docx_template/src/docx_entry.dart:58:7) I/flutter ( 708): #3 DocxManager.updateArch. (package:docx_template/src/docx_entry.dart:203:13) I/flutter ( 708): #4 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:633:13) I/flutter ( 708): #5 DocxManager.updateArch (package:docx_template/src/docx_entry.dart:202:10) I/flutter ( 708): #6 DocxTemplate.generate (package:docx_template/src/template.dart:96:14)

alihassan143 commented 3 months ago

https://github.com/alihassan143/docx_template_dart this will work with latest flutter version and latest dependencies