Skip to main content
Home

latest
This package works with Cloudflare Workers, Node.js, Deno, Bun, Browsers
This package works with Cloudflare Workers
This package works with Node.js
This package works with Deno
This package works with Bun
This package works with Browsers
JSR Score
41%
Published
2 years ago (0.0.1)
import JSZip from "npm:jszip@3.10.1"; import { DOMParser, Element, HTMLDocument } from "npm:xmldom@0.6.0"; export async function parseXLSX(arrayBuffer: ArrayBuffer): Promise<Record<string, unknown[][]>> { const zip = await JSZip.loadAsync(arrayBuffer); const workbook = await zip.file("xl/workbook.xml")?.async("text"); const parser = new DOMParser(); if (!workbook) { throw new Error("Workbook not found"); } const workbookDoc = parser.parseFromString(workbook, "application/xml"); if (!workbookDoc) { throw new Error("Workbook not found"); } const sheetNames = [...workbookDoc.getElementsByTagName("sheet")].map( (sheet) => ({ id: sheet.getAttribute("r:id"), name: sheet.getAttribute("name") }) ); const sheets: Record<string, unknown[][]> = {}; for (const { id, name } of sheetNames) { const sheetRels = await zip.file("xl/_rels/workbook.xml.rels")?.async("text"); if (!sheetRels) { throw new Error("Sheet relationships not found"); } const relsDoc = parser.parseFromString(sheetRels, "application/xml"); if (!relsDoc) { throw new Error("Sheet relationships not found"); } const relsEls = relsDoc.getElementsByTagName("Relationship"); if (!relsEls) { throw new Error("Sheet relationships not found"); } const sheetFilePath = [...relsEls].find((rel) => rel.getAttribute("Id") === id)?.getAttribute("Target"); const sheetContent = await zip.file("xl/" + sheetFilePath)?.async("text"); if (!sheetContent) { throw new Error("Sheet content not found"); } const sheetDoc = parser.parseFromString(sheetContent, "application/xml"); // if name is not found, use id const key = name || id; if (key && sheetDoc) { sheets[key] = parseSheet(sheetDoc); } } return sheets; } export function parseSheet(sheetDoc: HTMLDocument): unknown[][] { const rows = []; const rowElements = sheetDoc.getElementsByTagName("row"); for (const rowElement of rowElements) { const row = []; const cellElements = rowElement.getElementsByTagName("c"); for (const cellElement of cellElements) { const cellValue = parseCell(cellElement); row.push(cellValue); } rows.push(row); } return rows; } export function parseCell(cellElement: Element): string | null { const valueElement = cellElement.getElementsByTagName("v")[0]; if (!valueElement) { return null; } return valueElement.textContent; }