集計したデータを CSV でダウンロードするには?

著者名: KADOYA Ryo (External link) (サイボウズ)

目次

はじめに

kintone にはデータを CSV 形式でダウンロードする機能があります。
通常の場合これで十分なのですが、場合によってはアプリをまたがるデータを集計したり、kintone.proxy() を使って他のサービスから取得したデータをダウンロードしたいことがあります。

ここは、kintone カスタマイズを使って、CSV ファイルをダウンロードするテクニックを紹介します。
このサンプルでは単純に、column1、column2 というフィールドをもったレコードを CSV に出力していますが、このテクニックを応用することで、kintone で扱えるどんなデータでもファイルに出力できます。

サンプルプログラム

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
 * Download aggregated data as csv sample program
 * Copyright (c) 2014 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */

(function() {
  'use strict';

  // 一覧ビューの表示イベント
  kintone.events.on('app.record.index.show', (events) => {

    let $link = $('#download-csv');
    if ($link.length === 0) {
      // ヘッダにリンクを作成
      const $header = $(kintone.app.getHeaderMenuSpaceElement());
      $link = $('<a id="download-csv" href="#">CSVでダウンロード</a>');
      $header.append($link);
    }

    // エスケープ
    const escapeStr = function(value) {
      return '"' + (value ? value.replace(/"/g, '""') : '') + '"';
    };

    if ((window.URL || window.webkitURL).createObjectURL == null) {
      // サポートされていないブラウザ
      return;
    }

    // CSVデータを作成
    const csv = [];
    let row = ['ID', 'column1', 'column2'];
    csv.push(row);
    for (let i = 0; i < events.records.length; i++) {
      const record = events.records[i];
      row = [];
      row.push(escapeStr(record['レコード番号'].value));
      row.push(escapeStr(record.column1.value));
      row.push(escapeStr(record.column2.value));
      csv.push(row);
    }

    // BOM付でダウンロード
    const csvbuf = csv.map((e) =>{
      return e.join(',');
    }).join('\r\n');

    const bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
    const blob = new Blob([bom, csvbuf], {type: 'text/csv'});

    const url = (window.URL || window.webkitURL).createObjectURL(blob);

    const fileName = 'download.csv';
    if (window.navigator.msSaveOrOpenBlob) {
      // for IE
      $link.unbind();
      $link.click(() => {
        const retVal = window.navigator.msSaveOrOpenBlob(blob, fileName);
      });
    } else {
      $link.attr('download', fileName);
      $link.attr('href', url);
    }
  });
})();

適用手順

このサンプルは jQuery を読み込む必要があるので、jQuery ライブラリとサンプルプログラムを順番に指定します。

  • まずは、 Cybozu CDN から jQuery ライブラリを指定します。
    アプリの設定画面から「JavaScript / CSS によるカスタマイズ」を開き、「PC 用の JavaScript ファイル」に URL 指定で次の URL を指定します。
    https://js.cybozu.com/jquery/3.7.1/jquery.min.js
  • 指定したライブラリの下に、今回の「サンプルプログラム」のファイルを追加します。
    サンプルプログラム 部分のコードをエディターにコピーして、ファイル名を「sample.js」、文字コードを「UTF-8」、BOM なしで保存します。
    ファイル名は任意ですが、ファイルの拡張子は「js」にしてください。

解説

Url 生成メソッド

このサンプルでは、window.URL.createObjectUrl メソッドを利用して Blob オブジェクトのダウンロード URL を生成しています。
window.URL.createObjectUrl の説明やサポートブラウザーについては MDN のドキュメント (External link) を参照してください。

文字エンコーディング

kintone では UTF-8 の文字エンコーディングが使用されています。
UTF-8 で出力した CSV ファイルをそのままでは Excel で開けないので、ファイルの先頭に BOM(Byte Order Mark)を付けることで、Excel で開けるようにしています。

もしどうしても Shift-JIS で出力したい場合は、外部ライブラリを利用することでエンコーディングを変換できます。
ここではぽりごん氏作の encoding.js (External link) (MIT or GPL v2 licenses)を利用した例を紹介します。

encoding.js

encoding.js はぽりごん氏によりオープンソースで提供されているライブラリです。
自己責任で利用してください。

47 行目から 54 行目を以下のように編集してください。

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// 文字列を配列に
const str2array = function(str) {
  const array = [];
  let i;
  const il = str.length;
  for (i = 0; i < il; i++) array.push(str.charCodeAt(i));
  return array;
};

// SJISの配列に変換
const csvbuf = csv.map((e) =>{
  return e.join(',');
}).join('\r\n');

const array = str2array(csvbuf);
const sjis_array = Encoding.convert(array, 'SJIS', 'UNICODE');
const uint8_array = new Uint8Array(sjis_array);
const blob = new Blob([uint8_array], {type: 'text/csv'});

const url = (window.URL || window.webkitURL).createObjectURL(blob);

おわりに

上記のテクニックを使うことで、お手軽にファイルのダウンロードをカスタマイズで実現できます。
ぜひお試しください。

information

この Tips は、2014 年 4 月版 kintone で動作を確認しています。