从字节文件创建Zip文件 Flutter web

4

我使用Firebase云存储来存储一些文件,然后必须将它们放入zip文件并下载。我只需要在Web上进行这个操作,这是困难的部分。 现在我的做法如下:

FloatingActionButton(
    child: const Icon(Icons.download),
    onPressed: () async {
      List<int>? bytes;
      webarc.ZipEncoder encoder = webarc.ZipEncoder();
      webarc.Archive archive = webarc.Archive();

      try {
        List<String> links = await Database.formLinks();

        for (String link in links) {
          String fileName = link.substring(link.lastIndexOf('/') + 1);
          http.Response response = await http.get(
            Uri.parse(link),
            headers: headers,
          );
          webarc.ArchiveFile file = webarc.ArchiveFile.stream(
            fileName,
            response.bodyBytes.elementSizeInBytes,
            response.bodyBytes.toList(),
          );
          archive.addFile(file);
        }
        webarc.OutputStream outputStream = webarc.OutputStream(
          byteOrder: webarc.LITTLE_ENDIAN,
        );
        bytes = encoder.encode(
          archive,
          level: webarc.Deflate.BEST_COMPRESSION,
          modified: DateTime.now(),
          output: outputStream,
        );
      } catch (e) {
        print(e);
        Fluttertoast.showToast(
          msg: 'Errore nel download dello zip.',
          toastLength: Toast.LENGTH_LONG,
          gravity: ToastGravity.BOTTOM,
        );
        return;
      }
      if (bytes == null) {
        Fluttertoast.showToast(
          msg: 'Errore nel download dello zip. bytes nulli.',
          toastLength: Toast.LENGTH_LONG,
          gravity: ToastGravity.BOTTOM,
        );
        return;
      }

      String zipFileName = 'forms.zip';

      await FileSaver.instance.saveFile(
        zipFileName,
        Uint8List.fromList(bytes),
        'zip',
        mimeType: MimeType.ZIP,
      );

      Fluttertoast.showToast(
        msg: 'Zip downloadato correttamente.',
        toastLength: Toast.LENGTH_LONG,
        gravity: ToastGravity.BOTTOM,
      );
    },
  ),

除了我下载的zip文件是空的之外,一切都完美无缺。

我尝试了很多不同的方法,使用html包下载,锚定并点击div,但现在我认为该软件包不起作用,我该怎么做?任何帮助都将被接受,谢谢。

附言: 这里是database.formLinks功能:

 static Future<List<Reference>> getCompiledForms() async =>
  (await formsRef.listAll()).items;

 static Future<List<String>> formLinks() async {
final List<Reference> forms = await getCompiledForms();
final List<String> links = [];
for (final form in forms) {
  String url = await form.getDownloadURL();
  links.add(url);
}
return links;

这些是我在这些函数中使用的包:

archive: ^3.1.2 (作为webarc)

http: ^0.13.3 (作为http)

file_saver: ^0.0.10

fluttertoast: ^8.0.7

cloud_firestore: ^2.3.0

1个回答

6
我上周也遇到了类似的问题,并且最终找到了解决方法。我在使用 anchor.click() 方法进行 html 下载。

将文件打包下载可以通过输入文件名字符串列表和 Uint8List 的文件数据列表来实现。

你可以尝试一下,看看这个方法是否适用于你!

  _downloadFilesAsZIP(context, List<String> filenames, files) {
    var encoder = ZipEncoder();
    var archive = Archive();
    ArchiveFile archiveFiles = ArchiveFile.stream(
      filenames[0].toString(),
      files[0].lengthInBytes,
      files[0],
    );
    print(archiveFiles);
    archive.addFile(archiveFiles);
    var outputStream = OutputStream(
      byteOrder: LITTLE_ENDIAN,
    );
    var bytes = encoder.encode(archive,
        level: Deflate.BEST_COMPRESSION, output: outputStream);
    print(bytes);
    downloadFile("out.zip", bytes);
  }

  downloadFile(String fileName, Uint8List bytes) {

    final blob = html.Blob([bytes]);
    final url = html.Url.createObjectUrlFromBlob(blob);
    final anchor = html.document.createElement('a') as html.AnchorElement
      ..href = url
      ..style.display = 'none'
      ..download = fileName;
    html.document.body.children.add(anchor);

// download
    anchor.click();

// cleanup
    html.document.body.children.remove(anchor);
    html.Url.revokeObjectUrl(url);
  }

你好,在我的情况下,我遇到了这个错误:参数类型 'Uint8List' 无法分配给参数类型 'InputStreamBase'。在 ArchiveFile.stream 内部。你能帮我吗? - Gabriel Almeida
尝试进行强制类型转换。例如:将value强制转换为InputStreamBase。 - AmateurCoder
这种方法不起作用... 我尝试了强制转换,但是仍然出现相同的错误。 - Gabriel Almeida
你能否提供你的代码作为一个新问题?这样回答会更容易!谢谢。 - AmateurCoder
你好,我已经成功解决了我的问题。我上传了一个包含我的照片链接的zip归档文件,然后在我的应用程序的另一个屏幕上下载了这个zip归档文件。运行良好。 - Gabriel Almeida
你好,我成功解决了我的问题。我上传了一个包含我的照片链接的zip存档,然后在我的应用程序的另一个屏幕上下载了这个zip存档。一切都很顺利。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接