新規投稿
フォローする

CSV出力をカスタマイズ

kintoneの標準機能で出力したCSVファイルは、チェックボックスフィールドや複数選択フィールドの表示が特殊で、集計しにくい場合があります。 今回は、CSV出力を自作する例を紹介します。

サンプル

一覧のメニューの右側の空白部分に自作のCSV出力ボタンを実装します。 チェックボックスフィールドや複数選択フィールドの値は、カンマ区切りで出力します。

コード

本サンプルでは、encoding.jsを利用しています。 「encoding.min.js」を読み込み後、下記「sample.js」を読み込みます。

・sample.js

(function () {
  "use strict";
  kintone.events.on('app.record.index.show', function(event){
    var encoding = 'SJIS'; // https://github.com/polygonplanet/encoding.js/blob/master/README_ja.md
    var outputfields = [ //出力するフィールドのフィールドコード
      'レコード番号',
      '文字列',
      '数値',
      'チェックボックス'
    ];
    var getRecords = function(app, fields, tmpRecords){
      var limit = 500;
      var tmpRecords = tmpRecords || [];
      return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', {
        app: app,
        fields: fields,
        query: 'order by レコード番号 asc limit ' + limit +' offset ' + tmpRecords.length
      }).then(function(response){
        tmpRecords = tmpRecords.concat(response.records);
        return response.records.length === limit ? getRecords(app, fields, tmpRecords) : tmpRecords;
      });
    };
    var csvButton = document.createElement('a');
    csvButton.innerText = 'CSVダウンロード';
    kintone.app.getHeaderMenuSpaceElement().appendChild(csvButton);
    csvButton.addEventListener('click', function(){
      getRecords(kintone.app.getId(), outputfields).then(function(records){
        var a = document.createElement('a');
        a.href = URL.createObjectURL(new Blob([
          new Uint8Array(Encoding.convert(Encoding.stringToCode(outputfields.map(function(outputfield){
            return '"' + outputfield + '"';
          }).join(',') + "\r\n" +
          records.map(function(record){
            return outputfields.map(function(outputfield){
              var value = record[outputfield].value;
              return '"' + (Array.isArray(value) ? value.join(',') : value) + '"';
            }).join(',');
          }).join("\r\n")), encoding))
        ], {type: 'text/csv'}));
        a.download = 'data.csv';
        document.body.appendChild(a);
        a.click();
        a.parentNode.removeChild(a);
      });
    });
  });
})();
4

13件のコメント

Avatar
SHOH

江田様

こちらのスクリプトでレコード一括取得をしていると思いますが、これは何件まで取得しCSV出力できるのでしょうか。

 

0
Avatar
江田篤史

SHOHさん

お世話になっております.
返信が遅くなり申し訳ございません.

APIのoffsetの上限があるため,10000レコードが上限となります.
https://developer.cybozu.io/hc/ja/articles/202331474#step2

10000レコードを超える場合は,カーソルAPIを利用したコードに変更するとよいかと思います.
https://developer.cybozu.io/hc/ja/articles/360029152012

0
Avatar
SHOH

江田様

10000レコード取得できれば問題ないのですが、それ以上取得する要件が出てきましたら、カーソルAPIを利用したコードに変更してみたいと思います。

ご返答ありがとうございました。

1
Avatar
ちゃいな嬢

江田さま

これを参考に作成してみましたが

 Unable to get property 'value' of undefined or null reference」が表示されます。

そもそも「encoding.min.js」の取得方法を理解できていないのかもしれませんが

サイトに飛んで、コードをコピーして、この名前でテキストエディタで出力し、

読み込ませましたが間違っていますか?

0
Avatar
江田篤史

ちゃいな嬢さん

お世話になっております。

「encoding.min.js」が読み込めていない場合は、Encodingが未定義という旨のエラーが出そうなので、読み込みはできているかと思います。

エラーが出ているのはsample.jsの35行目でしょうか?
その場合は、フィールドコードが間違っている可能性が高いです。
今一度フィールドコードをご確認いただけますか。

0
Avatar
ちゃいな嬢

江田さま

間違っていました!!文字列という項目がフォームの基準の名前のままでした。

うまく行きました!素晴らしいです。

いくつかコードで質問です

①「var getRecords = function(app」の意味はなんでしょうか?

function以降が処理でgetRecordsに結果を渡してる?

これと「getRecords(kintone.app.getId()」は同じ?

onclick でgetRecordsを処理??

江田さまのコーディングが高レベルで初心者が理解するのが大変です・・

②「var tmpRecords = tmpRecords || []; 」の意味は?|| []  ??

 

 

0
Avatar
江田篤史

ちゃいな嬢さん

お世話になっております。


> 「var getRecords = function(app」の意味はなんでしょうか?
getRecordsという名前の関数を作成しています。
https://developer.cybozu.io/hc/ja/articles/115005338743
上記リンクと若干書き方が違いますが、ほぼ同義です。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/function
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/function

> function以降が処理でgetRecordsに結果を渡してる?
function以降が処理で、getRecordという名前をつけています。
プログラムぽく言えば、function式で関数を作成して、getRecordという変数に代入しています。
JavaScriptでは関数もオブジェクトなので、変数に代入することができます。

> これと「getRecords(kintone.app.getId()」は同じ?
getRecords(kintone.app.getId())は、上記で作成したgetRecordsという関数を実行するという記述です。

>onclick でgetRecordsを処理??
仰る通りです。

 

②「var tmpRecords = tmpRecords || []; 」の意味は?|| []  ??
やりたかったこととしては、getRecords()の実行時に、第三引数のtmpRecordsが指定されなかった場合に[]をデフォルト値として設定するという処理です。
ES6が使用できる環境であれば、デフォルト引数という機能を使ってもっと簡単に記述できます。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Default_parameters

A = B || C というのは条件分岐しながら代入を行うときに便利なショートハンドです。
下記と同義になります。

if (B) {
A = B;
} else {
A = C
}
0
Avatar
ちゃいな嬢

江田さま

大変勉強になりました!これをスラスラは書けませんが少し理解できましたし、

関数にしても色んな書き方ができるのだなと思いました。

あと少し

}).then(function(response){ のthen は?

return kintone.api( の結果が真の時の処理ってことですか?

return a なら aという変数の値を返すところをその中に処理を入れているのですよね?

returnが連続するのでどこからどこまでが!って理解が難しい・・

0
Avatar
江田篤史

ちゃいな嬢さん

> }).then(function(response){ のthen は? return kintone.api( の結果が真の時の処理ってことですか?
はい、仰る通りです。
kintone.api()の第4引数以降を省略すると、kintone.api()はPromiseオブジェクトを返り値として返します。
https://developer.cybozu.io/hc/ja/articles/202166310#step1
https://developer.cybozu.io/hc/ja/articles/204564604

.then()メソッドはPromiseオブジェクトのメソッドです。
kintoneに限った話ではなく、JavaScriptの話なのでGoogle検索で「JavaScript Promise」などと調べるとわかりやすい解説が出てきます。

> return a なら aという変数の値を返すところをその中に処理を入れているのですよね?
はい、仰る通りです。
PromiseStateがfulfilledになったとき(非同期処理が終了したとき)にaとなるような値を返します。

> returnが連続するのでどこからどこまでが!って理解が難しい・・
Promiseをそのまま使うのは可読性が低いと感じる場合は、async/awaitを使うと良いかと思います。
https://developer.cybozu.io/hc/ja/articles/900001244323

0
Avatar
ちゃいな嬢

江田さま

再度質問です。 csvに出力しましたら、更新者・作成者がうまく出力されません。

これは無理ですか?

 

ちゃいな嬢により編集されました
0
Avatar
江田篤史

ちゃいな嬢さん

返信遅くなりました。

更新者・作成者は、valueが文字列ではなく、nameとcodeプロパティを持ったオブジェクトとなっています。
https://developer.cybozu.io/hc/ja/articles/202166330#creator

フィールドタイプが'CREATOR'または'MODIFIER'のフィールドについては、value.nameを出力するようにコードを変更すると良いかと思います。

0
Avatar
ちゃいな嬢

江田様

無事に出来ました、ありがとうございます。

少しずつ理解しているのですが、return,async,await が理解できていません。

何かいいものありませんか?

このCSV出力コードを利用して、ベースファイルを読込み、レコードの項目にあるアプリIDを利用して

そのアプリをCSV出力としたいのですが、なかなかうまくいかないです。

基本的に理解できていないのかもしれません

0
Avatar
ちゃいな嬢

江田様、ご無沙汰しております。頑張ってコードを組み立てましたが、

この形式でチェックボックスをCSV出力すると、そのファイルは読込みできなくないですか?

どのようにしたら解決するのでしょうか・・・

0
サインインしてコメントを残してください。