RACCOON TECH BLOG

株式会社ラクーンホールディングス 技術戦略部より、
tipsやノウハウなど技術的な話題を
発信いたします。

node.jsでエクセルファイルを編集する方法

技術部のアベです。
一般的にエクセルの内容をプログラム的に変化させるにはVBA / マクロを使用すると思いますが、モジュールを活用してjavascriptでエクセルの編集が出来るのは簡単だし便利だなぁと思ったので、今回はnode.jsのpackageのxlsx-populateを使用してエクセルを編集してみました。

この記事ではnode.jsを使用する為、実行環境はnode.js公式からダウンロード・インストールを行ってください。

xlsx-populateを使ってみる

新規エクセルファイルの作成

新規エクセルファイルを作成する

新規エクセルファイルを作成してみましょう。

const XlsxPopulate = require("xlsx-populate");
const outputPathName = "./new.xlsx";

XlsxPopulate.fromBlankAsync().then(workbook => {
    return workbook.toFileAsync(outputPathName);
})

node.jsを実行すると作業ディレクトリに[new.xlsx]ファイルが作成されます。

node index.js

新規エクセルファイルにデータを入れて作成する

あらかじめ決まったデータを入れた状態で、新規エクセルファイルの作成も出来ます。

const XlsxPopulate = require("xlsx-populate");
const outputPathName = "./new.xlsx";

XlsxPopulate.fromBlankAsync().then(workbook => {
    // 見出し
    workbook.sheet("Sheet1").cell("A1").value("No");
    workbook.sheet("Sheet1").cell("B1").value("姓");
    workbook.sheet("Sheet1").cell("C1").value("名");
    workbook.sheet("Sheet1").cell("D1").value("年齢");

    // 内容
    workbook.sheet("Sheet1").cell("A2").value(1);
    workbook.sheet("Sheet1").cell("B2").value("スズキ");
    workbook.sheet("Sheet1").cell("C2").value("イチロウ");
    workbook.sheet("Sheet1").cell("D2").value(25);

    workbook.sheet("Sheet1").cell("A3").value(2);
    workbook.sheet("Sheet1").cell("B3").value("タナカ");
    workbook.sheet("Sheet1").cell("C3").value("ジロウ");
    workbook.sheet("Sheet1").cell("D3").value(32);

    workbook.sheet("Sheet1").cell("A4").value(3);
    workbook.sheet("Sheet1").cell("B4").value("タカハシ");
    workbook.sheet("Sheet1").cell("C4").value("サブロウ");
    workbook.sheet("Sheet1").cell("D4").value(30);

    // 別の書き方でもできます。
    /*
    let rows = [
        ["No", "姓", "名", "年齢"],
        [1, "スズキ", "イチロウ", 25],
        [2, "タナカ", "ジロウ", 32],
        [3, "タカハシ", "サブロウ", 30]
    ];
    workbook.sheet("Sheet1").cell("A1").value(rows);
    */
    return workbook.toFileAsync(outputPathName);
})

[new.xlsx]ファイルの中にデータがあります。

既存のファイルの編集をする

先ほどの[new.xlsx]を使って編集します。

ブックを開いて、Sheet1のデータを取得する

Sheet1のデータを取得してコマンドプロンプトに内容を出力してみましょう。

const XlsxPopulate = require("xlsx-populate");
const outputPathName = "./new.xlsx";

XlsxPopulate.fromFileAsync(outputPathName).then(workbook => {
    console.log(workbook.sheet("Sheet1").usedRange().value());
});
C:\Users\xxxx\node_excel>node index.js
[
  [ 'No', '姓', '名', '年齢' ],
  [ 1, 'スズキ', 'イチロウ', 25 ],
  [ 2, 'タナカ', 'ジロウ', 32 ],
  [ 3, 'タカハシ', 'サブロウ', 30 ]
]

新しいシートの作成する

resultというSheetを作成してみましょう。

const XlsxPopulate = require("xlsx-populate");
const outputPathName = "./new.xlsx";

XlsxPopulate.fromFileAsync(outputPathName).then(workbook => {
    // resultというSheetを作成
    let newSheetName = "result";
    workbook.addSheet(newSheetName);

    workbook.toFileAsync(outputPathName).then(result => {
        console.log("success");
    });
});

[new.xlsx]にresultシートが出来ました。

既存Sheetの削除をする

作成したresultシートを削除してみましょう。

const XlsxPopulate = require("xlsx-populate");
const outputPathName = "./new.xlsx";

XlsxPopulate.fromFileAsync(outputPathName).then(workbook => {
    // resultというSheetを削除
    let newSheetName = "result";
    workbook.deleteSheet(newSheetName);

    workbook.toFileAsync(outputPathName).then(result => {
        console.log("success");
    });
});

エラーを回避する

既存Sheetを同名でaddSheetするとエラーで怒られます。

Error: Sheet with name "result" already exists.

このように回避しました。

const XlsxPopulate = require("xlsx-populate");
const outputPathName = "./new.xlsx";

XlsxPopulate.fromFileAsync(outputPathName).then(workbook => {
    // resultというSheetを作成
    // resultシートが既にある場合エラーとなるので、存在した場合は削除し、新しく作成する
    let newSheetName = "result";
    if(workbook.sheet(newSheetName)) {
        workbook.deleteSheet(newSheetName);
        workbook.addSheet(newSheetName);
    } else {
        workbook.addSheet(newSheetName);
    }

    workbook.toFileAsync(outputPathName).then(result => {
        console.log("success");
    });
});

処理を組み合わせて、新しいデータを作る

Sheet1のデータを元に年齢を2倍の数値に計算し、BセルCセルの姓・名を結合内容をDセルに追記しセルのスタイルなどを付けてresultのシートを新規で加えています。

const XlsxPopulate = require("xlsx-populate");
const outputPathName = "./new.xlsx";

XlsxPopulate.fromFileAsync(outputPathName).then(workbook => {
    // resultというSheetを作成
    // resultシートが既にある場合エラーとなるので、存在した場合は削除し、新しく作成する
    let newSheetName = "result";
    if(workbook.sheet(newSheetName)) {
        workbook.deleteSheet(newSheetName);
        workbook.addSheet(newSheetName);
    } else {
        workbook.addSheet(newSheetName);
    }

    // sheet1のすべての内容を取得
    let rows = workbook.sheet("Sheet1").usedRange().value();

    // 新しくSheet2(result)に記述する配列
    let newRows = [];

    rows.forEach((row, index) => {
        if(index == 0) {
            // 見出しに姓名を追加
            newRows.push([
                row[0],
                row[1],
                row[2],
                "姓名",
                row[3]
            ]);
            return;
        }

        // 年齢を2倍にして、姓-名を連結した内容を加える
        let age = row[3] * 2;
        newRows.push([
            row[0],
            row[1],
            row[2],
            row[1] + row[2],
            age
        ]);

        // 年齢が60以上の場合はセルを目立たせる
        if(age >= 60) {
            workbook.sheet(newSheetName).cell("E" + (index + 1)).style("fill","ff0000");
        }
    });

    // Sheet2(result)に新しく作成したデータを書き込む
    workbook.sheet(newSheetName).cell("A1").value(newRows);

    workbook.toFileAsync(outputPathName).then(result => {
        console.log("success");
    });
});


[new.xlsx]のresultシートに指定した内容が入力されていました。

javascriptでエクセルを読み書き出来る事が画期的!

実際に業務で使ってみて便利だったので、
簡単な内容ですが紹介させて頂きました。
xlsx-populateには今回は紹介できなかった機能があるので是非使ってみてください。

おまけ(exeにして他の人に使ってもらう)

nexeで作成をしたエクセル編集機能をパッケージングして他の人が利用しやすくする方法です。

npm install nexe
nexe index.js

node_excel.exe ファイルが出来たと思います。
node.jsの実行環境が無くても使えるのでプログラマーではない人に配布するには良いと思いました!

関連記事

運営会社:株式会社ラクーンホールディングス(c)2000 RACCOON HOLDINGS, Inc