logo header
logo header
logo header
logo header
  • 2016.09.29
  • 技術ブログ開発

WebシステムでJavascriptを使ってCSVをダウンロードさせるには?

csv-icon

こんにちは、農道JSです。
CSVダウンロードの機能を持っているWebシステムが割と多いと思いますので、CSVダウンロードについて少し話をしたいと思います。

よくあるWebシステムの場合

例えば、あなたの作ったWebシステムで「何かしらのデータを一覧表示できる」かつ、その一覧表示画面に「CSVダウンロード」のボタンがあって、それをクリックすると現在表示されているデータを、CSV形式でダウンロードできるとします。

そのようなシステムでは、下記のユースケースが考えられます。

(1)ユーザーが「データを一覧表示する」ボタンをクリックする

  • → フロントエンドはHTMLスケルトンをGETする
    (あるいは、JavaScriptによって作成する)
  • → APIからデータをGETして、そのデータをHTMLスケルトンに入れ込む

(2)ユーザーが「CSVダウンロード」のボタンをクリックする

  • → フロントエンドはCSV出力専用のURLからCSVファイルをGETする

良くあるパターンだと思いますが、この場合、(2)で以下のような問題が生じる可能性があります。

  • サーバとやり取りが発生する為
    • トラフィックが増える
    • より遅くなる
  • セッションタイムアウト・サーバ不具合やメインテナンスがあれば、ダウンロードできない
  • 「画面を開いた時点」と「CSVダウンロードのリクエストがサーバに届いた時点」の間で、データが変わっている可能性がある

これらの問題を解消するためには、クライアント(JavaScript)からダウンロードするような仕組みにすると良いです。

具体的にどうする?

JavaScriptで「APIからデータをGET」で下記のfunctionによってデータを取っています:

returnは下記のような2D配列です:

上記の前提で、JavaScriptのコードは(モダン、HTML5サポートのブラウザで)下記になります:

プログラミング的にa要素を追加して、それにデータをURIとして追加して、そしてその要素をプログラミング的にクリックします。

もう少し使い回ししやすくすると:

そうすると、最終的な結果は下記のより分かりやすい形になります:

HTML5を対応してないブラウザは?

古い(HTML5対応してない)ChromeとFirefoxだとa要素の代わりにiframe要素を作って、document.bodyにappendChildして、その要素のsrcを上記の「data」に設定するとできます。

IE10だと

でできます。
上記の「downloadArrayAsCsv」を古いブラウザでも対応しているようにしたいなら、ブラウザを判別して、ifとelseで適切なアクションを取るようにすれば良いと思います。

以上です。

ともに世界をアップグレードできる、そんな日を夢見て。
Upgrade the World!