CSVファイルとかよく扱ったりすることもありますよね。今回はHTML5から追加されたFilleAPIというのがあって、もともとサーバーにあるファイルを読みにいくのではなく、フォームのアップロードみたいなボタンでCSVファイルを読み込んで出力する時の処理の方法を防備録として残しておく。
目次
実際のサンプル
実際にCSVをアップロードして出力したものになります。
See the Pen javascriptでFileAPIからCSVを読み込んでみる by kiriyama (@kirikirimai) on CodePen.
FileAPIについて
そもそもFileAPIってなんぞや?という方。ネットでたくさん情報があるので、簡単に書くと HTML5 から追加された File API でWebページにユーザーのローカルにあるファイルを直接読み込めるようなりました。方法としては「input」の方法と ドラッグ&ドロップ という方法があります。
今回はinputを使った処理になります。
記述はいたって簡単でhtmlでは下記のように書きます。
HTML
//複数のファイルを処理したい場合は属性にmultipleを設定する
上記のように「type」属性に「file」を指定してあげるだけです。
また複数のファイルを扱いたい場合は属性に「multiple」を記載してあげるだけです。画像を複数枚アップなどに使用できそうです。
プログラムの流れ
HTMLはフォームタイプで「file」を選べばいいので簡単ですが、今度はjavascriptで読み込んだCSVファイルを出力する流れを書いていきます。
1:ボタンを取得してchangeイベントの設定
// 1: ボタンを取得してchangeイベントの設定 var loadBtn = document.querySelector("#loadBtn"); loadBtn.addEventListener("change", upload, false);
まずはファイルを読み込むボタンを「querySelector」でDOM要素を取得して、CSVファイルをアップした時に発生する「change」イベントを設定し、upload関数を実行します。
2:FileAPIがブラウザに対応してるかチェック
function upload(evt) { // 2:FileAPIがブラウザに対応してるかcheckFileReader関数でチェック if (!checkFileReader()) { alert("エラー:FileAPI非対応のブラウザです。"); } else { //ファイルを読み込む処理 } } function checkFileReader() { var isUse = false; if (window.File && window.FileReader && window.FileList && window.Blob) { isUse = true; } return isUse; }
FileAPIがHTML5から追加されたこともあり、念のためブラウザでチェックしておきます。 もし使えるなら「isUse]変数にtrueの値を入れてreturnで返します。」
3: 選択されたファイル情報を取得する
// 3: 選択されたファイル情報を取得 var file = event.target.files[0]; //readerオブジェクトを作成 var reader = new FileReader(); // ファイル読み取りを実行 reader.readAsText(file);
ブラウザでFileAPIが使えるなら実際に読み込み処理になります。
まず関数の引数に「event」と引数から「target.files」からアップしたファイルを取得します。filesは配列なので対象ファイルはfiles[0]に格納されています。
この時点ではアップロードされたファイルを取得しただけであってまだ読み込んでません。この後に FileReader オブジェクトの「 readAsText」メソッドを実行することでCSVファイルの読み込み処理が可能になります。
ですので、FileReaderオブジェクトの「reader」を作成し「 readAsText 」メソッドに取得したファイル(file変数)を引き渡します。
*ちなみに画像ファイルを読み込む時には「readAsDataURL」メソッドがありますのでそちらを使用します。
4:CSVファイルを読み込む処理とエラー処理をする
// 3: 選択されたファイル情報を取得 var file = event.target.files[0]; //readerオブジェクトを作成 var reader = new FileReader(); // ファイル読み取りを実行 reader.readAsText(file); // 4:読み込んだCSVファイルを取得 reader.onload = function(event) { var result = event.target.result; makeCSV(result); }; //読み込めなかった場合のエラー処理 reader.onerror = function() { alert("エラー:ファイルをロードできません。"); };
前回でFileReaderオブジェクトの「readAsText」メソッドで読み来むファイルを指定しましたが、「onload」メソッドで読む込む処理とonerrorメソッドで読み込めなかった場合の処理を書いていきます。 まずエラーの場合は上記のように「onerror」メソッド内でアラートを表示しています。
「onload」メソッドでは、FileAPIのchangeメソッドと同様にevent.targetのresultプロパティに読み込まれたCSVファイルのデータが格納されていますので一旦、result変数に入れて、makeCSVメソッドに引き渡します。
*処理が長くなりそうなのでmakeCSVメソッドにしただけです。
5:csvデータを1行ごとに配列にする
//CSVを出力する関数 function makeCSV(csvdata) { //5:csvデータを1行ごとに配列にする var tmp = csvdata.split("\n"); }
さて、CSVファイルを読み込んだら実際に出力までの処理をmakeCSV関数内で処理していきます。まずはCSVデータを1行ごとで管理するために改行コードごとに配列に入れるため。splitメソッドで「\n」としています。
*splitメソッドは指定した文字や正規表現によるで文字列を分割して配列で返すメソッドです
これにより変数tmlに1行ごとのCSVのデータが格納されています。
6:1行のデータから各項目(各列)のデータを取りだし、2次元配列にする
//csvデータをそのままtableで出力する var tabledata = $("#resulttable"); var htmldata = "
2つのfor分でCSVデータを出力用に作成し終えたら、実際にWebページに出力します。変数:htmldataにtableの閉じタグを追加してあげます。
後は、jQueryですが、変数:tabledata(#resulttableのDOM)にappendメソッドでhtmldataを追加してあげることでCSVデータがちゃんとWebページに出力されているはずです。
CSVを扱う際の注意点
今回のFileAPIだけでなくともCSVを読み込む方法は他にもありますが、読み込む際の注意点として、CSVファイルの文字コードは「UTF-8」で、「コンマ区切り」にしましょう。どちらも一般的だと思います。
また今回の処理はCSVの「名前」や「メールアドレス」などタイトルの部分もそのまま読み込んですが実際は必要ないことが多いです。その場合は一旦、行ごとで配列に追加した後に配列の最初行・・・つまりタイトルなどの行を配列のメソッドで削除するなどの処理をしたほうがいいでしょう。
またCSVを読みこんで処理をしましたが、画像やテキストファイルをアップしてしまうこともあるかと思います。その際は、FileAPIのchangeメソッド内で、ファイルを取得した際にファイル情報の入ったプロパティが用意されてるんでチェックするといいと思います。下記に記載します。
// 3: 選択されたファイル情報を取得 var file = event.target.files[0]; var type = file.type; // MIMEタイプ var size = file.size; // ファイル容量(byte) var limit = 10000; // byte, 10KB // MIMEタイプの判定 if ( type == 'image/jpeg' ) { alert('画像はアップロードできません'); return; } //readerオブジェクトを作成 var reader = new FileReader(); // ファイル読み取りを実行 reader.readAsText(file);