1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[備忘録] Node.jsでExcelを読み込みたい

Posted at

はじめに

自動化ツールの一環で、Node.jsを使ってExcelを読み込みたかった
ちょこっとSheetJSをさわったのでメモ

おことわり

  • この記事ではエクセルの内容を読むだけで、セルに書き込んだりブックを新しく作ったりしません
  • せっかくなのでTypeScriptで書いてみました
    • ts-node使ったり、いちいちjsにトランスパイルしたりしないと実行できないので、たぶんcommonJSか.mjs拡張子で作ってnodeで起動するのがツール利用観点では楽かも

環境

macOS 12.6
node 18.12.1
SheetJS(xlsx) 0.19.1
typescript 4.9.4
@types/node 18.11.18
ts-node 10.9.1

npm i -D typescript ts-node @types/node

使用ライブラリ

SheetJS
npmでのパッケージ名はxlsx

NodeJSでのInstallationページに下記のように記載がある通り、npmで配布されているのはバージョン0.18.5で止まっているそうな

Older releases are technically available on the public npm registry as xlsx, but the registry is out of date. The latest version on that registry is 0.18.5
This is a known registry bug

公式曰く、npmからinstallしたパッケージはuninstallして、cdnで配布されている新しいのを入れ直してくれだとよ

Install

npm i https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz
yarn add https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz

データを読んでみるExcelを適当に作る

image.png

ファイルの読み込み

index.ts
import os from 'node:os';
import path from 'node:path';
import * as XLSX from 'xlsx';

const filepath = path.join(os.homedir(), '/Desktop/prices.xlsx');
const wb = XLSX.readFile(filepath, {
  type: 'array', // Input data encoding bufferやbase64なども選択可能
  sheets: ['Sheet1'], // 読み込むシート
  cellHTML: false, // rich textをHTMLとして読み込むか フロントエンドで表示したい時は使えそう
});
const ws = wb.Sheets['Sheet1'];

もしmjsで作ってるなら

公式Docsに言及がある通り、native node modulesをloadできないのでsetしてあげる必要がある
Docsはimport * as XLSX from 'xlsx/xlsx.mjs';って書いてあるけど、/xlsx.mjsつけるとうまく動かなかった

index.mjs
import * as XLSX from 'xlsx'
import fs from 'node:fs'
/* load 'fs' for readFile and writeFile support
See https://docs.sheetjs.com/docs/getting-started/installation/nodejs#esm-import */
XLSX.set_fs(fs)

wsの中身は...

{
  '!ref': 'B2:E8',
  B2: {
    t: 's',
    v: 'products',
    r: '<t>products</t><phoneticPr fontId="1"/>',
    w: 'products'
  },
/////// 略 ///////
  B8: {
    t: 's',
    v: 'chair',
    r: '<t>chair</t><phoneticPr fontId="1"/>',
    w: 'chair'
  },
  C8: { t: 'n', v: 6, w: '6' },
  D8: { t: 'n', v: 3840, w: '3840' },
  E8: { t: 'n', v: 23040, f: 'C8*D8', w: '23040' }
}
  • 空白セルは勝手に無視してくれる
  • tとかwとか
key description
t The Excel data type for a cell.
b Boolean, n Number, e error, s String, d Date, z Stub
v The raw value of the cell. Can be omitted if a formula is specified
f Cell formula (if applicable)
cellFormulaoptionで設定可能
F Range of enclosing array if formula is array formula (if applicable)
w Formatted text (if applicable)
cellTextoptionで設定可能
h HTML rendering of the rich text (if applicable)
cellHTMLoptionで設定可能
z Number format string associated with the cell
cellNFoptionで設定可能
s style/theme
cellStylesoptionで設定可能
c Comments associated with the cell
l Cell hyperlink object

Excel上のデータを読み込んで何かする

合計金額でも出してみましょうか

index.ts
const sums: number[] = [];
for (const [key, value] of Object.entries(ws)) {
  if (key.match(/E\d+/) && typeof value.v === 'number') sums.push(value.v);
}

const subtotal = sums.reduce((p, c) => p + c);
console.log({ subtotal }); // -> 44920

さいごに

この辺を参照すれば書き込みも問題なくできそう

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?