【HTML/Javascript】フロントエンドでCSVデータを出力する方法
※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。
【目次】
【20/6/26 追記】
この記事の内容だとExcelでcsvを開くと文字化けする可能性があります。
この記事の内容+以下のサイトを参考にすると、Excelで開いても文字化けしないcsv(tav)ファイルを作ることができます(サイトのコメント欄も要チェックです)。まあExcel2016以降はUTF-8に対応されたみたいなので、この記事の内容でも問題ないかもですが...
javascript で作成したCSVファイルをエクセルで表示可能にする - Qiita
概要
Angular(フロントエンド)からCSVデータを出力したかったのですが、HTMLとJavascriptだけで簡単に出力ができたので、その備忘録を書きます。
今回のブログのコードはAngular(Typescript)で記述しますが、使用している技術はHTMLとJavascriptの技術になります。ですので、Javascriptを使用されている方も参考にできる記事になっていると思います。
CSVデータ出力方法
処理の流れ
- ユーザ(画面)がクリックイベントを発火する
- 多次元(2次元)配列でデータを作成
- 多次元(2次元)配列のデータをJSON形式に変換し、さらにCSV出力方法を追加
- HTMLでa要素を作成
- 4のa要素に3のJSON形式のデータとdownload属性を追加する
- HTMLドキュメントに5のa要素を追加する
- a要素でクリックイベントを発火させる
- a要素を破棄する
最終的にJSON形式に変換できればCSV出力はできるので、多次元(2次元)配列ではなくても、オブジェクトデータなどでもCSV出力は可能です。
多次元(2次元)配列を使った理由
2次元配列の構造は以下のような感じです。
var a = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ]
上記のデータのうち1つの要素がCSVの1行になるわけですが、上記データの構造と以下のCSVデータ構造(分かりやすいようにスプレッドシートの画像を載せています)を見比べてみるとどうですか?構造が似ていていませんか? 私は似ているなと思い、データ構造のイメージがしやすかったので、2次元配列を使うことにしました。
多次元(2次元)配列とは?
2つ以上のインデックスが組み合わさっている配列で、配列の中に配列があるイメージです。JavaScriptでは多次元配列という構文は用意されていませんが、多次元配列のように配列を組み合わせても使うことはできます。
詳しくはこちらをご覧ください。
画面とメソッドを作成
component.html
<button (click)="downloadCsv()">CSVダウンロード</button>
component.ts
export class TestComponent { downloadCsv() { // 以下で記述 } }
2次元配列データを作成し、JSON形式に変換
component.ts
downloadCsv() { const array: stirng[][] = [ ['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9'], ] // 本来であれば、foerEachやmapなどを使って2次元配列を作ることになるかと思います。その場合は、pushやconcat、new Arrayなどを使うことが多いと思います。 const csvData: string = this.arrToCSV(array) } arrToCSV(array: string[][]): string { let csvData = 'data:text/csv;charset=utf-8,'; /// 最初にcsvDataに出力方法を追加しておく arr.forEach(a => { const row = a.join(','); csvData += row + '\r\n'; }); return csvData; }
a要素を作成して、csvを出力
component.ts
downloadCsv() { ... const csvData: string = this.arrToCSV(array) const encodedUri = encodeURI(csvData); // csvDataをエンコード化する const ele = document.createElement('a'); // a要素を作成する ele.setAttribute('href', encodedUri); // a要素に出力データを追加 ele.setAttribute('download', 'test' + '.csv'); // a要素に出力情報を追加。「'test'」部分は変数を入れることも可能。 ele.style.visibility = 'hidden'; document.body.appendChild(ele); ele.click(); // HTMLドキュメントに追加したa要素を実行(clickイベント発火) document.body.removeChild(ele); }
今後に向けて
知らないことが無限に出てくる。
参考
素晴らしい記事に感謝致します。
多次元配列 - 配列 - JavaScript入門
クライアント側でCSV生成してダウンロードさせる - ryotah’s blog
【JavaScript】配列データをCSVファイルとして保存できるようにする | あれは魔法だろうか?
Export JSON to CSV file in Angular - GeeksforGeeks