Files
CapaKraken/packages/application/src/use-cases/dispo-import/read-workbook.ts
T

80 lines
1.9 KiB
TypeScript

import XLSXModule from "xlsx";
const XLSX =
(
XLSXModule as typeof import("xlsx") & {
default?: typeof import("xlsx");
}
).default ?? (XLSXModule as typeof import("xlsx"));
export type WorksheetCellValue = boolean | Date | number | string | null;
export type WorksheetMatrix = WorksheetCellValue[][];
function normalizeWorksheetCellValue(value: unknown): WorksheetCellValue {
if (value === undefined || value === null) {
return null;
}
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
return value;
}
if (value instanceof Date) {
return value;
}
return String(value);
}
export async function readWorksheetMatrix(
workbookPath: string,
sheetName: string,
): Promise<WorksheetMatrix> {
const workbook = XLSX.readFile(workbookPath, {
cellDates: true,
dense: true,
});
const worksheet = workbook.Sheets[sheetName];
if (!worksheet) {
throw new Error(`Worksheet "${sheetName}" not found in workbook "${workbookPath}"`);
}
const rows = XLSX.utils.sheet_to_json<(WorksheetCellValue | null)[]>(worksheet, {
header: 1,
raw: true,
defval: null,
});
return rows.map((row) => row.map((value) => normalizeWorksheetCellValue(value)));
}
export function getCellString(
rows: WorksheetMatrix,
rowNumber: number,
columnNumber: number,
): string | null {
const value = rows[rowNumber - 1]?.[columnNumber - 1];
if (value === null || value === undefined) {
return null;
}
if (value instanceof Date) {
return value.toISOString();
}
return String(value);
}
export function toColumnLetter(columnNumber: number): string {
let current = columnNumber;
let result = "";
while (current > 0) {
const remainder = (current - 1) % 26;
result = String.fromCharCode(65 + remainder) + result;
current = Math.floor((current - 1) / 26);
}
return result;
}