33 lines
1.1 KiB
TypeScript
33 lines
1.1 KiB
TypeScript
import { mkdir } from 'node:fs/promises';
|
|
import { dirname } from 'node:path';
|
|
import XLSX from 'xlsx';
|
|
import { CatalogPayload, OutputWriter, sanitizeSheetName } from './sheets.js';
|
|
|
|
export class ExcelWriter implements OutputWriter {
|
|
public constructor(private readonly path: string) {}
|
|
|
|
public async write(payload: CatalogPayload): Promise<void> {
|
|
const workbook = XLSX.utils.book_new();
|
|
const grouped = new Map<string, Record<string, unknown>[]>();
|
|
for (const row of payload.rows) {
|
|
const sheet = sanitizeSheetName(String(row['Source Newsletter'] ?? 'Newsletter'));
|
|
grouped.set(sheet, [...(grouped.get(sheet) ?? []), row]);
|
|
}
|
|
for (const [sheet, rows] of grouped) {
|
|
XLSX.utils.book_append_sheet(workbook, XLSX.utils.json_to_sheet(rows), sheet);
|
|
}
|
|
XLSX.utils.book_append_sheet(
|
|
workbook,
|
|
XLSX.utils.json_to_sheet(payload.sponsors),
|
|
'Sponsored Links'
|
|
);
|
|
XLSX.utils.book_append_sheet(
|
|
workbook,
|
|
XLSX.utils.json_to_sheet(payload.deadLinks),
|
|
'Dead Links'
|
|
);
|
|
await mkdir(dirname(this.path), { recursive: true });
|
|
XLSX.writeFile(workbook, this.path);
|
|
}
|
|
}
|