312

我有要写入文件的数据,并打开一个文件对话框供用户选择保存文件的位置。如果它可以在所有浏览器中运行,那就太好了,但它必须在 Chrome 中运行。我想在客户端做这一切。

基本上我想知道在这个函数中放什么:

saveFile: function(data)
{
}

该函数在哪里接收数据,让用户选择一个位置来保存文件,并在该位置创建一个包含该数据的文件。

如果有帮助的话,使用 HTML 也很好。

4

12 回答 12

310

Awesomeness01(不需要锚标记)对代码进行了非常小的改进,并按照trueimage的建议进行了添加(支持 IE):

// Function to download data to a file
function download(data, filename, type) {
    var file = new Blob([data], {type: type});
    if (window.navigator.msSaveOrOpenBlob) // IE10+
        window.navigator.msSaveOrOpenBlob(file, filename);
    else { // Others
        var a = document.createElement("a"),
                url = URL.createObjectURL(file);
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        setTimeout(function() {
            document.body.removeChild(a);
            window.URL.revokeObjectURL(url);  
        }, 0); 
    }
}

经测试可在 Chrome、FireFox 和 IE10 中正常工作。

在 Safari 中,数据会在新选项卡中打开,并且必须手动保存此文件。

于 2015-06-14T17:09:08.520 回答
147

function download(text, name, type) {
  var a = document.getElementById("a");
  var file = new Blob([text], {type: type});
  a.href = URL.createObjectURL(file);
  a.download = name;
}
<a href="" id="a">click here to download your file</a>
<button onclick="download('file text', 'myfilename.txt', 'text/plain')">Create file</button>

然后,您可以通过将下载属性放在锚标记上来下载文件。

我喜欢这个比创建数据 url 更好的原因是你不必制作一个很大的长 url,你可以只生成一个临时 url。

于 2015-03-30T05:52:31.250 回答
139

This project on github looks promising:

https://github.com/eligrey/FileSaver.js

FileSaver.js implements the W3C saveAs() FileSaver interface in browsers that do not natively support it.

Also have a look at the demo here:

http://eligrey.com/demos/FileSaver.js/

于 2012-11-15T20:05:49.697 回答
42

在创建文件之前选择保存文件的位置是不可能的。但至少在 Chrome 中,仅使用 JavaScript 生成文件是可能的。这是我创建 CSV 文件的一个旧示例。将提示用户下载它。不幸的是,这在其他浏览器中效果不佳,尤其是 IE。

<!DOCTYPE html>
<html>
<head>
    <title>JS CSV</title>
</head>
<body>
    <button id="b">export to CSV</button>
    <script type="text/javascript">
        function exportToCsv() {
            var myCsv = "Col1,Col2,Col3\nval1,val2,val3";

            window.open('data:text/csv;charset=utf-8,' + escape(myCsv));
        }

        var button = document.getElementById('b');
        button.addEventListener('click', exportToCsv);
    </script>
</body>
</html>
于 2012-11-15T20:08:19.197 回答
15

function download(text, name, type) {
  var a = document.getElementById("a");
  var file = new Blob([text], {type: type});
  a.href = URL.createObjectURL(file);
  a.download = name;
}
<a href="" id="a">click here to download your file</a>
<button onclick="download('file text', 'myfilename.json', 'text/json')">Create file</button>

如果您更改 mime 类型,我认为这也可以与 json 文件一起使用。

于 2020-02-10T20:22:40.490 回答
14

For latest browser, like Chrome, you can use the File API as in this tutorial:

window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.PERSISTENT, 5*1024*1024 /*5MB*/, saveFile, errorHandler);
于 2012-11-15T20:05:34.230 回答
10
function SaveBlobAs(blob, file_name) {
    if (typeof navigator.msSaveBlob == "function")
        return navigator.msSaveBlob(blob, file_name);

    var saver = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
    var blobURL = saver.href = URL.createObjectURL(blob), 
        body = document.body;

    saver.download = file_name;

    body.appendChild(saver);
    saver.dispatchEvent(new MouseEvent("click"));
    body.removeChild(saver);
    URL.revokeObjectURL(blobURL);
}
于 2019-10-12T16:37:16.793 回答
9

在控制台中尝试了这个,它可以工作。

var aFileParts = ['<a id="a"><b id="b">hey!</b></a>'];
var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // the blob
window.open(URL.createObjectURL(oMyBlob));
于 2015-04-11T09:47:36.037 回答
5

您不能仅在 Javascript 中执行此操作。由于安全原因,在浏览器上运行的 Javascript 还没有足够的权限(有提议)。

相反,我建议使用Downloadify

一个小型 javascript + Flash 库,无需服务器交互即可创建和下载文本文件。

您可以在这里看到一个简单的演示,您可以在其中提供内容并测试保存/取消/错误处理功能。

于 2012-11-15T20:02:56.913 回答
4

对于 Chrome 和 Firefox,我一直在使用纯 JavaScript 方法。

(我的应用程序不能使用一个包,Blob.js因为它是由一个特殊的引擎提供的:一个带有 WWWeb 服务器的 DSP,几乎没有空间容纳任何东西。)

function FileSave(sourceText, fileIdentity) {
    var workElement = document.createElement("a");
    if ('download' in workElement) {
        workElement.href = "data:" + 'text/plain' + "charset=utf-8," + escape(sourceText);
        workElement.setAttribute("download", fileIdentity);
        document.body.appendChild(workElement);
        var eventMouse = document.createEvent("MouseEvents");
        eventMouse.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        workElement.dispatchEvent(eventMouse);
        document.body.removeChild(workElement);
    } else throw 'File saving not supported for this browser';
}

注释、警告和黄鼠狼的话:

  • 我在 Linux (Maipo) 和 Windows (7 和 10) 环境中运行的 Chrome 和 Firefox 客户端中使用此代码取得了成功。
  • 但是,如果sourceText大于 MB,Chrome 有时(仅有时)会卡在自己的下载中而没有任何失败指示;到目前为止,Firefox 还没有表现出这种行为。原因可能是 Chrome 中的一些 blob 限制。坦率地说,我只是不知道;如果有人对如何纠正(或至少检测)有任何想法,请发布。如果出现下载异常,当 Chrome 浏览器关闭时,它会生成诊断信息,例如 Chrome 浏览器诊断
  • 此代码与 Edge 或 Internet Explorer 不兼容;我没有尝试过 Opera 或 Safari。
于 2018-02-22T01:28:47.140 回答
2

StreamSaver是一种替代方法,可以保存非常大的文件,而无需将所有数据保存在内存中。
事实上,它模拟了服务器在保存文件时所使用的所有内容,但所有客户端都使用服务工作者。

您可以获取编写器并手动将 Uint8Array 写入其中,也可以将二进制可读流通过管道传输到可写流

有几个例子展示:

  • 如何将多个文件保存为 zip
  • 将 readableStream 从例如管道Response传输blob.stream()到 StreamSaver
  • 键入内容时手动写入可写流
  • 或重新编码视频/音频

这是最简单形式的示例:

const fileStream = streamSaver.createWriteStream('filename.txt')

new Response('StreamSaver is awesome').body
  .pipeTo(fileStream)
  .then(success, error)

如果要保存 blob,只需将其转换为 readableStream

new Response(blob).body.pipeTo(...) // response hack
blob.stream().pipeTo(...) // feature reference
于 2019-05-31T19:41:06.240 回答
1

Javascript 有一个 FileSystem API。如果您可以处理仅在 Chrome 中使用该功能,那么一个很好的起点是:http ://www.html5rocks.com/en/tutorials/file/filesystem/ 。

于 2014-12-20T06:22:07.167 回答