【问题标题】:How to save and download text file in Flutter web application如何在 Flutter Web 应用程序中保存和下载文本文件
【发布时间】:2020-04-27 00:33:51
【问题描述】:

我是 Flutter 的新手,在 Flutter Web 应用程序中工作,我的要求是创建和下载一个文本文件。如下所示。

void getData() {
    List<int> bytes = utf8.encode('this is the text file');
    print(bytes); // Need to download this with txt file.
}

谁能帮我实现这个目标

【问题讨论】:

    标签: flutter dart flutter-web


    【解决方案1】:

    此方法基于对HTML 文档的操作。 应该导入一些额外的包:

    import 'dart:convert';
    import 'dart:html' as html; // or package:universal_html/prefer_universal/html.dart
    

    代码sn-p:

    final text = 'this is the text file';
    
    // prepare
    final bytes = utf8.encode(text);
    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 = 'some_name.txt';
    html.document.body.children.add(anchor);
    
    // download
    anchor.click();
    
    // cleanup
    html.document.body.children.remove(anchor);
    html.Url.revokeObjectUrl(url);
    
    

    HereDartPad 演示。

    【讨论】:

    • 谢谢!感觉有点hacky,但它有效。不幸的是,我没有在 Chrome 中看到“另存为”对话框,它只是开始下载文件。我打开了“下载前询问每个文件的保存位置”设置。
    • @OleksiiShliama 如果您查看 FileSaver.js 库,它实际上在做与 Spatz 所做的完全相同的事情 :)。检查here。在 chrome 中,我也会出现另存为对话框。可能是版本问题..?
    • DartPad 下载按钮没有下载任何文件?
    • @Abdullah Khan 谢谢!由于 new security restrictions 确实在 chrome 中被阻止,但在 Firefox 中仍然有效。
    • @Abdullah Khan 此代码仍然有效 - 仅沙盒 iframe 存在问题(dartpad 在内部使用一个)。
    【解决方案2】:

    还有另一种方法,通过称为FileSaver 的流行 JS 库

    首先,更新您的ProjectFolder/web/index.html 文件以包含库并定义webSaveAs 函数,如下所示:

    ...
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.min.js"> 
    </script>
    
    <script>
    function webSaveAs(blob, name) {
      saveAs(blob, name);
    }
    </script>
    
    <script src="main.dart.js" type="application/javascript"></script>
    
    ...
    

    然后你可以像这样从 Dart 代码中调用这个函数:

    import 'dart:js' as js;
    import 'dart:html' as html;
    
    ...
    
    js.context.callMethod("webSaveAs", [html.Blob([bytes], "test.txt"])
    

    【讨论】:

    • 最后一行有一个小错字。这里也是列表文字 js.context.callMethod('webSaveAs', [ html.Blob(>[bytes]), 'test.txt' ]); (如果你的 linter 没有给你警告,你可以去掉 > 。
    【解决方案3】:

    如果您只想保存一个文本文件,这种方法比处理所有这些转换更直接:

    import 'dart:convert' show utf8;
    
    // ignore: avoid_web_libraries_in_flutter
    import 'dart:html' show AnchorElement;
    
    void saveTextFile(String text, String filename) {
      AnchorElement()
        ..href = '${Uri.dataFromString(text, mimeType: 'text/plain', encoding: utf8)}'
        ..download = filename
        ..style.display = 'none'
        ..click();
    }
    

    您可以根据需要更改 mimeType 和编码。比如我最近一个项目要生成CSV文件,所以我用mimeType: 'text/csv'

    【讨论】:

      【解决方案4】:

      此解决方案使用 FileSaver.js 库,它应该打开“saveAs”对话框。

      我希望它能按预期工作:

      import 'dart:js' as js;
      import 'dart:html' as html;
      
      ...
      
      final text = 'this is the text file';
      final bytes = utf8.encode(text);
      
      final script = html.document.createElement('script') as html.ScriptElement;
      script.src = "http://cdn.jsdelivr.net/g/filesaver.js";
      
      html.document.body.nodes.add(script);
      
      // calls the "saveAs" method from the FileSaver.js libray
      js.context.callMethod("saveAs", [
        html.Blob([bytes]),
        "testText.txt",            //File Name (optional) defaults to "download"
        "text/plain;charset=utf-8" //File Type (optional)
      ]);
      
       // cleanup
       html.document.body.nodes.remove(script);
      

      【讨论】:

      • 我不断收到“未找到另存为方法”错误。有其他人看过这个吗?
      • 我不知道你为什么不断收到这个错误。很抱歉我帮不上忙
      • @HassanAnsari 你让它在托管网站上工作吗?
      • 是的,我做到了,我创建了一个用于保存文件的插件,在网络上它将下载文件,在所有其他 5 平台上它将保存在文档文件夹中。这里是pub.dev/packages/file_saver
      【解决方案5】:

      我偶然发现了这一点,几乎没有发现任何东西,但从最新的颤振版本 2.5.0 开始,这对我有用。

      您必须将此脚本添加到您的 web/index.html 文件的正文中

      <script src="https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.21.15/plugins/export/libs/FileSaver.js/FileSaver.min.js"></script> 
      

      然后只需使用此方法下载任何类型的文件

      void save(Object bytes, String fileName) {
        js.context.callMethod("saveAs", <Object>[
          html.Blob(<Object>[bytes]),
          fileName
        ]);
      }
      

      例如,我想从服务器下载 JSON 响应,所以我这样称呼它。

      save(json.encode(response.data), 'file.json');
      

      使用这种方法几乎可以下载任何类型的文件,我确实使用这种方法下载图像和 JSON 文件,非常简单。

      【讨论】:

        猜你喜欢
        • 2020-10-10
        • 1970-01-01
        • 2014-07-11
        • 2019-03-16
        • 1970-01-01
        • 2017-01-03
        • 2020-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多