LoginSignup
43
44

More than 5 years have passed since last update.

JavaScriptでCSVエクスポートを実装してみた。

Last updated at Posted at 2017-11-28

前書き

CSVのエクスポートは、WEBアプリでは結構利用する機能だと思います。
できる限り、フロント側で完結したい内容ではありますので、JavaScriptで実装してみました。

実装

利用するのは以下二つのライブラリです。

# JsonをCSV文字列に変換してくれるライブラリ
$ npm install papaparse
$ yarn add papaparse

# 文字コード変換をしてくれるライブラリ
$ npm install encoding-japanese
$ yarn add encoding-japanese

Papaparseは、他にもできることが多く、ドキュメントが素晴らしいのでぜひご覧ください。

Papaparse

JSONをCSV形式に変換する処理

Papaparseにオブジェクト配列を渡すことで、簡単にCSV文字列(区切り文字列)に変換してくれます。

import Papa from 'papaparse';
import encoding from 'encoding-japanese';

...

// configの初期値
const config = {
  delimiter: ',', // 区切り文字
  header: true, // キーをヘッダーとして扱う
  newline: '\r\n', // 改行
};

// 区切り文字へ変換
const delimiterString = Papa.unparse(json, config);

// blobUrlへの変換
const strArray = encoding.stringToCode(delimiterString);
const convertedArray = encoding.convert(strArray,'SJIS', 'UNICODE');
const UintArray = new Uint8Array(convertedArray);
const blobUrl = new Blob([UintArray], {type: 'text/csv'});

ソースとしては以上です。
のちにダウンロードを行うため、blobへ変換しています。
その変換過程でencoding(encoding-japanese)のconvertで第2引数の文字コードに変換しています。

ダウンロード処理

ダウンロードでは、擬似的にaタグを利用して、blobを叩いてダウンロードさせるようにします。

const blob = blobUrl;
const aTag = document.createElement('a');

aTag.download = fileName;

// 各ブラウザに合わせ、CSVをダウンロード
if (window.navigator.msSaveBlob) {
  // for IE
  window.navigator.msSaveBlob(blob, aTag.download);
} else if (window.URL && window.URL.createObjectURL) {
  // for Firefox
  aTag.href = window.URL.createObjectURL(blob);

  document.body.appendChild(aTag);

  aTag.click();

  document.body.removeChild(aTag);
} else if (window.webkitURL && window.webkitURL.createObject) {
  // for Chrome
  aTag.href = (window.URL || window.webkitURL).createObjectURL(blob);

  aTag.click();
} else {
  // for Safari
  window.open(
    `data:type/csv;base64,${window.Base64.encode(this.state.content)}`,
    '_blank'
  );
}

ダウンロードの処理には、ほとんどPapaparseもencoding-japaneseも利用しません。
各ブラウザで保存方法が違うので、制御式を書いています。
(aタグ使わずにもっといい書き方あるのかな。。。)

まとめ

まとめとして、一連のソースを記述します。

const config = {
  delimiter: ',', // 区切り文字
  header: true, // キーをヘッダーとして扱う
  newline: '\r\n', // 改行
};

// 区切り文字へ変換
const delimiterString = Papa.unparse(json, config);

// blobUrlへの変換
const strArray = encoding.stringToCode(delimiterString);
const convertedArray = encoding.convert(strArray,'SJIS', 'UNICODE');
const UintArray = new Uint8Array(convertedArray);
const blobUrl = new Blob([UintArray], {type: 'text/csv'});
const blob = blobUrl;
const aTag = document.createElement('a');

aTag.download = fileName;

// 各ブラウザに合わせ、CSVをダウンロード
if (window.navigator.msSaveBlob) {
  // for IE
  window.navigator.msSaveBlob(blob, aTag.download);
} else if (window.URL && window.URL.createObjectURL) {
  // for Firefox
  aTag.href = window.URL.createObjectURL(blob);

  document.body.appendChild(aTag);

  aTag.click();

  document.body.removeChild(aTag);
} else if (window.webkitURL && window.webkitURL.createObject) {
  // for Chrome
  aTag.href = (window.URL || window.webkitURL).createObjectURL(blob);

  aTag.click();
} else {
  // for Safari
  window.open(
    `data:type/csv;base64,${window.Base64.encode(this.state.content)}`,
    '_blank'
  );
}

後書き

フロント側でも簡単にCSVエクスポートが実装できました。
Papaparseを使えば、インポート処理も実装できるので、なかなか重宝します。

43
44
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
44