【问题标题】:Javascript: Download data to file from content within the pageJavascript:从页面内的内容下载数据到文件
【发布时间】:2018-02-24 18:12:31
【问题描述】:

设置如下: 我有一个主页,其中显示了使用页面内的逗号分隔值构建的图表。我想让用户可以将数据下载为 cvs 文件,而无需再次联系服务器。 (因为数据已经存在) 这有可能吗?我更喜欢纯 JavaScript 解决方案。

到目前为止,我发现:http://pixelgraphics.us/downloadify/test.html 但它涉及我想避免的闪存。

我无法想象这个问题以前没有被问过。很抱歉重复发帖,但似乎我使用了错误的关键字或其他什么 - 我在这些论坛中没有找到解决方案。

【问题讨论】:

    标签: javascript file download local


    【解决方案1】:

    在 Safari 5、Firefox 6、Opera 12、Chrome 26 上测试。

    <a id='a'>Download CSV</a>
    <script>
        var csv = 'a,b,c\n1,2,3\n';
        var a = document.getElementById('a');
        a.href='data:text/csv;base64,' + btoa(csv);
    </script>
    

    HTML5

    <a id='a' download='Download.csv' type='text/csv'>Download CSV</a>
    <script>
        var csv = 'a,b,c\n1,2,3\n';
        var data = new Blob([csv]);
        var a = document.getElementById('a');
        a.href = URL.createObjectURL(data);
    </script>
    

    【讨论】:

    • 这是我使用的,但是在 Mozzila Firefox 中,它会导致大文件 (>6MB) 的可怕滞后。
    • 如果 URL 太大,那么在 Chrome 中下载将会失败。
    • 听听“太大”是什么意思会很有帮助。您要下载多少 MB?您可能需要使用 HTML 5 方法,因为旧方法只能处理 ~4kB,具体取决于浏览器。
    • 对于大文件,问题是html解析器需要解析整个字符串,需要时间...
    【解决方案2】:

    简单的解决方案:

    function download(content, filename, contentType)
    {
        if(!contentType) contentType = 'application/octet-stream';
            var a = document.createElement('a');
            var blob = new Blob([content], {'type':contentType});
            a.href = window.URL.createObjectURL(blob);
            a.download = filename;
            a.click();
    }
    

    用法

    download("csv_data_here", "filename.csv", "text/csv");
    

    【讨论】:

    • 'application/octet-stream' 是我的关键:+1:
    【解决方案3】:

    更新

    时间肯定会改变事情 ;-) 当我第一次回答这个问题时,IE8 是可用的最新 IE 浏览器(2010 年 11 月),因此没有跨浏览器的方式来实现这一点而无需往返服务器,或使用需要 Flash 的工具。

    @Zectburno's answer 将为您提供您现在需要的东西,但是对于历史背景,请注意哪些 IE 浏览器支持哪些功能。

    • btoa() 在 IE8 和 IE9 中未定义
    • Blob 在 IE10+ 中可用

    请务必在您需要支持的浏览器中进行测试。即使另一个答案中的 Blob 示例应该在 IE10+ 中工作,它也不适用于我只需单击链接(浏览器不执行任何操作,没有错误)......只有当我右键单击并将目标另存为“file.csv”然后导航到文件并双击它可以打开文件。

    Test both approaches (btoa/Blob) in this JSFiddle. (这里是代码)

    <!doctype html>
    <html>
    <head>
    </head>
    <body>
      <a id="a" target="_blank">Download CSV (via btoa)</a>
      <script>
        var csv = "a,b,c\n1,2,3\n";
        var a = document.getElementById("a");
        a.href = "data:text/csv;base64," + btoa(csv);
      </script>
      <hr/>
      <a id="a2" download="Download.csv" type="text/csv">Download CSV (via Blob)</a>
      <script>
        var csv = "a,b,c\n1,2,3\n";
        var data = new Blob([csv]);
        var a2 = document.getElementById("a2");
        a2.href = URL.createObjectURL(data);
      </script>
    </body>
    </html>
    

    原答案

    我认为没有可用的选项。

    我会调整您的代码,以便如果在用户系统上检测到 Flash 10+ (93% saturation as of September 2009),则提供 Downloadify 选项,否则回退到服务器端请求。

    【讨论】:

    • 可以从javascript调用dowloadify吗?创建一个适合我的设计的 Flash 按钮会很棘手。
    • @TomášZato 是的,它可以被 JavaScript 调用:github.com/dcneiner/Downloadify
    • 不知道这对我的问题有何回答。我已经阅读了“文档”,但是我的问题是是否可以从 javascript 触发下载。不幸的是 impossible - 必须点击下载按钮。
    • 需要点击,但不需要下载!
    【解决方案4】:

    据我所知,这是不可能的:这就是创建 Downloadify 的原因。

    您可以尝试链接到包含 CSV 数据的data:URL,但会出现跨浏览器问题。

    【讨论】:

      【解决方案5】:
      function export(exportAs) {
          var csvText = tableRowsToCSV(this.headTable.rows);­
          csvText += tableRowsToCSV(this.bodyTable.rows);­
          //open the iframe doc for writing
          var expIFrame;
          if (strBrowser == "MSIE") expIFrame = document.exportiframe;
          else expIFrame = window.framesexportiframe;
          var doc = expIFrame.document;
          doc.open('text/plain', 'replace');
          doc.charset = "utf-8";
          doc.write(csvText);
          doc.close();
          var fileName = exportAs + ".txt";
          doc.execCommand("SaveAs", null, fileName);
      }
      
      function tableRowsToCSV(theRows) {
          var csv = "";
          var csvRow = "";
          var theCells;
          var cellData = "";
          for (var r = 0; r < theRows.length; r++) {
              theCells = theRows.item(r).cells;
              for (var c = 0; c < theCells.length; c++) {
                  cellData = "";
                  cellData = theCells.item(c).innerText;
                  if (cellData.indexOf(",") != -1) cellData = "'" + cellData + "'";
                  if (cellData != "") csvRow += "," + cellData;
              }
              if (csvRow != "") csvRow = csvRow.substring(1, csvRow.length);­
              csv += csvRow + "\n";
              csvRow = "";
          }
          return csv;
      }
      

      我以前在其他地方找到了这段代码,here

      【讨论】:

      • expIFrame = window.framesexportiframe; //window中没有framesexportiframe属性!
      【解决方案6】:

      如果您的用户拥有最新的浏览器,新的 Blob 对象可以帮助您。

      根据此处的示例https://developer.mozilla.org/en/docs/DOM/Blob(“Blob 构造函数示例用法”),您可以执行以下操作:

      var typedArray = "123,abc,456"; //your csv as a string
      var blob = new Blob([typedArray], {type: "text/csv"});
      var url = URL.createObjectURL(blob);
      var a = document.querySelector("#linktocsv"); // the id of the <a> element where you will render the download link
      a.href = url;
      a.download = "file.csv";
      

      【讨论】:

        【解决方案7】:

        HTML:

        <a href="javascript:onDownload();">Download</a>
        

        JavaScript:

        function onDownload() {
            document.location = 'data:Application/octet-stream,' +
                                 encodeURIComponent(dataToDownload);
        }
        

        取自How to Download Data as a File From JavaScript

        【讨论】:

        • 这是一个简单的解决方案,但正如原始来源中所提到的,目前尚不清楚为下载文件命名的方法。如果有人知道这个问题的解决方案,将不胜感激。
        【解决方案8】:

        我遇到过的最全面的解决方案是使用FileSaver.js,它可以为您处理许多潜在的跨浏览器问题并提供回退。

        它像其他海报一样利用Blob 对象,创建者甚至创建了一个Blob.js polyfill,以防您需要支持不支持@987654323 的浏览器版本@

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-10
          • 2010-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多