Files
bizmax_downloader/convert-xlsx-to-csv.ts
2026-04-13 11:25:40 +09:00

92 lines
2.5 KiB
TypeScript

import XLSX from "xlsx";
import { mkdir, readdir, writeFile } from "node:fs/promises";
import path from "node:path";
const INPUT_DIR = process.env.BIZMAX_OUTPUT_DIR ?? path.resolve(process.cwd(), "output");
const CSV_DIR = process.env.BIZMAX_CSV_DIR ?? path.join(INPUT_DIR, "csv");
const CSV_NAME = process.env.BIZMAX_CSV_NAME ?? "bizmax-all.csv";
function toText(value: unknown): string {
if (value == null) {
return "";
}
return String(value);
}
function escapeCsv(value: string): string {
if (/[",\n\r]/.test(value)) {
return `"${value.replace(/"/g, "\"\"")}"`;
}
return value;
}
function rowToCsv(row: string[]): string {
return row.map(escapeCsv).join(",");
}
async function main(): Promise<void> {
const entries = await readdir(INPUT_DIR, { withFileTypes: true });
const xlsxFiles = entries
.filter((entry) => entry.isFile() && entry.name.toLowerCase().endsWith(".xlsx"))
.map((entry) => path.join(INPUT_DIR, entry.name))
.sort();
if (xlsxFiles.length === 0) {
throw new Error(`No .xlsx files found in ${INPUT_DIR}`);
}
const outputRows: string[] = [];
let wroteHeader = false;
for (const xlsxFile of xlsxFiles) {
const workbook = XLSX.readFile(xlsxFile, { cellDates: false });
for (const sheetName of workbook.SheetNames) {
const worksheet = workbook.Sheets[sheetName];
const rows = XLSX.utils.sheet_to_json<unknown[]>(worksheet, {
header: 1,
raw: false,
defval: "",
});
if (rows.length === 0) {
continue;
}
const headerRow = (rows[0] ?? []).map(toText);
if (!wroteHeader) {
outputRows.push(
rowToCsv(["source_file", "source_sheet", ...headerRow]),
);
wroteHeader = true;
}
for (const row of rows.slice(1)) {
const values = (row as unknown[]).map(toText);
outputRows.push(
rowToCsv([
path.basename(xlsxFile),
sheetName,
...values,
]),
);
}
}
}
if (!wroteHeader) {
throw new Error(`No worksheet rows found in ${INPUT_DIR}`);
}
await mkdir(CSV_DIR, { recursive: true });
const outputPath = path.join(CSV_DIR, CSV_NAME);
await writeFile(outputPath, `${outputRows.join("\n")}\n`, "utf8");
process.stdout.write(`${outputPath}\n`);
}
main().catch((error: unknown) => {
const message = error instanceof Error ? error.message : String(error);
process.stderr.write(`${message}\n`);
process.exitCode = 1;
});