SheetJS(xlsx.js)とExcelJS

JS

SheetJSとExcelJSを両方使って感じたことは、

両方ともExcelのヘッダーとボディの情報を入れる手順はほぼ同じで、

ExcelJSは、セルごとに細かい設定(折り返し表示や幅や高さ、中心寄せ)ができるのが特徴だと思います。

SheetJS(xlsx.js)

SheetJSはアルファベット1文字が多く出て来ます。

そこで、アルファベットの意味をメモしておこうと思います。

ws(ワークシート)

t: セルのデータ型を表す

  • 's': 文字列(String)
  • 'n': 数値(Number)
  • 'b': 論理値(Boolean)
  • 'e': エラー(Error)
  • 'd': 日付(Date)

decode_range()

decode_range()とは開始セルと終了セルの情報をオブジェクト形式で返します。

const range = XLSX.utils.decode_range("A1:C3");

console.log(range);
/*
{
  s: { c: 0, r: 0 }, // 開始セル (A1): 列 A (c = 0), 行 1 (r = 0)
  e: { c: 2, r: 2 }  // 終了セル (C3): 列 C (c = 2), 行 3 (r = 2)
}
*/

引数"A1:C3" は A1 から C3 までの範囲を指定しています。

s: 開始セル (start)

  • c: 開始列を数値で表現します
  • r: 開始行を数値で表現します

e: 終了セル (end)

  • c: 終了列
  • r: 終了行

このようにSheetJSはExcelの列と行のアルファベットを使用しています。

encode_cell

encode_cellとはSheetJSの関数で、

行と列の番号からセルの場所(アドレス)を示します。

  • c: 列番号(0から始まる)
  • r: 行番号(0から始まる)
XLSX.utils.encode_cell({ c: 0, r: 0 });  // "A1"
XLSX.utils.encode_cell({ c: 1, r: 0 });  // "B1"
XLSX.utils.encode_cell({ c: 2, r: 3 });  // "C4"

使い方例

const XLSX = require('xlsx'); // XLSX ライブラリのインポート

// HTML テーブルからデータを取得する関数
function extractTableData() {
    const headerRows = [
        ['列1', '列2', '列3', '列4-1', '列5-1'], // 1段目のヘッダー
        ['列4-2', '列5-2']                      // 2段目のヘッダー
    ];

    const data = [
        ['データ1', 'データ2', 'データ3', 'データ4-1', 'データ5-1'],
        ['データ1', 'データ2', 'データ3', 'データ4-2', 'データ5-2']
    ];

    return { headerRows, data };
}

// Excelファイルにエクスポートする関数
function exportToExcel() {
    const { headerRows, data } = extractTableData();

    // ヘッダーとデータを結合
    const fullData = headerRows.concat(data);

    // シートにデータを変換
    const ws = XLSX.utils.aoa_to_sheet(fullData);

    // スタイル設定
    const range = XLSX.utils.decode_range(ws['!ref']);
    for (let R = range.s.r; R <= range.e.r; R++) {
        for (let C = range.s.c; C <= range.e.c; C++) {
            const cellRef = XLSX.utils.encode_cell({ r: R, c: C });
            const cell = ws[cellRef];

            if (cell) {
                // セルスタイルが未定義なら初期化
                if (!cell.s) cell.s = {};

                // テキスト折り返し設定
                if (!cell.s.alignment) cell.s.alignment = {};
                cell.s.alignment.wrapText = true;
            }
        }
    }

    // 新しいワークブックを作成し、シートを追加
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

    // Excelファイルを出力
    XLSX.writeFile(wb, "table_export.xlsx");
}

// Excelファイルをエクスポート
exportToExcel();

ExcelJS

const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('DataSheet');  // ワークシート名を 'DataSheet' に設定

// ヘッダー行を追加(例)
worksheet.addRow(['Header 1', 'Header 2', 'Header 3']);

// データ行の例
const data = [
  ['Data 1-1', 'Data 1-2', 'Data 1-3'],
  ['Data 2-1', 'Data 2-2', 'Data 2-3'],
  ['Data 3-1', 'Data 3-2', 'Data 3-3']
];

// 各行をシートに追加
data.forEach(row => {
  worksheet.addRow(row);
});

//あるいはテーブルのデータを反映させる場合

$('#abc tr').each(function() {
    // 各行のセルデータを取得
    const rowData = [];
    $(this).find('td').each(function() {
        rowData.push($(this).text());
    });
    
    // Excelシートに追加
    worksheet.addRow(rowData);
});

// ダウンロードリンクを作成してファイル名を設定
workbook.xlsx.writeBuffer().then(function(buffer) {
    const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = 'MyExcelFile.xlsx';  // ここでダウンロードするファイル名を設定
    link.click();
});

動的な列を指定する

// ヘッダー行から動的に列インデックスを特定
const header1 = 'Header 2'; // 改行設定を適用したいヘッダー名
const header2 = 'Header 4'; // 改行設定を適用したいヘッダー名

const getColumnIndexByHeader = (headerName) => {
  let columnIndex = -1;
  worksheet.getRow(1).eachCell({ includeEmpty: true }, (cell, colNumber) => {
    if (cell.value === headerName) {
      columnIndex = colNumber;
    }
  });
  return columnIndex;
};

const columnIndex1 = getColumnIndexByHeader(header1);
const columnIndex2 = getColumnIndexByHeader(header2);

// 指定した列に改行設定を適用
if (columnIndex1 !== -1) {
  worksheet.getColumn(columnIndex1).eachCell({ includeEmpty: true }, (cell) => {
    cell.alignment = { wrapText: true };
  });
}

if (columnIndex2 !== -1) {
  worksheet.getColumn(columnIndex2).eachCell({ includeEmpty: true }, (cell) => {
    cell.alignment = { wrapText: true };
  });
}

行の高さを指定

行の高さを設定する方法

worksheet.getRow(index).height = 30; 

列の幅を設定する方法

worksheet.getColumn(columnIndex).width = 20;