くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

JavaScriptでExcelを操作する

Excelでデータのエクスポートしたいなと思い、いろいろ調べてみたら、
SheetJS(xlsx)を使うとできるらしいので、試してみたときの備忘録。

注意

  • 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つ

  1. axiosのresponseTypeをarraybufferにする
  2. 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"
  };
}

ポイントは、

  1. worksheetはシート名を指定しないといけない
  2. 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');
}

以上!!

参考にしたサイト様