1. ホーム
  2. javascript

サーバーとの連携なしでjavascriptのデータをCSVファイルに書き出す

2023-08-13 17:51:06

質問

nodeJSサーバであれば、ヘッダを書き、MIMEタイプを設定して、送信することができます。

res.header("Content-Disposition", "attachment;filename="+name+".csv"); 
res.type("text/csv");
res.send(200, csvString);

というヘッダがあるため、ブラウザは名前付きcsvファイルのダウンロードを作成します。

ブラウザで有用なデータが生成されたとき、それを CSV ファイルで取得するための 1 つの解決策は、ajax を使用してサーバーにアップロードし、(おそらくオプションでそこに保存し)サーバーがこれらのヘッダーを使用してそれを送り返し、ブラウザで csv ダウンロードになるようにすることです。

しかし、私は、サーバーとのピンポンを伴わない、100% ブラウザーのソリューションを望んでいます。

そこで、新しいウィンドウを開いて、META タグに相当するヘッダーを設定することを試みることができるのではないかと思いつきました。

しかし、これは最近のChromeではうまくいきません。

私は新しいウィンドウを取得し、それはcsvStringを含んでいますが、ダウンロードとして動作しません。

私は、下のタブにダウンロードが表示されるか、下のタブにダウンロードが表示された空白の新しいウィンドウが表示されることを期待していたのだと思います。

metaタグが正しいのか、他のタグも必要なのか気になるところです。

サーバーにパンクさせることなく、うまくいく方法はないでしょうか?

ブラウザでCSVを作成するJsFiddle(動作しない-ウィンドウは出力されるがダウンロードされない)

var A = [['n','sqrt(n)']];  // initialize array of rows with header row as 1st item
for(var j=1;j<10;++j){ A.push([j, Math.sqrt(j)]) }
var csvRows = [];
for(var i=0,l=A.length; i<l; ++i){
    csvRows.push(A[i].join(','));   // unquoted CSV row
}
var csvString = csvRows.join("\n");
console.log(csvString);
var csvWin = window.open("","","");
csvWin.document.write('<meta name="content-type" content="text/csv">');
csvWin.document.write('<meta name="content-disposition" content="attachment;  filename=data.csv">  ');
csvWin.document.write(csvString);

どのように解決するのですか?

常に、HTML5 の download 属性があります。

この属性がある場合、作者はそのハイパーリンクがリソースのダウンロードに使われることを意図していることを示します。 ハイパーリンクがリソースをダウンロードするために使用されることを示します。 リンクをクリックすると、ローカル ファイルとして保存するよう促されます。

属性に値がある場合、その値はあらかじめ入力されたファイル名として使用されます。 ユーザーがリンクをクリックしたときに表示される保存のプロンプトで、事前に入力されたファイル名として使用されます。 リンクをクリックしたときに表示される保存プロンプトで、事前に入力されたファイル名として使用されます。

var A = [['n','sqrt(n)']];

for(var j=1; j<10; ++j){ 
    A.push([j, Math.sqrt(j)]);
}

var csvRows = [];

for(var i=0, l=A.length; i<l; ++i){
    csvRows.push(A[i].join(','));
}

var csvString = csvRows.join("%0A");
var a         = document.createElement('a');
a.href        = 'data:attachment/csv,' +  encodeURIComponent(csvString);
a.target      = '_blank';
a.download    = 'myFile.csv';

document.body.appendChild(a);
a.click();

フィドル

Chrome と Firefox でテスト。最新版では正常に動作します。 (2013年7月現在) .

Operaでも同様に動作しますが、ファイル名を設定しません。 (2013年7月現在) .

IE9 では動作しないようです (大きな驚き) (2013 年 7 月現在) .

download 属性をサポートしているブラウザの概要は、以下のとおりです。 ここで

非対応ブラウザの場合は、サーバーサイドで適切なヘッダを設定する必要があります。


どうやら IE10 と IE11 用のハックがあります。 をサポートしていないようです。 download 属性がサポートされていません。 (をサポートしていません(Edge ではサポートしています)。 .

var A = [['n','sqrt(n)']];

for(var j=1; j<10; ++j){ 
    A.push([j, Math.sqrt(j)]);
}

var csvRows = [];

for(var i=0, l=A.length; i<l; ++i){
    csvRows.push(A[i].join(','));
}

var csvString = csvRows.join("%0A");

if (window.navigator.msSaveOrOpenBlob) {
    var blob = new Blob([csvString]);
    window.navigator.msSaveOrOpenBlob(blob, 'myFile.csv');
} else {
    var a         = document.createElement('a');
    a.href        = 'data:attachment/csv,' +  encodeURIComponent(csvString);
    a.target      = '_blank';
    a.download    = 'myFile.csv';
    document.body.appendChild(a);
    a.click();
}