web-dev-qa-db-ja.com

ユーザーがダウンロードできるように、サーバー経由ではなくメモリ内にファイルを作成する方法

クライアント側でテキストファイルを作成し、ユーザーにダウンロードを促す方法はありますか。サーバーとのやり取りはありません。私は自分のマシンに直接書き込むことはできないことを知っていますが(セキュリティなど)、保存してもらうように作成してプロンプトを出すことはできますか。

731
Joseph Silber

データURIを使用できます。ブラウザのサポートはさまざまです。 ウィキペディア を参照してください。例:

<a href="data:application/octet-stream;charset=utf-16le;base64,//5mAG8AbwAgAGIAYQByAAoA">text file</a>

オクテットストリームはダウンロードプロンプトを強制することです。それ以外の場合は、おそらくブラウザで開きます。

CSVの場合は、次のものを使用できます。

<a href="data:application/octet-stream,field1%2Cfield2%0Afoo%2Cbar%0Agoo%2Cgai%0A">CSV Octet</a>

jsFiddleデモ を試してください。

398

HTML5対応ブラウザ用のシンプルなソリューション...

function download(filename, text) {
  var element = document.createElement('a');
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  element.setAttribute('download', filename);

  element.style.display = 'none';
  document.body.appendChild(element);

  element.click();

  document.body.removeChild(element);
}
form * {
  display: block;
  margin: 10px;
}
<form onsubmit="download(this['name'].value, this['text'].value)">
  <input type="text" name="name" value="test.txt">
  <textarea name="text"></textarea>
  <input type="submit" value="Download">
</form>

使用法

download('test.txt', 'Hello world!');
636
Matěj Pokorný

上記の解決策はすべて、すべてのブラウザで機能するわけではありません。これがIE 10+、Firefox、Chrome(そしてjQueryや他のライブラリなし)でついに動作するものです:

save: function(filename, data) {
    var blob = new Blob([data], {type: 'text/csv'});
    if(window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveBlob(blob, filename);
    }
    else{
        var elem = window.document.createElement('a');
        elem.href = window.URL.createObjectURL(blob);
        elem.download = filename;        
        document.body.appendChild(elem);
        elem.click();        
        document.body.removeChild(elem);
    }
}

状況に応じて、elemを削除した後に URL.revokeObjectURL を呼び出すこともできます。 URL.createObjectURL のドキュメントによると:

CreateObjectURL()を呼び出すたびに、同じオブジェクト用のURLがすでに作成されている場合でも、新しいオブジェクトURLが作成されます。これらのそれぞれは、必要なくなったときにURL.revokeObjectURL()を呼び出して解放する必要があります。ドキュメントがアンロードされると、ブラウザはこれらを自動的に解放します。ただし、最適なパフォーマンスとメモリ使用量のために、明示的にそれらをアンロードできる安全な時間がある場合は、そうするべきです。

178
Ludovic Feltz

上記の例はすべて、クロムとIEでは問題なく動作しますが、Firefoxでは失敗します。本体にアンカーを追加し、クリック後にそれを削除することを検討してください。

var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob(['Test,Text'], {type: 'text/csv'}));
a.download = 'test.csv';

// Append anchor to body.
document.body.appendChild(a);
a.click();

// Remove anchor from body
document.body.removeChild(a);
174
naren

私は FileSaver.js をうまく使っています。その互換性はかなりよく(IE10 +と他のすべて)、そしてそれは使うのがとても簡単です:

var blob = new Blob(["some text"], {
    type: "text/plain;charset=utf-8;",
});
saveAs(blob, "thing.txt");
106

次の方法は、IE11以降、Firefox 25以降、およびChrome 30以降で機能します。

<a id="export" class="myButton" download="" href="#">export</a>
<script>
    function createDownloadLink(anchorSelector, str, fileName){
        if(window.navigator.msSaveOrOpenBlob) {
            var fileData = [str];
            blobObject = new Blob(fileData);
            $(anchorSelector).click(function(){
                window.navigator.msSaveOrOpenBlob(blobObject, fileName);
            });
        } else {
            var url = "data:text/plain;charset=utf-8," + encodeURIComponent(str);
            $(anchorSelector).attr("download", fileName);               
            $(anchorSelector).attr("href", url);
        }
    }

    $(function () {
        var str = "hi,file";
        createDownloadLink("#export",str,"file.txt");
    });

</script>

アクションでこれを参照してください: http://jsfiddle.net/Kg7eA/ /

FirefoxとChromeはナビゲーション用のデータURIをサポートしています。これにより、データURIに移動してファイルを作成できますが、IEはセキュリティ上の理由からそれをサポートしていません。

一方、IEにはBLOBを保存するためのAPIがあり、これを使用してファイルを作成およびダウンロードできます。

22
dinesh ygv

この解決策は、tiddlywikiの(tiddlywiki.com)githubリポジトリから直接抽出されます。私はほとんどすべてのブラウザでtiddlywikiを使ってきましたが、それは魅力のように機能します。

function(filename,text){
    // Set up the link
    var link = document.createElement("a");
    link.setAttribute("target","_blank");
    if(Blob !== undefined) {
        var blob = new Blob([text], {type: "text/plain"});
        link.setAttribute("href", URL.createObjectURL(blob));
    } else {
        link.setAttribute("href","data:text/plain," + encodeURIComponent(text));
    }
    link.setAttribute("download",filename);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}

Githubレポ: ダウンロードセーバーモジュール

12
Danielo515

IE10で動作するソリューション:(私はcsvファイルが必要でしたが、それはtxtにタイプとファイル名を変更するのに十分です)

var csvContent=data; //here we load our csv data 
var blob = new Blob([csvContent],{
    type: "text/csv;charset=utf-8;"
});

navigator.msSaveBlob(blob, "filename.csv")
10
Dzarek

ダウンロード可能になるように文字列を変換するだけの場合は、jQueryを使用してこれを試すことができます。

$('a.download').attr('href', 'data:application/csv;charset=utf-8,' + encodeURI(data));
9
Rick
var element = document.createElement('a');
element.setAttribute('href', 'data:text/text;charset=utf-8,' +      encodeURI(data));
element.setAttribute('download', "fileName.txt");
element.click();
7
MANVENDRA LODHI

前述のように、 filesaver はクライアント側でファイルを操作するための素晴らしいパッケージです。しかし、大きなファイルではうまくいきません。 StreamSaver.js は、大きなファイルを処理することができる(FileServer.jsで指定されている)代替ソリューションです。

const fileStream = streamSaver.createWriteStream('filename.txt', size);
const writer = fileStream.getWriter();
for(var i = 0; i < 100; i++){
    var uint8array = new TextEncoder("utf-8").encode("Plain Text");
    writer.write(uint8array);
}
writer.close()
7
Mostafa

2014年4月現在、FileSytem APIはW3Cで標準化されていない可能性があります。 BLOBで解決策を見ている人は誰でも注意してスレッドを組むべきです、と私は思います。

HTML5が急上昇

FileSytem APIのW3Cメーリングリスト /

5
pravin

本当に役に立った@Rickの回答に基づいています。

このように共有したい場合は、文字列dataを拡大縮小する必要があります。

$('a.download').attr('href', 'data:application/csv;charset=utf-8,'+ encodeURI(data));

`申し訳ありませんが、StackOverflowでの私の現在の低い評判のために@ Rickの答えにコメントできません。

編集の提案 は共有され、拒否されました。

5
atfornes

パッケージ js-file-download from - github.com/kennethjiang/js-file-download は、ブラウザサポートのためのEdgeケースを処理します。

ソースを見る このページで言及されているテクニックがどのように使われているかを見るために/。

Installation

yarn add js-file-download
npm install --save js-file-download

使用法

import fileDownload from 'js-file-download'

// fileDownload(data, filename, mime)
// mime is optional

fileDownload(data, 'filename.csv', 'text/csv')
4
Beau Smith

URIを使用するときのダウンロードの命名についてのこのブログ記事 で説明されているように、Chromeを使用してファイルの名前を提案することもできます。

3
owencm

この下の機能は働いた。

 private createDownloadableCsvFile(fileName, content) {
   let link = document.createElement("a");
   link.download = fileName;
   link.href = `data:application/octet-stream,${content}`;
   return link;
 }
1
bountyhunter

URL api、特に RL.createObjectURL() 、および Blob apiを使用して、ほとんど何でもエンコードおよびダウンロードできます。

document.body.innerHTML += 
`<a id="download" download="PATTERN.json" href="${URL.createObjectURL(new Blob([JSON.stringify("HELLO WORLD", null, 2)]))}"> Click me</a>`
download.click()
download.outerHTML = ""

ボーナス!任意の サイクリックオブジェクト をダウンロードして、エラーを回避してください:

TypeError:循環オブジェクト値(Firefox)TypeError:変換中

jSONへの循環構造(ChromeおよびOpera)TypeError:Circular

値引数の参照はサポートされていません(エッジ)

https://github.com/douglascrockford/JSON-js/blob/master/cycle.js を使用する

/* JSON.decycle */
if(typeof JSON.decycle!=="function"){JSON.decycle=function decycle(object,replacer){"use strict";var objects=new WeakMap();return(function derez(value,path){var old_path;var nu;if(replacer!==undefined){value=replacer(value)}
if(typeof value==="object"&&value!==null&&!(value instanceof Boolean)&&!(value instanceof Date)&&!(value instanceof Number)&&!(value instanceof RegExp)&&!(value instanceof String)){old_path=objects.get(value);if(old_path!==undefined){return{$ref:old_path}}
objects.set(value,path);if(Array.isArray(value)){nu=[];value.forEach(function(element,i){nu[i]=derez(element,path+"["+i+"]")})}else{nu={};Object.keys(value).forEach(function(name){nu[name]=derez(value[name],path+"["+JSON.stringify(name)+"]")})}
return nu}
return value}(object,"$"))}}


document.body.innerHTML += 
`<a id="download" download="PATTERN.json" href="${URL.createObjectURL(new Blob([JSON.stringify(JSON.decycle(document), null, 2)]))}"></a>`
download.click()
0
NVRM

私にとってこれは完全にうまくいった、同じファイル名と拡張子がダウンロードされる

<a href={"data:application/octet-stream;charset=utf-16le;base64," + file64 } download={title} >{title}</a>

'title'は拡張子sample.pdfwaterfall.jpgなどのファイル名です。

'file64'はbase64の内容で、これはWw6IDEwNDAsIFNsaWRpbmdTY2FsZUdyb3VwOiAiR3JvdXAgQiIsIE1lZGljYWxWaXNpdEZsYXRGZWU6IDM1LCBEZW50YWxQYXltZW50UGVyY2VudGFnZTogMjUsIFByb2NlZHVyZVBlcmNlbnQ6IDcwLKCFfSB7IkdyYW5kVG90YWwiOjEwNDAsIlNsaWRpbmdTY2FsZUdyb3VwIjoiR3JvdXAgQiIsIk1lZGljYWxWaXNpdEZsYXRGZWUiOjM1LCJEZW50YWxQYXltZW50UGVyY2VudGFnZSI6MjUsIlByb2NlZHVyZVBlcmNlbnQiOjcwLCJDcmVhdGVkX0J5IjoiVGVycnkgTGVlIiwiUGF0aWVudExpc3QiOlt7IlBhdGllbnROです。

0
abdul