Excelでデータのエクスポートしたいなと思い、いろいろ調べてみたら、
SheetJS(xlsx)を使うとできるらしいので、試してみたときの備忘録。
追記: 2020/10/04
SheetJS(xlsx)の無料版だと、スタイルのコピーや設定ができないので、
xlsx-populateの方が良さそう。
注意
- xlsなどに対応するため、スタイルの互換性がない
- 行/列の幅などの情報はコピーできるが、セルのスタイルは不可
- セルのスタイルをコピーする場合は、自前で解析するか、有料版を利用する
- ただ、sheetjs-styleを利用するとできる
インストール
$ npm install xlsx
ローカルのファイルを読み込む
Node.jsでローカルファイルを読む場合はこんな感じ。
import * as XLSX from "xlsx"; const workbook = XLSX.readFile('test.xlsx');
Web上のファイルを読み込む
Web上で読み込む場合はこんな感じ。
import * as XLSX from "xlsx"; import $axios from "axios" function async readFile(): XLSX.WorkBook { // arraybufferでファイルを取得 const res = await $axios.get("/test.xlsx", { responseType: "arraybuffer" }); // Uint8Arrayに詰め替え const data = new Uint8Array(res.data); // xlsxファイルの読み込み const workbook = XLSX.read(data, { type: "array", cellStyles: true }); return workbook; }
ポイントは、以下の2つ
- axiosのresponseTypeを
arraybuffer
にする XLSX.read()
でcellStyles: true
も設定する
cellStyles: true
を設定すると、セルの幅など一部のスタイルをコピーできる
セルに値を設定する
workbookを取得してから、セルに値を設定するまで流れはこんな感じ。
// セルに値を設定する function async writeCell(workbook: XLSX.WorkBook) { // ファイルを読み込んでworkbookを取得 const workbook = await this.readFile(); // index指定でシート名を取得 const sheetName = workbook.SheetNames[0]; // シート名からworksheetを取得 const worksheet = workbook.Sheets[sheetName]; // 取得したworksheetの"A1"に値を設定 worksheet["A1"] = { v: "AAA", t: "s", w: "AAA" }; }
ポイントは、
- worksheetはシート名を指定しないといけない
- cellの形式が特殊で、v/t/wのフィールドが存在する
cellの形式が特にわかりにくく、
worksheet["A1"].v = "AAA";
だとうまくいかないことがある。
- v ... 生のデータ
- w ... 表示されるデータ
- t ... データの型: sは文字列
Ref. SheetJS|Cell Object
tのデータ型はこんな感じ。
Type | Description |
---|---|
b |
Boolean: value interpreted as JS boolean |
e |
Error: value is a numeric code and w property stores common name ** |
n |
Number: value is a JS number ** |
d |
Date: value is a JS Date object or string to be parsed as Date ** |
s |
Text: value interpreted as JS string and written as text ** |
z |
Stub: blank stub cell that is ignored by data processing utilities ** |
Ref. SheetJS|Data Types
空のセルに書き込もうとすると、
- tがz(black cell)になっていたり、
- w(表示データ)が空だったりして、
うまくいかなかった。。
ファイルをローカルに書き出す
Node.jsでローカルファイルとして書き出す場合はこんな感じ。
import * as XLSX from "xlsx"; XLSX.writeFile(workbook, 'out.xlsx');
ファイルをダウンロードする
Web上でダウンロードする場合はこんな感じ。
FileSaver.jsを使うといいらしい。
import * as XLSX from "xlsx"; import { saveAs } from "file-saver"; function async downloadWorkbook(workbook: XLSX.WorkBook) { // 書き込むときの設定 const wopts: XLSX.WritingOptions = { bookType: "xlsx", bookSST: true, type: "array" }; // workbookを書き出し const wbout = XLSX.write(workbook, wopts); // FileSaver.jsでダウンロード const blob = new Blob([wbout], { type: "application/octet-stream" }); saveAs(blob, 'out.xlsx'); }
以上!!