table要素をCSV形式でダウンロードする機能を実現する

table要素をCSV形式でダウンロードする機能を実現するために作成しました。
大抵のテーブルにそのまま使用できるといいな…。

仕様・制約

  • 指定のtableをCSVで取得する
  • UTF-8BOMありで出力する
    • Excel対策のため
  • カンマ(,)、ダブルクォーテーション(")、改行(\r?\n)をエスケープ文字で括る
    • エスケープ文字は、二重にする
  • display:none;の要素を取得する
    • 取得しない場合、textContentではなくinnerTextを使用する
  • <br>改行は消滅する
    • textContentの制約で<br>が消滅する
    • <br>直後に\n改行を入れると改行を取得できる(表示上は改行1回分となる)

ソース

<table class="sample-table">...</table>

<a href="javascript:void(0)" onclick="onCSVDownload(this, document.querySelector('.sample-table'), 'table.csv');">CSVダウンロード</a>
<script>
// テーブルデータのCSVダウンロード
function onCSVDownload(a, table, filename) {
  var escaped = /,|\r?\n|\r|"/;
  var e = /"/g;

  // データ作成
  var bom = new Uint8Array([0xEF, 0xBB, 0xBF]); // UTF-8BOMあり
  var csv = [], row = [], field, r, c;
  for (r=0;  r<table.rows.length; r++) {
    row.length = 0;
    for (c=0; c<table.rows[r].cells.length; c++) {
      field = table.rows[r].cells[c].textContent;
      row.push(escaped.test(field)? '"'+field.replace(e, '""')+'"': field);
      // 区切り、改行、エスケープ文字を含む場合、エスケープ文字文字で囲む(エスケープ文字は二重にする)
    }
    csv.push(row.join(','));
  }
  //var blob = new Blob([/*bom, */csv.join('\n')], {'type': 'text/csv'}); // BOMなし
  var blob = new Blob([bom, csv.join('\n')], {'type': 'text/csv'});

  // 保存
  if (window.navigator.msSaveBlob) {
    // IE用(保存 or 開く保存)
    window.navigator.msSaveBlob(blob, filename); 
    //window.navigator.msSaveOrOpenBlob(blob, filename);
  } else {
    a.download = filename;
    a.href = window.URL.createObjectURL(blob);
  }
}

</script>

サンプル

連番氏名氏名(カタカナ)性別電話番号生年月日
1深沢宗一フカザワソウイチ028-739-00041995/08/25
2浅川明夫アサカワアキオ083-168-55971979/03/18
3梅田司ウメダツカサ0779-29-45831984/03/30
4鵜飼輝夫ウカイテルオ0246-88-77961980/04/13
5山川幸子ヤマカワサチコ086-139-27811976/08/01
6大滝日出夫オオタキヒデオ0845-64-78671989/05/09
7安永博久ヤスナガヒロヒサ06-9707-21431963/11/06
8山本千尋ヤマモトチヒロ086-464-65511976/02/16
9出口祐司デクチユウジ088-18-21371963/05/28
10島津昌一郎シマヅショウイチロウ06-2275-45121991/02/04
xxxA,I
06"2275"45121991/02/04

※4列目の性別データがdisplay:none;で非表示

CSVダウンロード

参考

コメント