web-dev-qa-db-ja.com

JavaScript:ファイルを作成して保存する

ファイルに書き込むデータがあります。ファイルの保存場所を選択するためのファイルダイアログを開きます。それはすべてのブラウザで動作した場合は素晴らしいでしょうが、それはChromeで動作する必要があります。私はこれをすべてクライアントサイドで行いたいです。

基本的に私はこの関数に何を入れるべきか知りたいのです。

saveFile: function(data)
{
}

関数がデータを取り込む場所で、ファイルを保存する場所をユーザーに選択させ、そのデータでその場所にファイルを作成します。

HTMLを使用しても問題ないでしょう。

222
user1756980

trueimage (IEのサポート)で示唆されているように、 Awesomeness01 (アンカータグは不要)によるコードの非常にマイナーな改良。

// 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では、データは新しいタブで開かれるので、このファイルを手動で保存する必要があります。

184
Kanchu

Githubに関するこのプロジェクトは有望に見えます。

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

FileSaver.jsは、W3CのsaveAs()FileSaverインターフェースをネイティブにサポートしていないブラウザに実装します。

こちらのデモもご覧ください。

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

121
lostsource
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を作成するだけで済みます。

110
Awesomeness01

作成前にファイルを保存する場所を選択することはできません。しかし、少なくとも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>
37
Matt Greer
setTimeout("create('Hello world!', 'myfile.txt', 'text/plain')");
function create(text, name, type) {
  var dlbtn = document.getElementById("dlbtn");
  var file = new Blob([text], {type: type});
  dlbtn.href = URL.createObjectURL(file);
  dlbtn.download = name;
}
<a href="javascript:void(0)" id="dlbtn"><button>click here to download your file</button></a>
17
Samuel Tees

Chromeのような最新のブラウザでは、このチュートリアルのように File APIを使用できます

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

コンソールでこれを試してみました、そしてそれは働きます。

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

これを使用してみてくださいそれはファイルをダウンロードし、あなたがしなければならないのはonclick属性を編集することだけです。

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

純粋にJavascriptでこれを行うことはできません。セキュリティ上の理由から、ブラウザで実行されているJavascriptにはまだ十分な権限がありません(提案があります)。

代わりに、 Downloadify を使用することをお勧めします。

サーバーとの対話なしでテキストファイルの作成とダウンロードを可能にする小さなJavaScript + Flashライブラリ。

簡単なデモを見ることができます ここ あなたがコンテンツを供給し、保存/キャンセル/エラー処理機能を試すことができます。

6
Aamir

JavascriptはFileSystem APIを持っています。この機能がChromeでしか機能しないようにすることができる場合は、まず最初に http://www.html5rocks.com/en/tutorials/file/filesystem/ としてください。

2
Alok

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が1 MBよりも大きい場合、Chromeは失敗を示すことなく、ときどき(ときどきだけ)ダウンロードに失敗することがあります。 Firefoxはこれまでのところ、この動作を見せていません。原因は、ChromeのBLOBの制限です。率直に言って、私は知りません。誰かがどのように修正(または少なくとも検出)するかについて何かアイデアを持っている場合は、投稿してください。ダウンロードの異常が発生した場合、Chromeブラウザを閉じると、 のような診断メッセージが表示されます。 Chrome browser diagnostic
  • このコードはEdgeまたはInternet Explorerと互換性がありません。私はOperaやSafariを試したことがありません。
2
We B Martians

StreamSaver は、すべてのデータをメモリに保存しなくても、非常に大きなファイルを保存するための代替手段です。
実際には、ファイルを保存するときにサーバーが行うすべてのことをエミュレートしますが、すべてのクライアント側をService Workerでエミュレートします。

あなたはライターを取得して手動でそれにUint8Arrayのものを書くか、書き込み可能なストリームにバイナリreadStreamを渡すことができます。

example showcasingがいくつかあります。

  • 複数のファイルをZipとして保存する方法
  • readStreamをResponseblob.stream()からStreamSaverにパイプする
  • 何かを入力したときに書き込み可能なストリームに手動で書き込む
  • またはビデオ/オーディオの再コーディング

これが最も単純な形式の例です。

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

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

BLOBを保存したいのであれば、それをReadStreamに変換するだけです。

new Response(blob).body.pipeTo(...) // response hack
blob.stream().pipeTo(...) // feature reference
0
Endless