【kintone】JavaScriptでレコード一覧をCSVファイルで出力してみよう

CSVをJavaScriptでちょっぴり柔軟に出力したい！！！

と思うことがありますよね。

今日はJavaScriptを出力する機能を作ってみましょう。
ちょっと長め＆重めです💦

# アプリの準備

kintone アプリストアから、顧客リストを「サンプルデータを含める」にチェックを付けて作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/2e4e0239-dbd4-41fc-20de-b749539fcaf1.png)

# JavaScript

JavaScript全体のコードはこちら
[kintoneのレコード一覧CSVファイルダウンロードするスクリプト](https://gist.github.com/juridon/5cb8decb56687b103fb80d21a2d6944d)

## ボタンをつける
こちらの記事を参考にボタンを設置します。
[【kintone】アプリの「スペース」フィールドにボタンを設置する](https://qiita.com/juri_don/items/53a7e8c3f4d63ca9dcca)

ボタンの機能の中身は↓のようにしておいてください。

```js
//ボタンをクリックしたときの動作
btn.onclick=()=>{
    //CSVダウンロード
    dlCsv();
}
```

## encoding.js

[Cybozu CDN](https://developer.cybozu.io/hc/ja/articles/202960194-Cybozu-CDN)
↓こちらを「JavaScript / CSSでカスタマイズ」の設定に追加しておきます。
https://js.cybozu.com/encodingjs/1.0.30/encoding.min.js

## CSVを出力する機能を書く

↓こちらを参考にkintoneのレコードをCSVファイルに書き込むようなコードにしてみました。
解説は後述します。

参考：
[ファイルをダウンロード保存する方法](https://javascript.keicode.com/newjs/download-files.php#2)
[ブラウザからjsの配列をcsvとしてダウンロードする。](https://qiita.com/ooooooo_q/items/69d67aabf78820d45e46)
[javascriptで文字コード変換](https://qiita.com/weal/items/3b3ddfb8157047119554)

```js

// 1.CSVファイル生成用
const HEADER =['会社名','部署名','担当者名','郵便番号','TEL'];//CSVに出力したいフィールドのフィールドコード

// CSVをダウンロード
const dlCsv = async ()=>{
    //フィールド名からCSVの文字列データを作る
    const setHeaderData = () => {
        let headerData = '';
        HEADER.forEach(h => {
            headerData += h + ',';
        });
        headerData += '\r\n';
        return headerData;
    };  

    //レコードからCSVの文字列データを作る
    const recordToCsvData = records => {
        let rowData = '';
        records.forEach(r => {
            HEADER.forEach(h => {
                rowData += r[h].value + ',';
            });
            rowData += '\r\n';
        });
        return rowData;
    }; 

    //URLエンコード
    const createDataUriFromString = str => {
        // 文字列を配列に変換
        const array = str.split('').map(s => s.charCodeAt());
        // エンコード
        const sjis_array = Encoding.convert(array, 'SJIS', 'UNICODE');
        const uInt8List = new Uint8Array(sjis_array);
        return uInt8List;
    };  
    
    //2. CSVにしたいレコードを取得する
    const param_get = {
        app:kintone.app.getId(),
        //query:'出力フラグ != 1', // 絞り込みたいときはクエリを書く"出力フラグ = 0" など
    };
    const obj_get = await kintone.api('/k/v1/records','GET',param_get);
    const targetRecords =obj_get.records;

    //3. レコード1件以上だったらCSV出力
    if (targetRecords.length > 0) {

        //4. CSVにするテキストデータを作成
        const str = createDataUriFromString( setHeaderData() + recordToCsvData(targetRecords));

        //5. CSVファイル作成
        const blob = new Blob([str], {type:"text\/csv"});
        const url = URL.createObjectURL(blob);
    
        //6. ダウンロード処理
        const a = document.createElement("a");
        document.body.appendChild(a);
        a.download = "test.csv";//ここすきなファイル名に
        a.href = url;
        a.click();
        a.remove();
        URL.revokeObjectURL(url);

        // // 出力フラグをONにするようなコードはこのへんに
        // let param_records = [～,～, ～,～];
        // const param_upd = {
        //     app:kintone.app.getId(),
        //     records:param_records,
        // };
        // const obj_put = await kintone.api('/k/v1/records','PUT',param_upd);
    }
}
```

## CSVダウンロードの流れ

ざっくり解説ですが、流れとしてはこの順で実行します。

1. 設定の定数
1. CSVにしたいレコードを取得する
2. レコード1件以上だったらCSV出力するIF文（レコード無ければ終了）
3. CSVにするテキストデータを作成
4. CSVファイル作成
5. ダウンロード処理


一つずつ見ていきます。

### 1.設定の定数

HEADER に、出力したいフィールドのフィールドコードを配列で書いておきます。

```js
// CSVファイル生成用
const HEADER =['会社名','部署名','担当者名','郵便番号','TEL'];//CSVに出力したいフィールドのフィールドコード
```

### 2.CSVにしたいレコードを取得する

出力したいCSVの元になるレコードを取りに行きます。
ここで、アプリに「出力フラグ」などを準備しておくと、queryに未出力のレコードを指定できたりします。
たとえば`query:'出力フラグ != 1',`など・・・。

`targetRecords = obj_get.records;`の部分でレコードの配列が代入されます。

参考：[レコードの一括取得（クエリで条件を指定）](https://developer.cybozu.io/hc/ja/articles/202331474#step2)

```js
    //CSVにしたいレコードを取得する(1)
    const param_get = {
        app:kintone.app.getId(),
        //query:'出力フラグ != 1', // 絞り込みたいときはクエリを書く
    };
    const obj_get = await kintone.api('/k/v1/records','GET',param_get);
    const targetRecords = obj_get.records;
```


### 3.レコード1件以上だったらCSV出力
2.で取得したレコードが1件以上だったら出力しましょう

```js
    //レコード1件以上だったらCSV出力(2)
    if (targetRecords.length > 0) {　～～
```

### 4.CSVにするテキストデータを作成

上の方でたくさん定義してあるCSV作成のための関数を使っています。
関数たちはこちらを参考に書いています。
参考：
[ブラウザからjsの配列をcsvとしてダウンロードする。](https://qiita.com/ooooooo_q/items/69d67aabf78820d45e46)
[javascriptで文字コード変換](https://qiita.com/weal/items/3b3ddfb8157047119554)

```js
    //CSVにするテキストデータを作成
    const str = createDataUriFromString( setHeaderData() + recordToCsvData(targetRecords));
```

### 5.CSVファイル作成
4.で作ったstrをCSV「ファイル」にします。
5.6.は↓のサイトを参考にしています。
参考：[ファイルをダウンロード保存する方法](https://javascript.keicode.com/newjs/download-files.php#2)

```js
    //CSVファイル作成(4)
    const blob = new Blob([str], {type:"text\/csv"});
    const url = URL.createObjectURL(blob);
```


### 6.ファイルのダウンロード処理
ダウンロードするときは、aタグを隠してクリックして削除するという流れなんですね。勉強になりました。

```js

    //ダウンロード処理(5)
    const a = document.createElement("a");
    document.body.appendChild(a);
    a.download = "test.csv";//ここすきなファイル名に
    a.href = url;
    a.click();
    a.remove();
    URL.revokeObjectURL(url);

```

# まとめ
今回はとにかくダウンロードしてみる。という仕組みを紹介しました。
工夫を加えると、「CSVファイルをダウンロードしたらフラグを立てる」というような仕組みも作れます。
コメントアウト部分も参考にされると良いかもしれません！？

是非挑戦してみてくださいね＾０＾

以上です。