3
2

More than 1 year has passed since last update.

【TypeScript】ExcelJSで出力したCSVへのSJIS対応

Posted at

ExcelJSによるCSV出力とSJIS対応

ExcelJSを利用して出力したCSVファイルをSJIS対応させようとサイトを参考にコードを書いたらエラーを吐いて動かなかったので備忘録。
SJIS対応にはecoding.jsをnpm installしてインポートする。

CSVファイルを作成する部分は他サイトにお任せして、エラーになった部分を以下に抜粋。

Csv.ts
import Encoding from "encoding-japanese";
// 省略
const workbook = new ExcelJS.Workbook(); //ブックを作成

// 省略
const uint8Arr = new Uint8Array(
  Encoding.convert((await workbook.csv.writeBuffer()), { 
// await workbook.csv.writeBuffer()にエラーが表示される
    from: "UTF8",
    to: "SJIS",
  })
);

Encoding.convertの引数の定義を見てみると以下のように一つ目の引数はstring型かIntArrayType型である必要がある。

export function convert(data: IntArrayType, to: Encoding, from?: Encoding): number[];
export function convert(data: string, to: Encoding, from?: Encoding): string;
export function convert(data: IntArrayType | string, options: ConvertStringOptions): string;
export function convert(data: IntArrayType | string, options: ConvertArrayBufferOptions): ArrayBuffer;
export function convert(data: IntArrayType | string, options: ConvertArrayOptions): number[];
export function convert(data: string, options: ConvertUnknownOptions): string;
export function convert(data: IntArrayType, options: ConvertUnknownOptions): number[];

さらにIntArrayType型は以下のように複数の配列の型で構成されている。

type IntArrayType =
    | ReadonlyArray<number>
    | Uint8Array
    | Uint16Array
    | Uint32Array
    | Int8Array
    | Int16Array
    | Int32Array;

そしてconvertの一つ目の引数に入れた関数writeBufferは以下のようにBufferを返してくれるようだが、BufferArrayBufferを継承しただけの模様。

writeBuffer(options?: Partial<CsvWriteOptions>): Promise<Buffer>;
declare interface Buffer extends ArrayBuffer { }

ArrayBufferUint8Arrayについてはここが綺麗にまとまっていて読みやすい。

解決策

つまりエラーメッセージにもあるようにIntArrayType型の引数が必要なのにBuffer型の変数を入れてんじゃねぇと怒られているわけなので、以下のようにUint8Array型にキャストしてあげるとエラーが解消され、SJISで文字化けしないCSVファイルが無事に出力される。

Csv.ts
const uint8Arr = new Uint8Array(
  Encoding.convert((await workbook.csv.writeBuffer() as Uint8Array), { 
// asでキャストする
    from: "UTF8",
    to: "SJIS",
  })
);
3
2
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
3
2