テーブルデータをCSVでインポートしてみよう!

フォローする

(著者:サイボウズ 北川 恭平

はじめに

kintoneの便利な機能である「テーブル」機能。
これを使えば、1つのレコード内で表形式にデータを管理できます。

このデータをCSVから、一気にインポートしよう!と、意気込むも…

テーブルに設定したフィールドに対しては、CSV/Excelファイルを使用した値の一括入力と一括更新はできません。

引用元:kintone ユーザーヘルプ

そうです。。CSVエクスポートはできるのですが、インポートはできないのです。。
だがしかし、なんとかすればなんとかなるのがkintoneのいい所。フィールド形式のドキュメントの通り、フォーマットを合わせてREST APIを実行すれば登録できます。

今回は、カスタマイズビューをつかってファイル読み込み画面を作成し、そこからCSVファイルを読み取ってテーブルデータをインポートしてみたいと思います。

準備

まずは下記のような設計でkintoneアプリを作ります。店舗の簡単な在庫管理といったイメージです。(その他の設定は適当でOKです)

フィールドタイプ フィールド名 フィールドコード
文字列(1行) Store Name sName
文字列(1行)<テーブル> Item Item
数値<テーブル> Number Number

また、テーブルにも「Table」という名前をつけます。

次に、ビューを作成していきましょう。レコードの一覧の表示形式を「カスタマイズ」にして、以下のようにHTMLを記述していきます。

記述するHTML

全体図

作成したビュー

JavaScript

 今回作成するJavaScriptでやりたいことは…

  • CSVファイルの読み込み
  • CSVファイル内のデータを、kintoneのフィールド形式に合わせてkintoneに登録

です。テーブルデータのみのインポートでもいいのですが、今回は店舗名とテーブルデータをセットで保存するものとします。

それでは早速今回作成したサンプルコードを紹介します。

今回、ソースからもわかるようにCybozu CDNでも提供されているjQueryを使いました。
ポイントとしては以下です。

  • csv2json…1行目を項目名として読み取りその他の行をデータとして処理します。処理結果はjsonデータとして返します。
  • 「post」ボタンを押したときの処理…csv2jsonの結果を元にこのアプリの登録用データを生成します。New Record Flagが存在した場合、そこから新しいレコードとして認識し、存在しな場合は前の行と同一レコードのテーブル行として処理します。データを生成したら、kintone.apiにてレコードを登録します。

テーブルデータは構造が少し複雑で、とっつきにくいですが慣れてしまえば簡単なのでどんどんJSカスタマイズで利用していきましょう( ̄ー ̄)

動作確認

実際に、下記のCSVファイルをこのアプリに読み込ませてみましょう。

TestImport.csv

「ファイルを選択」より、TestImport.csvを選択します

「POST」ボタンを押してレコードを登録します。2つのレコードで、3行のテーブルがそれぞれ登録されれば成功です。

キタキタ南国フルーツのテーブル

ノースリバー商店のテーブル

問題なく2つのレコードとしてデータが登録できました!

今回は、テーブルデータを新規でのレコード追加としてカスタマイズをおこないました。
既存のテーブルへの行追加も工夫すればできそうなので、興味がある方はチャレンジしてみてはいかがでしょうか?

このTipsは、2015年4月版で確認したものになります。

デモ環境

https://dev-demo.cybozu.com/k/81/

※デモ環境についての説明はこちら

コメント

Avatar
Eriko

いつもお世話になっております。
既存のテーブルへの行追加は現在可能でしょうか?

Avatar
cybozu Development team

Erikoさん
cybozu.com developer network事務局です。

既存のテーブルであっても行追加はできますが、いちど今のデータを取得し、
その取得したデータに行を追加して更新という手順になります。

ぜひご検討ください。

Avatar
Eriko

cybozu.com developer network事務局様、
いつも大変お世話になります。

もし差し支えなければ、その手順などを詳しくお教えいただけないでしょうか…?
色々と試したのですが、どうにも上手くいかず八方塞がりです。

Avatar
cybozu Development team

Erikoさん
返信ありがとうございます。ちょっと試してみて記事化を検討します!
進捗ありましたらまたコメントさせていただきます。

Avatar
cybozu Development team

Erikoさん
お待たせいたしました。既存のレコードのテーブル更新のTipsをリリースしました!
https://cybozudev.zendesk.com/hc/ja/articles/208399613

是非お試しください。

Avatar
鈴木佑介

ファイルの文字コードはUTF-8以外、SJISとかでは対応難しいのでしょうか?

Avatar
Satoru Suzuki

横から失礼します。

こちらの記事を参考にさせていただき、
ちょうどSJISからのテーブルインポートをやりましたので、参考までに。

以下のencoding.jsを、アプリ設定で一緒にアップして使っています。

encoding.js
https://github.com/polygonplanet/encoding.js

//ファイル選択とテキストエリアのセレクタ取得
var dialog = document.querySelector('#selfile');
var textarea = document.querySelector('textarea[name=\"txt\"]')

// ファイルタイプ定義
var types = [
    'text/csv',
    'text/comma-separated-values',
    'text/plain',
    'application/csv',
    'application/excel',
    'application/vnd.ms-excel',
    'application/vnd.msexcel',
    'text/anytext'
];

// ファイル指定時のイベント
dialog.addEventListener('change', function(evt) {
   var reader = new FileReader();
   var file = evt.target.files[0];

   if (!file) {
       // 指定ファイル存在確認
       alert('指定したファイルが存在しません。');
       return;
    } else if ((types.indexOf(file.type) < 0) || /\.csv$/.test(file.name)) {
        // CSVファイルチェック
        alert('CSVファイルではありません。');
        return;
   } else {
        // ファイル読み込み(ArrayBuffer形式)
        reader.readAsArrayBuffer(file);
// オンロード時処理
        reader.onload = function(ev) {
// 配列に変換
            var uint8Array = new Uint8Array(ev.target.result);
// 文字コードを判定
            var encoding = Encoding.detect(uint8Array);
// 判定した文字コードからunicodeへ変換
            var codeArray = Encoding.convert(uint8Array, {
                from: encoding,
                to: 'unicode'
           });
// テキストエリアに出力
           textarea.value = Encoding.codeToString(codeArray);
       };
    }
});
〜 以下略 〜
Satoru Suzukiにより編集されました
Avatar
takatomo

以下の状況で行き詰っています。ご教示頂けますでしょうか。

1.インポートするCSVを選択してもテキストエリアに表示されない。
→ご提供頂いているデモ環境では表示されるので、CSVの問題ではなさそうです。

2.テキストエリアにCSVデータの内容を貼り付けてPOSTしても、登録できない。
→こちらもデモ環境ではコピペしてPOSTすると登録できるのは確認しました。

そもそも根本的な事で間違っているような気がするのですが、原因が特定できません。

考えられる原因を教えて頂けると助かります。よろしくお願いします。

Avatar
cybozu Development team

高橋様

ご不便をおかけしております。

>今回、ソースからもわかるようにCybozu CDNでも提供されているjQueryを使いました。

とあり、jQueryを使えるようにする設定が必要です。

こちらの記事の「Cybozu CDNを利用する」を参考に、jQueryのライブラリのリンクを設定いただくことをお試しいただけますか。

よろしくお願いいたします。

Avatar
takatomo

cybozu Development team様

お世話になります。早速のご返信ありがとうございます。

頂いた「こちらの記事」のリンクがクリックしても表示されないので、

リンクをご確認頂いてもよろしいでしょうか。お手数をお掛けして申し訳ありません。

宜しくお願い致します。 

Avatar
cybozu Development team

高橋様

失礼いたしました。こちらになります。

https://cybozudev.zendesk.com/hc/ja/articles/204695384

Avatar
takatomo

cybozu Development team様

有難うございます。おかげ様で実行できました!

Avatar
OECDE

お世話になります。

このページを参考にデータインポートを試みていますが、CSVのテキストボックスへの展開まではうまくいくものの、

インポートが出来ません。

jswatchdogでエラーが無くなるまで細かな訂正もしましたし、エラー表示が出るわけでもありません。

 

ここの記事と違っているのは、

ダウンロードした既存のデータでは、"New Record Flag"とはならず、"レコードの開始行"となっています。

また、フィールド名もフィールドコードも日本語です。

これが問題なのでしょうか?

 

インポートするデータの中には、ルックアップやドロップダウン、ラジオボタンなどありますが、

フィールド形式の指定など、キチンとやっているつもりです。

自分で原因を調べる方法など、ヒントをいただければ幸いです。

よろしくお願いいたします。

Avatar
cybozu Development team

OECDE様

いつもお世話になっております。
cybozu.com developer network事務局です。

> ダウンロードした既存のデータでは、"New Record Flag"とはならず、"レコードの開始行"となっています。
書き出したデータが「レコードの開始行」となっているのは、kintoneを日本語でお使いの場合、
書き出す言語も日本語となるので、「レコードの開始行」と表示されます。
この違いについては、問題ありません。

どこに問題があるか、開発者ツールを利用してデバッグすると発見できるかと思います。
下記を参考にデバッグをしてみてください。

○動かない?そんな時はデバッグをしてみよう!入門編
https://cybozudev.zendesk.com/hc/ja/articles/207613916

よろしくお願いいたします。

Avatar
OECDE

ありがとうございます。

その場合下記のエラーについては、原因わかりました。

日付をyyyy/mm/ddで記述していたのが原因でした。

OECDEにより編集されました
Avatar
cybozu Development team
OECD様
 
ご確認ありがとうございます。cybozu developer network運営事務局です。
書き換えられたのは、以下の部分かと思います。
if (jsonArray[i]['New Record Flag']) {
 
上記を「New Record Flag」とした場合は、読み込むCSVファイルの先頭行も "New Record Flag"に、
「レコードの開始行」とした場合は、 "レコードの開始行"とする必要があります。
今一度ご確認お願いします。
Avatar
OECDE

たびたびすみません。

エラー原因は特定でき、データのインポートは出来ましたが、

一度に100件までしかインポート出来ないようです。

データが4万件超あるので、せめて数千件は一度にインポートしたいのですが、

方法は無いでしょうか?

Avatar
cybozu Development team

OECDE 様


インポートを確認できたとのこと、良かったです。
おっしゃる通り、一度に取得できるレコードは500件、一度に登録・更新および削除できるレコードは100件までになります。

それを超えるレコード操作については、リクエストの繰り返し処理を記載することになります。
コミュニティの方でも数千件のレコード取得&更新処理の質問が出ていましたので、参考になさってください。
Avatar
OECDE

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

こちらでも「100件ずつしか登録できないなら、100件ずつ切って登録を繰り返せばよい」という発想で、

ループをひとつ追加して対応しました。

 

ただ、5000件も続けてインポートすると、途中で失敗し、

実際に登録されたデータが4800件とか、100件単位でデータが抜けていることがありました。

おそらく前回の登録が完了しないうちに、次の登録処理を実行しようとしたためでは?

と推測しているのですが、いただいたURLでは、これを回避する方法があるのか、今一つわかりませんでした。

 

Avatar
cybozu Development team

OECDE 様

確かに順番に処理していってほしいので、同期処理を記述する必要がありますね。

kintone.apiは基本的には非同期通信なので、Promiseを使って同期処理を記述するのが良いと思います。
 
ちょうど同じく1万件以上のデータ読み込みをしたいという質問が出ていました。
下の方になりますが、Promiseでの記述例もございます。ご確認お願いします。
ログインしてコメントを残してください。
Powered by Zendesk