なんだかGoodVibes

日々の勉強メモです。

【Node】エクセルを読み込む(ループで回して読み込み)

こんにちは。
今回もエクセル関連です。
今回はループを使った読み込みを行ってみます。

読み込むエクセルはこんな感じ。
いつもと変わらない内容です。
f:id:nandakagoodvibes:20191215221537p:plain


今回もxlsxモジュールを使っていきます。
では、さっそくサンプルです。

var xlsx = require('xlsx');

var book = xlsx.readFile('sample.xlsx');
var ws = book.Sheets['Sheet1'];

var range = ws['!ref'];

// セルの範囲を数値に変換する
var decodeRange = xlsx.utils.decode_range(range);

// ループで回して読み込み
for (var colIdx = decodeRange.s.c; colIdx <= decodeRange.e.c; colIdx++) {
    for (var rowIdx = decodeRange.s.r; rowIdx <= decodeRange.e.r; rowIdx++) {

        // セルのアドレスを取得する
        var address = xlsx.utils.encode_cell({ r: rowIdx, c:colIdx });
        var cell = ws[address];

        if (typeof cell !== "undefined" && typeof cell.v !== "undefined") {
            console.log('[' + address + '](' + colIdx + ',' + rowIdx + ')');
            console.log('\t→' + cell.v);
        }
    }
}


結果は以下です。

[A1](0,0)
        →A1です。
[A2](0,1)
        →A2です。
[A3](0,2)
        →A3です。
[B1](1,0)
        →B1です。
[B2](1,1)
        →B2です。


では、細かく見ていきましょう!


モジュールの読み込みと対象のセット

var xlsx = require('xlsx');

var book = xlsx.readFile('sample.xlsx');
var ws = book.Sheets['Sheet1'];

var range = ws['!ref'];

ここは前回までに紹介した内容です。
以下の記事を参考にしてください。

nandakagoodvibes.hatenablog.com


セルの範囲を数値に変換する

var decodeRange = xlsx.utils.decode_range(range);

ループで回して読み込みを行うためにセルの範囲を数値に変換しています。
decodeRangeを出力すると以下のようになります。

{ s: { c: 0, r: 0 }, e: { c: 1, r: 2 } }

開始:{ s: { c: 0, r: 0 }、終了:e: { c: 1, r: 2 }
と変換されています。
ちなみに、変換元のrangeはA1:B3となっています。
次の処理から、変換した範囲を使って処理します。


ループで回して読み込み

まずは、ループの部分を見てみましょう 。

for (var colIdx = decodeRange.s.c; colIdx <= decodeRange.e.c; colIdx++) {
    for (var rowIdx = decodeRange.s.r; rowIdx <= decodeRange.e.r; rowIdx++) {
        .....
    }
}

サンプルは、最初に列のループ、次に行のループといった処理になっています。
最初のループ:decodeRange.s.c(列の開始)〜decodeRange.e.c(列の終了)
次のループは:decodeRange.s.r(行の開始)〜decodeRange.e.r(行の終了)
といった内容です。


次に、読み込みの処理です。
まずは、列、行の番号を指定して、セルを取得しています。
addressにはA1形式に変換されたものが代入されます。

var address = xlsx.utils.encode_cell({ r: rowIdx, c:colIdx });
var cell = ws[address];


ifで行っているのは、セルの値が取得できたかの判定です。
値が入っていないセルが読み込みの範囲にあるときに
以下の判定をせずにcell.vとかするとエラーになってしまいます。
なので、型がundefinedでないかで判定します。

if (typeof cell !== "undefined" && typeof cell.v !== "undefined") {
    console.log('[' + address + '](' + colIdx + ',' + rowIdx + ')');
    console.log('\t→' + cell.v);
}

これでエクセルをループで回して読み込みができました。