はじめに
初めまして、初投稿です。読みづらい箇所もあると思いますが、よろしくお願いします。
エクセルなどで作成した表データをそのままテーブルにできないかと色々模索した際に作成したコードです。
「エクセルをそのままテーブルにしたい!」という私みたいなモノグサさんのお役に立てれば幸いです。
環境
- html
- Javascript
- Google Chrome
- CSVファイル(Excel、Googleスプレッドシートなどで作成)
※条件:セル内改行なし ・ コンマ , は使用しない
作業手順
以下の手順でコードを作成していきます。
-
- 【HTML】CSVファイルの読み込み
-
- 【HTML】テーブルを書き出す場所を作成する
-
- 【Javascript】form要素(CSVファイル)の取得する
-
- 【Javascript】CSVの各データを配列として読み込む-1
-
- 【Javascript】CSVの各データを配列として読み込む-2
-
- 【Javascript】テーブルに書き出す処理
-
- 【Javascript】作成したテーブルの tr にidを付与する
1 【HTML】FileAPIを使ってCSVファイルを読み込む
まず最初に、FileAPIを使ってCSVファイルを読み込みます。
accept="text/csv" とすることで、CSVファイルだけが選択できるようにします。
<input name="userFile" type="file" accept="text/csv">
2 【HTML】テーブルを書き出す場所を作成する
テーブルを書き出したい場所に、次のコードを入れます。
div id="table" に、テーブルが出力されます。
<div class="container">
<div id="table" class="userTableBox">
</div>
3 【Javascript】form要素(CSVファイルの中身)の取得する
form要素を取得し、FileReaderクラスでFile オブジェクト(CSV)の中身を読み込みます。
var form = document.forms.userform;
form.userFile.addEventListener('change', function(e) {
var result = e.target.files[0];
var reader = new FileReader();
reader.readAsText( result );
4 【Javascript】CSVの各データを配列として読み込む-1
3 で読み込んだCSVを配列化して取得します。
さらに、テーブルにした時の、1列の要素数を取得しておきます。
//1行ごとに配列化します。
reader.addEventListener('load', function() {
var arr = reader.result.split('\n');
//全ての配列を個別に取得します。
for(i = 0; i < arr.length; i++){
var arrayElements = new Array(arr[i]);
}
//一番上にくる配列(<th>タグに入る)を取得
var first = arr[0];
var userData = reader.result.split(/,|;|\n/);
//1列の要素数を取得
var rowCnt = parseInt(userData.length) / parseInt(arr.length);
5 【Javascript】CSVの各データを配列として読み込む-2
配列データを中身の要素数(エクセルの列数)で均等に分割します。
Array.prototype.divide = function(n){
var userArray = this;
var indx = 0;
var results = [];
var length = userArray.length;
while (indx + n < length){
var result = userArray.slice(indx,indx+n);
results.push(result);
indx = indx + n
}
var rest = userArray.slice(indx,length+1);
results.push(rest);
return results;
}
userArray = reader.result.split(/,|;|\n/);
dividedArrayData = userArray.divide(rowCnt);
6 【Javascript】テーブルに書き出す処理
ここでついに、取り込んだCSVファイルのデータをテーブルに書き出します。この時点では、ヘッダー行のみ背景色と文字色を変更しておきます。さらに今後、CSSで見た目を修正する時のために各セルにIdとclassを追加する準備をします。
function makeTable(data, tableId){
var rows=[];
var table = document.createElement("table");
//完成したテーブルに <table id="userCsvTable">というidを付与します。
table.id = "userCsvTable"
//(縦方向)の要素数を取得・縦方向の繰り返し処理回数を指定
for(i = 0; i < data.length; i++){
rows.push(table.insertRow(-1));
if (i === arr.length){
break
}
//(横方向)の要素数を取得・横方向の繰り返し処理回数を指定 これは要素数分、列を作成する処理
for(j = 0; j < data[0].length; j++){
cell=rows[i].insertCell(-1);
// 追加した行にセルを追加してテキストを書き込む
cell.appendChild(document.createTextNode(data[i][j]));
if(i==0){
// ヘッダー行(エクセルの、1行目):<th>の部分・背景色と文字色の指定
cell.style.backgroundColor = "gray";
cell.style.color = "white";
//ヘッダー行:各セルのidにインデックス番号を入れる
//(ここでは0ゼロしか入らない・次のステップで正しい連番に置き換えます。)
cell.id = i
//各セルのclassを追加。ここではヘッダー行は index としています。
cell.classList.add("index_"+i,"cellContents","header-cell");
}
else{
//ヘッダー行以外の内容行(エクセルの、2行目以降)
cell.id = i
//各セルのclassを追加。2行目以降(ヘッダー行以外)は contents としています。
cell.classList.add("contents_"+i,"cellContents","body-cell")
}
}
}
// 指定したdiv要素にテーブルを追加する
document.getElementById(tableId).appendChild(table);
}
// 表のデータ
var data = dividedArrayData
// 表を作成する
makeTable(data,"table");
7 【Javascript】作成したテーブルの<tr>にidを付与する
CSSで見た目を修正するために各セルに正式なidを付与して完成です。
//作成したテーブルの tr にidを付与する
var trId = "userElementID_"
var tmp = document.getElementsByTagName("tr") ;
for(var i=0;i<=arr.length-1;i++){
//id追加
tmp[i].setAttribute("id",trId+i);
}
//作成したテーブルの各セルにidを付与する ※⑥で先にセルにidを付与しないと動作しない
var idName = "cell_"
var cellId = document.getElementsByClassName("cellContents") ;
for(var i=0;i<=tmp.length-1;i++){
//idを追加
cellId[i].setAttribute("id",idName+i);
}
});
});
最後に
ここまでお付き合いいただきありがとうございます。
もっとシンプルな書き方とかあると思いますのでアドバイスなどいただけると嬉しいです。
動作サンプルはこちらからご確認いただけます。