用JavaScript创建并保存一个文件

我有想要写入文件的数据,并打开一个文件对话框供用户选择保存文件的位置。如果它能在所有浏览器中工作就太好了,但它必须在Chrome中工作。我想在客户端完成。

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

saveFile: function(data)
{
}

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

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

931708 次浏览

你不能单纯地在Javascript中做到这一点。由于安全原因,Javascript在浏览器上运行还没有足够的权限(已经提出了建议)。

相反,我建议使用Downloadify:

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

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

对于最新的浏览器,比如Chrome,你可以使用本教程中的文件API:

window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.PERSISTENT, 5*1024*1024 /*5MB*/, saveFile, errorHandler);

这个项目在github上看起来很有前途:

https://github.com/eligrey/FileSaver.js < a href = " https://github.com/eligrey/FileSaver.js " > < / >

中实现了W3C saveAs() FileSaver接口

也可以看看这里的演示:

http://eligrey.com/demos/FileSaver.js/ < a href = " http://eligrey.com/demos/FileSaver.js/ " > < / >

不可能在创建文件之前选择保存文件的位置。但至少在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>

Javascript有一个文件系统API。如果你能处理有功能只在Chrome中工作,一个好的起点将是:http://www.html5rocks.com/en/tutorials/file/filesystem/

.
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>

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

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

在控制台中尝试了这一点,并且它可以工作。

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));

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中,数据在一个新选项卡中打开,必须手动保存该文件。

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

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

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。

StreamSaver是保存非常大的文件,而不必将所有数据保存在内存中的替代方案。事实上,它模拟了服务器保存文件时的所有剂量,但所有客户端都使用service worker。

你可以获取写入器并手动写入Uint8Array的Uint8Array,或者将二进制readableStream管道到可写流

有一些例子显示:

  • 如何将多个文件保存为zip文件
  • 将readableStream从例如Responseblob.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
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);
}