![[React / JavaScript] ExcelJSで実装したCSV出力機能でSJIS変換対応をしてみた](https://devio2023-media.developers.io/wp-content/uploads/2020/04/javascript.png)
[React / JavaScript] ExcelJSで実装したCSV出力機能でSJIS変換対応をしてみた
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部 IoT事業部の若槻です。
前回のエントリでは、ExcelJSを使用してアプリにExcel/CSVのダウンロード機能を実装しましたが、その際のCSVの文字コードはUTF8でした。
今回は、ReactアプリでExcelJSで実装したCSV出力機能で文字コードをSJIS(Shift-JIS)に変換する対応をしてみました。
デモ
下記リンクを別タブで開きます。上記サンドボックスのプレビューが開けます。
SJIS形式でダウンロード
[CSV形式(SJIS)]をクリックして、ファイルをダウンロードします。

ダウンロードしたファイルをVSCodeで開くと、日本語文字(ダブルバイト文字)が文字化けします。

[UTF-8]をクリックして、[Reopen with Encoding]をクリックします。

[Japanese (Shift JIS)]をクリックしてファイルをSJISで開き直します。

すると文字化けが解消して日本語文字が正常に表示されました。

ファイルをExcelで開いても文字化けなく日本語文字を表示させられました。

UTF8形式でダウンロード
UTF8の方も試してみます。
[CSV形式(UTF8)]をクリックして、ファイルをダウンロードします。

ダウンロードしたファイルをVSCodeで開くと、UTF8で文字化けなく開けました。

ファイルをExcelで開くとこちらはちゃんと(?)文字化けしました。

コード概要
import React from "react";
import "./styles.css";
import ExcelJS from "exceljs";
import encoding from "encoding-japanese";
export const App: React.FC = () => {
  const handlerClickDownloadButton = async (
    e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
    format: "xlsx" | "csv",
    charcode?: "UTF8" | "SJIS"
  ) => {
    e.preventDefault();
    const workbook = new ExcelJS.Workbook();
    workbook.addWorksheet("sheet1");
    const worksheet = workbook.getWorksheet("sheet1");
    worksheet.columns = [
      { header: "ID", key: "id" },
      { header: "作成日時", key: "createdAt" },
      { header: "名前", key: "name" }
    ];
    worksheet.addRows([
      {
        id: "f001",
        createdAt: 1629902208,
        name: "りんご"
      },
      {
        id: "f002",
        createdAt: 1629902245,
        name: "ぶどう"
      },
      {
        id: "f003",
        createdAt: 1629902265,
        name: "ばなな"
      }
    ]);
    const uint8Array =
      format === "xlsx"
        ? await workbook.xlsx.writeBuffer()
        : charcode === "UTF8"
        ? await workbook.csv.writeBuffer()
        : new Uint8Array(
            encoding.convert(await workbook.csv.writeBuffer(), {
              from: "UTF8",
              to: "SJIS"
            })
          );
    const blob = new Blob([uint8Array], {
      type: "application/octet-binary"
    });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "sampleData." + format;
    a.click();
    a.remove();
  };
  return (
    <>
      <header>
        <h1>データ出力</h1>
      </header>
      <>
        <button onClick={(e) => handlerClickDownloadButton(e, "xlsx")}>
          Excel形式
        </button>
        <button onClick={(e) => handlerClickDownloadButton(e, "csv", "UTF8")}>
          CSV形式(UTF8)
        </button>
        <button onClick={(e) => handlerClickDownloadButton(e, "csv", "SJIS")}>
          CSV形式(SJIS)
        </button>
      </>
    </>
  );
};
- 文字コードの変換にはencoding-japaneseを使用しています。
 await workbook.csv.writeBuffer()により作成したuint8ArrayはUTF8となります。「CSV形式(SJIS)」ボタンが押された時はそれをencoding.convert()によりUTF8からSJISに変換して新しいuint8Arrayを作成しています。
参考
以上






