@dou-ui/sheet-xlsx 0.0.0-stage → 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +10 -2
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/messages.js +94 -0
- package/dist/messages.js.map +1 -0
- package/dist/read-styles.js +301 -0
- package/dist/read-styles.js.map +1 -0
- package/dist/read.js +1099 -0
- package/dist/read.js.map +1 -0
- package/dist/styles.js +124 -0
- package/dist/styles.js.map +1 -0
- package/dist/types/index.d.ts +25 -0
- package/dist/types/messages.d.ts +20 -0
- package/dist/types/read-styles.d.ts +28 -0
- package/dist/types/read.d.ts +36 -0
- package/dist/types/styles.d.ts +33 -0
- package/dist/types/write.d.ts +13 -0
- package/dist/types/xml-read.d.ts +45 -0
- package/dist/types/xml.d.ts +8 -0
- package/dist/types/zip.d.ts +32 -0
- package/dist/write.js +799 -0
- package/dist/write.js.map +1 -0
- package/dist/xml-read.js +166 -0
- package/dist/xml-read.js.map +1 -0
- package/dist/xml.js +20 -0
- package/dist/xml.js.map +1 -0
- package/dist/zip.js +168 -0
- package/dist/zip.js.map +1 -0
- package/package.json +44 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.js","names":[],"sources":["../src/write.ts"],"sourcesContent":["import {\n boundsOf,\n columnName,\n lightThemeColor,\n linkTarget,\n meetsRule,\n parseRange,\n plainStyle,\n quoteSheet,\n renameReferencesAll,\n textCollator,\n type SheetBounds,\n type SheetColor,\n type SheetCondition,\n type SheetConditionalFormat,\n type SheetConditionalStyle,\n type SheetData,\n type SheetFileSource,\n type SheetLinkTarget,\n type SheetProtection,\n type SheetStyle,\n type SheetValidation,\n type SheetValue,\n} from '@dou-ui/sheet/core'\nimport { isSheetError, serialOf } from '@dou-ui/sheet/formula'\nimport { argb, StyleSheet } from './styles'\nimport { attrs, esc, HEAD, NS, NS_PKG, NS_R } from './xml'\nimport { pause, SLICE, zip, type ZipEntry } from './zip'\n\n/** Options of the .xlsx exporter. */\nexport interface SheetXlsxExportOptions {\n /**\n * Writes formulas, with what they came to so other programs show the\n * results until they work them out again; `false` writes only the\n * results, e.g. for formulas with functions only this grid has. `true`\n * by default; exporting the selection always writes the results.\n */\n formulas?: boolean\n}\n\n/** An error as the file can hold it: a formula that depends on itself as `#VALUE!`. */\nconst errorCode = (code: string) => esc(code === '#CYCLE!' ? '#VALUE!' : code)\n\nconst encoder = new TextEncoder()\n\n/** The deepest outline level, `undefined` for none. */\nfunction maxLevel(levels: Map<number, number>) {\n let max = 0\n for (const level of levels.values()) if (level > max) max = level\n return max || undefined\n}\n\nconst DATE = /^\\d{4}-\\d{2}-\\d{2}$/\nconst DATE_TIME = /^\\d{4}-\\d{2}-\\d{2}[ T]\\d{2}:\\d{2}(:\\d{2})?$/\nconst TIME = /^\\d{2}:\\d{2}(:\\d{2})?$/\n\n/** The number format of a date or time written as text, when the cell has none. */\nfunction dateFormat(text: string) {\n if (DATE.test(text)) return 'yyyy-mm-dd'\n if (DATE_TIME.test(text)) return text.length > 16 ? 'yyyy-mm-dd hh:mm:ss' : 'yyyy-mm-dd hh:mm'\n if (TIME.test(text)) return text.length > 5 ? 'hh:mm:ss' : 'hh:mm'\n return undefined\n}\n\n/** Column widths: px to the characters the file counts in, which the file format turns back into these px (its padding included). */\nconst widthOf = (px: number) => Math.max(0, Math.round((px * 256) / 7) / 256)\n/** Row heights: px to points. */\nconst heightOf = (px: number) => Math.round(px * 0.75 * 100) / 100\n\nconst cellName = (row: number, col: number) => `${columnName(col)}${row + 1}`\nconst rangeText = (b: SheetBounds) =>\n b.top === b.bottom && b.left === b.right\n ? cellName(b.top, b.left)\n : `${cellName(b.top, b.left)}:${cellName(b.bottom, b.right)}`\n\nconst ILLEGAL = /[[\\]:*?/\\\\]/g\n/** Whether other programs take a sheet name as it is. */\nconst legalName = (name: string) =>\n name.length > 0 &&\n name.length <= 31 &&\n !/[[\\]:*?/\\\\]/.test(name) &&\n !name.startsWith(\"'\") &&\n !name.endsWith(\"'\")\n\n/**\n * Sheet names other programs take: at most 31 characters, none of\n * `[]:*?/\\`, no `'` at either end, each different ignoring case. Names\n * that are fine stay as they are; the others are changed, with a number\n * after them when that makes them the same as another.\n */\nfunction sheetNames(names: string[]) {\n const out: (string | undefined)[] = []\n const taken = new Set<string>()\n for (const [i, name] of names.entries())\n if (legalName(name) && !taken.has(name.toLowerCase())) {\n out[i] = name\n taken.add(name.toLowerCase())\n }\n for (const [i, name] of names.entries()) {\n if (out[i] != null) continue\n const base = name.replace(ILLEGAL, '_').replace(/^'|'$/g, '_').slice(0, 31) || 'Sheet'\n let next = base\n for (let n = 2; taken.has(next.toLowerCase()); n++) {\n const tail = ` (${n})`\n next = base.slice(0, 31 - tail.length) + tail\n }\n taken.add(next.toLowerCase())\n out[i] = next\n }\n return out as string[]\n}\n\n/**\n * A list of values written in the rule itself, `\"a,b\"`, or `null` when it\n * can't be: a value with a comma or a quote would split or end it, and\n * the file holds at most 255 characters.\n */\nfunction inlineList(options: readonly unknown[]) {\n const values = options.map((o) =>\n String(typeof o === 'object' && o !== null ? (o as { value: unknown }).value : o),\n )\n if (values.some((v) => v.includes(',') || v.includes('\"'))) return null\n const list = `\"${values.join(',')}\"`\n return list.length <= 255 ? list : null\n}\n\n/** The ranges of a rule, as the file lists them. */\nconst sqref = (range: string | string[]) =>\n (Array.isArray(range) ? range : [range]).map((r) => r.replaceAll('$', '').trim()).join(' ')\n\n/** The top left cell of a rule's first range, which its formula is written for. */\nfunction anchorOf(range: string | string[]) {\n const first = Array.isArray(range) ? range[0] : range\n const parsed = first ? parseRange(first.replaceAll('$', '')) : null\n if (!parsed) return 'A1'\n const b = boundsOf(parsed)\n return cellName(Number.isFinite(b.top) ? b.top : 0, Number.isFinite(b.left) ? b.left : 0)\n}\n\n/** A value in a formula: numbers as they are, dates as day numbers, text in quotes. */\nfunction literal(value: SheetValue | undefined) {\n if (value == null) return '\"\"'\n if (typeof value === 'number') return String(value)\n if (typeof value === 'boolean') return value ? 'TRUE' : 'FALSE'\n const serial = dateFormat(value) ? serialOf(value) : null\n if (serial != null) return String(serial)\n return `\"${value.replaceAll('\"', '\"\"')}\"`\n}\n\nconst formulaText = (formula: string) => (formula.startsWith('=') ? formula.slice(1) : formula)\n\nconst CELL_IS: Partial<Record<SheetCondition['op'], string>> = {\n eq: 'equal',\n ne: 'notEqual',\n gt: 'greaterThan',\n ge: 'greaterThanOrEqual',\n lt: 'lessThan',\n le: 'lessThanOrEqual',\n between: 'between',\n notBetween: 'notBetween',\n}\n\n/** A tone's soft fill or plain color as the light theme paints it, for scales and bars. */\nfunction toneColor(color: SheetColor, share: number) {\n const tones = ['neutral', 'primary', 'success', 'warning', 'danger']\n if (!tones.includes(color)) return lightThemeColor(color)\n const base = color === 'neutral' ? 'var(--dou-color-text)' : `var(--dou-color-${color})`\n return lightThemeColor(`color-mix(in oklab, ${base} ${share}%, var(--dou-color-bg-surface))`)\n}\n\n/** Writes the cells a source exports as an .xlsx file. */\nexport async function writeXlsx(\n source: SheetFileSource,\n options: SheetXlsxExportOptions = {},\n): Promise<Uint8Array> {\n const book = source.book\n if (!source.sheets.length)\n throw new Error('[@dou-ui/sheet-xlsx] a workbook needs at least one sheet to be written')\n const styles = new StyleSheet()\n const strings: string[] = []\n const stringIds = new Map<string, number>()\n let stringCount = 0\n const shared = (text: string) => {\n stringCount++\n let id = stringIds.get(text)\n if (id == null) {\n id = strings.push(text) - 1\n stringIds.set(text, id)\n }\n return id\n }\n const namedStyles = new Map<string, SheetStyle | undefined>()\n const styleNamed = (name: string | undefined) => {\n if (!name) return undefined\n if (!namedStyles.has(name)) {\n const style = book.styles?.[name]\n namedStyles.set(name, style ? plainStyle(style) : undefined)\n }\n return namedStyles.get(name)\n }\n const lookStyle = (style: SheetConditionalStyle) =>\n typeof style === 'string' ? styleNamed(style) : plainStyle(style)\n\n // a cell's look by its style's name and format, each pair worked out once\n const looks = new Map<string | undefined, Map<string, number>>()\n const lookOf = (name: string | undefined, format: string | undefined, quote: boolean) => {\n let byFormat = looks.get(name)\n if (!byFormat) looks.set(name, (byFormat = new Map()))\n const key = (quote ? \"'\" : '') + (format ?? '')\n let id = byFormat.get(key)\n if (id == null) {\n id = styles.look({ style: styleNamed(name), format, quote })\n byFormat.set(key, id)\n }\n return id\n }\n // dates repeat a lot in a column: each text's day number and format, worked out once\n const dates = new Map<string, { serial: number; format: string } | null>()\n const dateOf = (text: string) => {\n let date = dates.get(text)\n if (date === undefined) {\n const format = dateFormat(text)\n const serial = format ? serialOf(text) : null\n date = format && serial != null ? { serial, format } : null\n if (dates.size < 100_000) dates.set(text, date)\n }\n return date\n }\n\n // what `plainCell` gives besides the cell's content, kept out of a new object per cell\n let plainKind: string | undefined\n let plainFormat: string | undefined\n let plainQuote = false\n /** A value's content; its type, format and quoting go to `plainKind`, `plainFormat` and `plainQuote`. */\n function plainCell(value: SheetValue | undefined, format: string | undefined) {\n plainKind = undefined\n plainFormat = format\n plainQuote = false\n if (value == null || value === '') return ''\n if (typeof value === 'number') {\n if (Number.isFinite(value)) return `<v>${value}</v>`\n // what the file can't hold as a number, such as dividing by zero worked out by hand\n plainKind = 'e'\n return '<v>#NUM!</v>'\n }\n if (typeof value === 'boolean') {\n plainKind = 'b'\n return `<v>${value ? 1 : 0}</v>`\n }\n const first = value.charCodeAt(0)\n const date = first >= 48 && first <= 57 ? dateOf(value) : null\n if (date) {\n plainFormat = format ?? date.format\n return `<v>${date.serial}</v>`\n }\n plainKind = 's'\n if (value.startsWith(\"'=\")) {\n plainQuote = true\n return `<v>${shared(value.slice(1))}</v>`\n }\n return `<v>${shared(value)}</v>`\n }\n\n const selection = source.scope === 'selection'\n const keepFormulas = !selection && options.formulas !== false\n const { colWidth, rowHeight } = source\n const names = sheetNames(source.sheets.map((s) => s.data.name))\n // sheets whose names changed, or read as a cell and need quoting: formulas referring to them follow\n const renamed = new Map<string, string>()\n for (const [i, { data }] of source.sheets.entries())\n if (names[i] !== data.name || quoteSheet(data.name).startsWith(\"'\"))\n renamed.set(data.name, names[i]!)\n const rename = (formula: string) => renameReferencesAll(formula, renamed)\n const entries: ZipEntry[] = []\n const sheetFiles: { name: string; hidden: boolean; filter?: string }[] = []\n\n const pacing = { signal: source.signal, lastPause: { at: performance.now() } }\n for (const [n, { index, data, bounds }] of source.sheets.entries()) {\n source.signal?.throwIfAborted()\n // the selection goes in at A1; a whole sheet keeps its places\n const top = selection && bounds ? bounds.top : 0\n const left = selection && bounds ? bounds.left : 0\n const last = bounds ? { row: bounds.bottom, col: bounds.right } : { row: -1, col: -1 }\n // column letters, worked out once per column\n const letters: string[] = []\n let rowName = ''\n const at = (_row: number, col: number) => (letters[col] ??= columnName(col - left)) + rowName\n\n // sizes, hidden lines and groups, by line\n const rowLevels = new Map<number, number>()\n const colLevels = new Map<number, number>()\n const hiddenRows = new Set<number>()\n const hiddenCols = new Set<number>()\n const collapsedRows = new Set<number>()\n const collapsedCols = new Set<number>()\n const after = data.groupSummary === 'after'\n if (!selection)\n for (const group of data.groups ?? []) {\n const parsed = parseRange(group.range)\n if (!parsed) continue\n const b = boundsOf(parsed)\n const rows = b.left === 0 && b.right === Infinity\n const [start, end] = rows ? [b.top, b.bottom] : [b.left, b.right]\n if (!Number.isFinite(end)) continue\n const levels = rows ? rowLevels : colLevels\n for (let i = start; i <= end; i++) levels.set(i, Math.min(7, (levels.get(i) ?? 0) + 1))\n if (group.collapsed) {\n const hidden = rows ? hiddenRows : hiddenCols\n for (let i = start; i <= end; i++) hidden.add(i)\n ;(rows ? collapsedRows : collapsedCols).add(after ? end + 1 : start - 1)\n }\n }\n for (const [key, size] of Object.entries(data.rowSizes ?? {}))\n if (size === 0) hiddenRows.add(+key)\n // rows the filter hides, hidden in the file too: other programs don't filter on opening\n if (!selection)\n for (const row of filteredOut(source, index, data, last.row)) hiddenRows.add(row)\n for (const [key, size] of Object.entries(data.colSizes ?? {}))\n if (size === 0) hiddenCols.add(+key)\n\n // columns: their widths, hidden ones and groups\n const colList = new Set<number>()\n for (const key of Object.keys(data.colSizes ?? {})) colList.add(+key)\n for (const col of colLevels.keys()) colList.add(col)\n for (const col of hiddenCols) colList.add(col)\n const cols = [...colList]\n .filter((col) => col >= left && (!selection || col <= last.col))\n // oxlint-disable-next-line unicorn/no-array-sort -- sorts the list built here\n .sort((a, b) => a - b)\n .map((col) => {\n const size = data.colSizes?.[col]\n const hidden = hiddenCols.has(col)\n return `<col${attrs({\n min: col - left + 1,\n max: col - left + 1,\n width: widthOf(size || colWidth),\n customWidth: size != null && size > 0 ? 1 : undefined,\n hidden,\n outlineLevel: colLevels.get(col),\n collapsed: collapsedCols.has(col) ? 1 : undefined,\n })}/>`\n })\n\n // cells, row by row; list cells for the types that pick from a list\n const lists = new Map<string, { values: string; cells: string[] } | null>()\n const notes: { ref: string; row: number; col: number; text: string }[] = []\n const links: { ref: string; target: SheetLinkTarget; link: string }[] = []\n const rows: string[] = []\n // the column a cell written next is in without saying so\n let nextCol = left\n // rows past the cells still written for their size, group or being hidden\n let lastRow = last.row\n if (!selection) {\n for (const row of rowLevels.keys()) if (row > lastRow) lastRow = row\n for (const row of hiddenRows) if (row > lastRow) lastRow = row\n for (const key of Object.keys(data.rowSizes ?? {})) if (+key > lastRow) lastRow = +key\n }\n // the rows go into bytes as they are written, so the text of a big sheet isn't held whole\n const chunks: Uint8Array[] = []\n const flush = () => {\n if (rows.length) chunks.push(encoder.encode(rows.join('')))\n rows.length = 0\n }\n for (let row = top; row <= lastRow; row++) {\n const line = data.cells[row]\n rowName = String(row - top + 1)\n let xml = ''\n nextCol = left\n if (line && row <= last.row)\n for (let col = left; col <= last.col && col < line.length; col++) {\n const input = line[col]\n if (input == null) continue\n xml += cellXML(row, col, input)\n }\n const size = data.rowSizes?.[row]\n const level = rowLevels.get(row)\n const hidden = hiddenRows.has(row)\n if (!xml && size == null && !level && !hidden) continue\n if (rows.length >= 1000) {\n flush()\n // a big sheet takes a while: let the page go on and the export be called off\n if (performance.now() - pacing.lastPause.at > SLICE) {\n await pause()\n source.signal?.throwIfAborted()\n pacing.lastPause.at = performance.now()\n }\n }\n rows.push(\n `<row${attrs({\n r: row - top + 1,\n ht: size ? heightOf(size) : undefined,\n customHeight: size ? 1 : undefined,\n hidden,\n outlineLevel: level,\n collapsed: collapsedRows.has(row) ? 1 : undefined,\n })}${xml ? `>${xml}</row>` : '/>'}`,\n )\n }\n\n function cellXML(row: number, col: number, input: unknown) {\n const cell =\n typeof input === 'object' && input !== null ? (input as Record<string, unknown>) : null\n if (cell && typeof cell.note === 'string' && cell.note)\n notes.push({ ref: at(row, col), row: row - top, col: col - left, text: cell.note })\n if (cell && typeof cell.link === 'string') {\n const target = linkTarget(cell.link)\n if (target) links.push({ ref: at(row, col), target, link: cell.link })\n }\n const value = source.value(index, row, col)\n const typed = source.cellType(index, row, col)\n let format = cell && typeof cell.format === 'string' ? cell.format : undefined\n const styleName = cell && typeof cell.style === 'string' ? cell.style : undefined\n\n // a type that picks from a list: its values become the cell's list\n if (typed?.name === 'select' && Array.isArray(typed.setup.options)) {\n const key = cell?.type as string\n let list = lists.get(key)\n if (list === undefined) {\n const values = inlineList(typed.setup.options)\n list = values == null ? null : { values, cells: [] }\n lists.set(key, list)\n }\n list?.cells.push(at(row, col))\n }\n\n let body = ''\n let kind: string | undefined\n let quote = false\n if (typed?.definition.plain) {\n body = plainCell(source.plain(index, row, col), format)\n kind = plainKind\n format = plainFormat\n } else if (typeof value === 'string' && value.startsWith('=') && value.length > 1) {\n const result = source.result(index, row, col)\n if (isSheetError(result) && result.code === '#ERROR!') {\n // not a formula other programs can read either: kept as its text\n kind = 's'\n body = `<v>${shared(value)}</v>`\n } else if (keepFormulas) {\n body = `<f>${esc(formulaText(rename(value)))}</f>`\n // what it came to; a date as its day number and a date format, as other programs give it\n if (isSheetError(result)) {\n kind = 'e'\n body += `<v>${errorCode(result.code)}</v>`\n } else if (typeof result === 'string') {\n const first = result.charCodeAt(0)\n const date = first >= 48 && first <= 57 ? dateOf(result) : null\n if (date) {\n body += `<v>${date.serial}</v>`\n format ??= date.format\n } else {\n kind = 'str'\n body += `<v>${esc(result)}</v>`\n }\n } else if (result != null) {\n body += plainCell(result, format)\n kind = plainKind\n }\n } else if (isSheetError(result)) {\n kind = 'e'\n body = `<v>${errorCode(result.code)}</v>`\n } else {\n body = plainCell(source.plain(index, row, col), format)\n kind = plainKind\n format = plainFormat\n }\n } else {\n body = plainCell(value, format)\n kind = plainKind\n format = plainFormat\n quote = plainQuote\n }\n\n const s = styleName || format || quote ? lookOf(styleName, format, quote) : 0\n if (!body && !s) return ''\n // a cell right after the one before goes without its name, which halves the file\n const named = col !== nextCol\n nextCol = col + 1\n return `<c${named ? ` r=\"${at(row, col)}\"` : ''}${s ? ` s=\"${s}\"` : ''}${kind ? ` t=\"${kind}\"` : ''}${body ? `>${body}</c>` : '/>'}`\n }\n\n // merges inside what is written\n const merges: string[] = []\n for (const merge of data.merges ?? []) {\n const parsed = parseRange(merge)\n if (!parsed) continue\n const b = boundsOf(parsed)\n if (selection && bounds) {\n if (b.top < top || b.left < left || b.bottom > bounds.bottom || b.right > bounds.right)\n continue\n }\n merges.push(\n `<mergeCell ref=\"${rangeText({ top: b.top - top, left: b.left - left, bottom: b.bottom - top, right: b.right - left })}\"/>`,\n )\n }\n\n const extra = selection ? null : sheetRules(data)\n const freeze =\n !selection && data.freeze && (data.freeze.rows || data.freeze.cols) ? data.freeze : null\n const pane = freeze\n ? `<pane${attrs({\n xSplit: freeze.cols || undefined,\n ySplit: freeze.rows || undefined,\n topLeftCell: cellName(freeze.rows ?? 0, freeze.cols ?? 0),\n activePane:\n freeze.rows && freeze.cols ? 'bottomRight' : freeze.rows ? 'bottomLeft' : 'topRight',\n state: 'frozen',\n })}/>`\n : ''\n const hasLevels = rowLevels.size || colLevels.size\n\n // a list from a cell type, where the cell has no rule of its own\n const typeLists = [...lists.values()]\n .filter((list) => list != null)\n .map(\n ({ values, cells }) =>\n `<dataValidation type=\"list\" allowBlank=\"1\" showErrorMessage=\"1\" sqref=\"${esc(\n compactRefs(cells),\n )}\"><formula1>${esc(values)}</formula1></dataValidation>`,\n )\n const validations = [...typeLists, ...(extra?.validations ?? [])]\n\n const relsList: string[] = []\n let legacy = ''\n if (notes.length) {\n const id = n + 1\n entries.push({ path: `xl/comments${id}.xml`, data: commentsXML(notes) })\n entries.push({ path: `xl/drawings/vmlDrawing${id}.vml`, data: vmlXML(notes) })\n relsList.push(\n `<Relationship Id=\"rId1\" Type=\"${NS_R}/comments\" Target=\"../comments${id}.xml\"/>`,\n `<Relationship Id=\"rId2\" Type=\"${NS_R}/vmlDrawing\" Target=\"../drawings/vmlDrawing${id}.vml\"/>`,\n )\n legacy = '<legacyDrawing r:id=\"rId2\"/>'\n }\n // links: web addresses through the sheet's relationships, places in the workbook as they are\n const hyperlinks = links.map(({ ref, target, link }) => {\n if (target.kind === 'cell') return `<hyperlink${attrs({ ref, location: link.slice(1) })}/>`\n const id = `rId${relsList.length + 1}`\n relsList.push(\n `<Relationship Id=\"${id}\" Type=\"${NS_R}/hyperlink\" Target=\"${esc(target.href)}\" TargetMode=\"External\"/>`,\n )\n return `<hyperlink${attrs({ ref, 'r:id': id })}/>`\n })\n const protect = !selection && data.protect ? protectionXML(data.protect) : ''\n\n const lastCell =\n last.row >= top && last.col >= left\n ? rangeText({ top: 0, left: 0, bottom: last.row - top, right: last.col - left })\n : 'A1'\n flush()\n const head =\n `${HEAD}<worksheet xmlns=\"${NS}\" xmlns:r=\"${NS_R}\">` +\n (hasLevels\n ? `<sheetPr><outlinePr${attrs({ summaryBelow: after ? 1 : 0, summaryRight: after ? 1 : 0 })}/></sheetPr>`\n : '') +\n `<dimension ref=\"${lastCell}\"/>` +\n `<sheetViews><sheetView${attrs({ workbookViewId: 0, tabSelected: n === 0 ? 1 : undefined })}>${pane}</sheetView></sheetViews>` +\n `<sheetFormatPr${attrs({\n defaultRowHeight: heightOf(rowHeight),\n defaultColWidth: widthOf(colWidth),\n customHeight: 1,\n outlineLevelRow: maxLevel(rowLevels),\n outlineLevelCol: maxLevel(colLevels),\n })}/>` +\n (cols.length ? `<cols>${cols.join('')}</cols>` : '') +\n '<sheetData>'\n const tail =\n '</sheetData>' +\n protect +\n (extra?.filter ?? '') +\n (merges.length\n ? `<mergeCells count=\"${merges.length}\">${merges.join('')}</mergeCells>`\n : '') +\n (extra?.conditional ?? '') +\n (validations.length\n ? `<dataValidations count=\"${validations.length}\">${validations.join('')}</dataValidations>`\n : '') +\n (hyperlinks.length ? `<hyperlinks>${hyperlinks.join('')}</hyperlinks>` : '') +\n legacy +\n '</worksheet>'\n entries.push({\n path: `xl/worksheets/sheet${n + 1}.xml`,\n data: [encoder.encode(head), ...chunks, encoder.encode(tail)],\n })\n if (relsList.length)\n entries.push({\n path: `xl/worksheets/_rels/sheet${n + 1}.xml.rels`,\n data: `${HEAD}<Relationships xmlns=\"${NS_PKG}\">${relsList.join('')}</Relationships>`,\n })\n sheetFiles.push({\n name: names[n]!,\n hidden: false,\n filter: !selection && data.filter ? data.filter.range : undefined,\n })\n }\n\n /** A sheet's filter, conditional formats and validations. */\n function sheetRules(data: SheetData) {\n let filter = ''\n if (data.filter) {\n const parsed = parseRange(data.filter.range)\n const columns = Object.entries(data.filter.columns ?? {})\n .map(([col, rule]) => {\n const id = +col - (parsed ? boundsOf(parsed).left : 0)\n if ('values' in rule) {\n const blank = rule.values.includes('')\n const values = rule.values\n .filter((v) => v !== '')\n .map((v) => `<filter val=\"${esc(v)}\"/>`)\n .join('')\n return `<filterColumn colId=\"${id}\"><filters${attrs({ blank })}>${values}</filters></filterColumn>`\n }\n const custom = customFilter(rule.condition)\n return custom ? `<filterColumn colId=\"${id}\">${custom}</filterColumn>` : ''\n })\n .join('')\n filter = `<autoFilter ref=\"${esc(data.filter.range.replaceAll('$', ''))}\"${columns ? `>${columns}</autoFilter>` : '/>'}`\n }\n\n let priority = 0\n const conditional = (data.conditionalFormats ?? [])\n .map((rule) => {\n const xml = conditionalRule(rule, ++priority)\n return xml\n ? `<conditionalFormatting sqref=\"${esc(sqref(rule.range))}\">${xml}</conditionalFormatting>`\n : ''\n })\n .join('')\n\n const validations = (data.validations ?? [])\n .map((rule) => validationXML(rule, rename))\n .filter(Boolean)\n return { filter, conditional, validations }\n }\n\n function conditionalRule(rule: SheetConditionalFormat, priority: number) {\n const dxf = () => {\n const look = 'style' in rule && rule.style != null ? lookStyle(rule.style) : undefined\n return look ? styles.differential(look) : undefined\n }\n const anchor = anchorOf(rule.range)\n if ('when' in rule) {\n const { op, value, to } = rule.when\n const cellIs = CELL_IS[op]\n if (cellIs)\n return `<cfRule${attrs({ type: 'cellIs', dxfId: dxf(), priority, operator: cellIs })}><formula>${esc(\n literal(value),\n )}</formula>${op === 'between' || op === 'notBetween' ? `<formula>${esc(literal(to))}</formula>` : ''}</cfRule>`\n const text = String(value ?? '')\n const quoted = literal(text)\n const textRule = (type: string, operator: string | undefined, formula: string) =>\n `<cfRule${attrs({ type, dxfId: dxf(), priority, operator, text: operator ? text : undefined })}><formula>${esc(\n formula,\n )}</formula></cfRule>`\n if (op === 'contains')\n return textRule('containsText', 'containsText', `NOT(ISERROR(SEARCH(${quoted},${anchor})))`)\n if (op === 'notContains')\n return textRule('notContainsText', 'notContains', `ISERROR(SEARCH(${quoted},${anchor}))`)\n if (op === 'begins')\n return textRule('beginsWith', 'beginsWith', `LEFT(${anchor},LEN(${quoted}))=${quoted}`)\n if (op === 'ends')\n return textRule('endsWith', 'endsWith', `RIGHT(${anchor},LEN(${quoted}))=${quoted}`)\n if (op === 'blank') return textRule('containsBlanks', undefined, `LEN(TRIM(${anchor}))=0`)\n if (op === 'notBlank')\n return textRule('notContainsBlanks', undefined, `LEN(TRIM(${anchor}))>0`)\n return ''\n }\n if ('formula' in rule)\n return `<cfRule${attrs({ type: 'expression', dxfId: dxf(), priority })}><formula>${esc(\n formulaText(rename(rule.formula)),\n )}</formula></cfRule>`\n if ('top' in rule || 'bottom' in rule) {\n const rank = rule.top ?? rule.bottom ?? 10\n return `<cfRule${attrs({\n type: 'top10',\n dxfId: dxf(),\n priority,\n percent: rule.percent,\n bottom: rule.bottom != null,\n rank,\n })}/>`\n }\n if ('average' in rule)\n return `<cfRule${attrs({\n type: 'aboveAverage',\n dxfId: dxf(),\n priority,\n aboveAverage: rule.average === 'above' ? undefined : '0',\n })}/>`\n if ('duplicates' in rule)\n return `<cfRule${attrs({ type: 'duplicateValues', dxfId: dxf(), priority })}/>`\n if ('unique' in rule)\n return `<cfRule${attrs({ type: 'uniqueValues', dxfId: dxf(), priority })}/>`\n if ('scale' in rule) {\n const colors = rule.scale.map((c) => argb(toneColor(c, 32)) ?? 'FFFFFFFF')\n const points =\n colors.length === 3\n ? '<cfvo type=\"min\"/><cfvo type=\"percentile\" val=\"50\"/><cfvo type=\"max\"/>'\n : '<cfvo type=\"min\"/><cfvo type=\"max\"/>'\n return `<cfRule${attrs({ type: 'colorScale', priority })}><colorScale>${points}${colors\n .map((c) => `<color rgb=\"${c}\"/>`)\n .join('')}</colorScale></cfRule>`\n }\n if ('bar' in rule) {\n const color = argb(toneColor(rule.bar === true ? 'neutral' : rule.bar, 30)) ?? 'FF638EC6'\n return `<cfRule${attrs({ type: 'dataBar', priority })}><dataBar><cfvo type=\"min\"/><cfvo type=\"max\"/><color rgb=\"${color}\"/></dataBar></cfRule>`\n }\n return ''\n }\n\n // the workbook around the sheets\n const sheetsXML = sheetFiles\n .map((s, i) => `<sheet${attrs({ name: s.name, sheetId: i + 1, 'r:id': `rId${i + 1}` })}/>`)\n .join('')\n const defined = sheetFiles\n .map((s, i) =>\n s.filter\n ? `<definedName name=\"_xlnm._FilterDatabase\" localSheetId=\"${i}\" hidden=\"1\">${esc(\n `${quoteSheet(s.name)}!${absolute(s.filter)}`,\n )}</definedName>`\n : '',\n )\n .join('')\n entries.push({\n path: 'xl/workbook.xml',\n data:\n `${HEAD}<workbook xmlns=\"${NS}\" xmlns:r=\"${NS_R}\">` +\n (book.protect ? '<workbookProtection lockStructure=\"1\"/>' : '') +\n '<bookViews><workbookView activeTab=\"0\"/></bookViews>' +\n `<sheets>${sheetsXML}</sheets>` +\n (defined ? `<definedNames>${defined}</definedNames>` : '') +\n '<calcPr calcId=\"191029\" fullCalcOnLoad=\"1\"/>' +\n '</workbook>',\n })\n const count = sheetFiles.length\n entries.push({\n path: 'xl/_rels/workbook.xml.rels',\n data:\n `${HEAD}<Relationships xmlns=\"${NS_PKG}\">` +\n sheetFiles\n .map(\n (_, i) =>\n `<Relationship Id=\"rId${i + 1}\" Type=\"${NS_R}/worksheet\" Target=\"worksheets/sheet${i + 1}.xml\"/>`,\n )\n .join('') +\n `<Relationship Id=\"rId${count + 1}\" Type=\"${NS_R}/styles\" Target=\"styles.xml\"/>` +\n `<Relationship Id=\"rId${count + 2}\" Type=\"${NS_R}/sharedStrings\" Target=\"sharedStrings.xml\"/>` +\n '</Relationships>',\n })\n entries.push({ path: 'xl/styles.xml', data: styles.toXML() })\n entries.push({\n path: 'xl/sharedStrings.xml',\n data:\n `${HEAD}<sst xmlns=\"${NS}\" count=\"${stringCount}\" uniqueCount=\"${strings.length}\">` +\n strings\n .map(\n (t) => `<si><t${/^\\s|\\s$|\\n/.test(t) ? ' xml:space=\"preserve\"' : ''}>${esc(t)}</t></si>`,\n )\n .join('') +\n '</sst>',\n })\n entries.push({\n path: '_rels/.rels',\n data:\n `${HEAD}<Relationships xmlns=\"${NS_PKG}\">` +\n `<Relationship Id=\"rId1\" Type=\"${NS_R}/officeDocument\" Target=\"xl/workbook.xml\"/>` +\n '</Relationships>',\n })\n const hasNotes = entries.some((e) => e.path.startsWith('xl/comments'))\n entries.push({\n path: '[Content_Types].xml',\n data:\n `${HEAD}<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">` +\n '<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>' +\n '<Default Extension=\"xml\" ContentType=\"application/xml\"/>' +\n (hasNotes\n ? '<Default Extension=\"vml\" ContentType=\"application/vnd.openxmlformats-officedocument.vmlDrawing\"/>'\n : '') +\n '<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>' +\n sheetFiles\n .map(\n (_, i) =>\n `<Override PartName=\"/xl/worksheets/sheet${i + 1}.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>`,\n )\n .join('') +\n entries\n .filter((e) => e.path.startsWith('xl/comments'))\n .map(\n (e) =>\n `<Override PartName=\"/${e.path}\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml\"/>`,\n )\n .join('') +\n '<Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>' +\n '<Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\"/>' +\n '</Types>',\n })\n // the content types first, as some readers expect\n entries.unshift(entries.pop()!)\n source.signal?.throwIfAborted()\n return zip(entries, pacing)\n}\n\n/** The rows of a sheet's filter that its rules hide, as the grid hides them. */\nfunction filteredOut(source: SheetFileSource, index: number, data: SheetData, lastRow: number) {\n const out = new Set<number>()\n const parsed = data.filter?.columns && parseRange(data.filter.range)\n if (!parsed) return out\n const b = boundsOf(parsed)\n const rules = Object.entries(data.filter!.columns!)\n .map(([key, rule]) => ({ col: Number(key), rule }))\n .filter(({ col }) => col >= b.left && col <= b.right)\n const collator = textCollator(source.locale)\n for (let row = b.top + 1; row <= Math.min(b.bottom, lastRow); row++)\n for (const { col, rule } of rules) {\n const result = source.result(index, row, col)\n const value = isSheetError(result) ? result.code : result\n const text = value == null || value === '' ? '' : source.text(index, row, col)\n if (!meetsRule(rule, value, text, collator)) {\n out.add(row)\n break\n }\n }\n return out\n}\n\n/** A part of a sheet's protection as the file writes it: `0` for what people may still do. */\nconst kept = (allowed: boolean | undefined) => (allowed ? 0 : undefined)\n\n/**\n * A sheet's protection. In the file each part says what is kept from\n * people (`1`, the default for most), so what the sheet allows is `0`.\n */\nfunction protectionXML(protect: true | SheetProtection) {\n const allow = protect === true ? {} : protect\n return `<sheetProtection${attrs({\n sheet: 1,\n objects: 1,\n scenarios: 1,\n formatCells: kept(allow.formatCells),\n formatColumns: kept(allow.formatColumns),\n formatRows: kept(allow.formatRows),\n insertColumns: kept(allow.insertColumns),\n insertRows: kept(allow.insertRows),\n deleteColumns: kept(allow.deleteColumns),\n deleteRows: kept(allow.deleteRows),\n autoFilter: kept(allow.filter),\n })}/>`\n}\n\n/** Cell names, with runs down a column written as ranges. */\nfunction compactRefs(refs: string[]) {\n const byCol = new Map<string, number[]>()\n for (const ref of refs) {\n const [, col, row] = /^([A-Z]+)(\\d+)$/.exec(ref)!\n const list = byCol.get(col!) ?? []\n list.push(+row!)\n byCol.set(col!, list)\n }\n const out: string[] = []\n for (const [col, list] of byCol) {\n list.sort((a, b) => a - b)\n let start = list[0]!\n let prev = start\n for (const row of [...list.slice(1), Infinity]) {\n if (row === prev + 1) {\n prev = row\n continue\n }\n out.push(start === prev ? `${col}${start}` : `${col}${start}:${col}${prev}`)\n start = prev = row\n }\n }\n return out.join(' ')\n}\n\n/** A validation as the file writes it, `''` for one it can't hold. */\nfunction validationXML(rule: SheetValidation, rename: (formula: string) => string) {\n const common = {\n allowBlank: 1,\n showErrorMessage: 1,\n showInputMessage: rule.prompt ? 1 : undefined,\n errorStyle: rule.strict === false ? 'warning' : undefined,\n error: rule.message,\n prompt: rule.prompt,\n sqref: sqref(rule.range),\n }\n if ('list' in rule) {\n const list =\n typeof rule.list === 'string' ? formulaText(rename(rule.list)) : inlineList(rule.list)\n if (list == null || list.length > 255) return ''\n return `<dataValidation${attrs({ type: 'list', ...common })}>${body(list)}</dataValidation>`\n }\n if ('formula' in rule)\n return `<dataValidation${attrs({ type: 'custom', ...common })}>${body(formulaText(rename(rule.formula)))}</dataValidation>`\n const { op, value, to } = rule.when\n const operator = CELL_IS[op]\n const numeric = typeof value === 'number' || (typeof value === 'string' && !!dateFormat(value))\n if (operator && numeric) {\n const type = typeof value === 'string' ? 'date' : rule.integer ? 'whole' : 'decimal'\n const formulas =\n op === 'between' || op === 'notBetween' ? [literal(value), literal(to)] : [literal(value)]\n return `<dataValidation${attrs({ type, operator, ...common })}>${body(...formulas)}</dataValidation>`\n }\n // text conditions as a formula on the top left cell\n const anchor = anchorOf(rule.range)\n const quoted = literal(String(value ?? ''))\n const formula: Partial<Record<SheetCondition['op'], string>> = {\n eq: `EXACT(LOWER(${anchor}),LOWER(${quoted}))`,\n ne: `NOT(EXACT(LOWER(${anchor}),LOWER(${quoted})))`,\n contains: `NOT(ISERROR(SEARCH(${quoted},${anchor})))`,\n notContains: `ISERROR(SEARCH(${quoted},${anchor}))`,\n begins: `LEFT(LOWER(${anchor}),LEN(${quoted}))=LOWER(${quoted})`,\n ends: `RIGHT(LOWER(${anchor}),LEN(${quoted}))=LOWER(${quoted})`,\n notBlank: `LEN(TRIM(${anchor}))>0`,\n }\n const custom = formula[op]\n return custom\n ? `<dataValidation${attrs({ type: 'custom', ...common })}>${body(custom)}</dataValidation>`\n : ''\n}\n/** A validation's formulas. */\nconst body = (...formulas: string[]) =>\n formulas.map((f, i) => `<formula${i + 1}>${esc(f)}</formula${i + 1}>`).join('')\n\n/** One condition of a custom filter. */\nconst one = (operator: string | undefined, val: string) =>\n `<customFilter${attrs({ operator, val })}/>`\n\n/** A filter's condition as the file's custom filter, `''` when it has none. */\nfunction customFilter(condition: SheetCondition) {\n const value = condition.value == null ? '' : String(condition.value)\n switch (condition.op) {\n case 'eq':\n return `<customFilters>${one(undefined, value)}</customFilters>`\n case 'ne':\n return `<customFilters>${one('notEqual', value)}</customFilters>`\n case 'gt':\n return `<customFilters>${one('greaterThan', value)}</customFilters>`\n case 'ge':\n return `<customFilters>${one('greaterThanOrEqual', value)}</customFilters>`\n case 'lt':\n return `<customFilters>${one('lessThan', value)}</customFilters>`\n case 'le':\n return `<customFilters>${one('lessThanOrEqual', value)}</customFilters>`\n case 'between':\n return `<customFilters and=\"1\">${one('greaterThanOrEqual', value)}${one('lessThanOrEqual', String(condition.to ?? ''))}</customFilters>`\n case 'notBetween':\n return `<customFilters>${one('lessThan', value)}${one('greaterThan', String(condition.to ?? ''))}</customFilters>`\n case 'contains':\n return `<customFilters>${one(undefined, `*${value}*`)}</customFilters>`\n case 'notContains':\n return `<customFilters>${one('notEqual', `*${value}*`)}</customFilters>`\n case 'begins':\n return `<customFilters>${one(undefined, `${value}*`)}</customFilters>`\n case 'ends':\n return `<customFilters>${one(undefined, `*${value}`)}</customFilters>`\n case 'blank':\n return '<filters blank=\"1\"/>'\n case 'notBlank':\n return `<customFilters>${one('notEqual', ' ')}</customFilters>`\n default:\n return ''\n }\n}\n\nconst absolute = (range: string) =>\n range\n .replaceAll('$', '')\n .split(':')\n .map((ref) => ref.replace(/^([A-Z]+)(\\d+)$/, '$$$1$$$2'))\n .join(':')\n\n/** The notes of a sheet as the file's comments. */\nfunction commentsXML(notes: { ref: string; text: string }[]) {\n return (\n `${HEAD}<comments xmlns=\"${NS}\"><authors><author></author></authors><commentList>` +\n notes\n .map(\n (note) =>\n `<comment ref=\"${note.ref}\" authorId=\"0\"><text><t xml:space=\"preserve\">${esc(note.text)}</t></text></comment>`,\n )\n .join('') +\n '</commentList></comments>'\n )\n}\n\n/** The boxes notes show in, which other programs need to show them. */\nfunction vmlXML(notes: { row: number; col: number }[]) {\n return (\n '<xml xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\">' +\n '<o:shapelayout v:ext=\"edit\"><o:idmap v:ext=\"edit\" data=\"1\"/></o:shapelayout>' +\n '<v:shapetype id=\"_x0000_t202\" coordsize=\"21600,21600\" o:spt=\"202\" path=\"m,l,21600r21600,l21600,xe\"><v:stroke joinstyle=\"miter\"/><v:path gradientshapeok=\"t\" o:connecttype=\"rect\"/></v:shapetype>' +\n notes\n .map(\n (note, i) =>\n `<v:shape id=\"_x0000_s${1025 + i}\" type=\"#_x0000_t202\" style=\"position:absolute;margin-left:80pt;margin-top:2pt;width:120pt;height:60pt;z-index:${i + 1};visibility:hidden\" fillcolor=\"#ffffe1\" o:insetmode=\"auto\">` +\n '<v:fill color2=\"#ffffe1\"/><v:shadow on=\"t\" color=\"black\" obscured=\"t\"/><v:path o:connecttype=\"none\"/>' +\n '<v:textbox style=\"mso-direction-alt:auto\"><div style=\"text-align:left\"></div></v:textbox>' +\n `<x:ClientData ObjectType=\"Note\"><x:MoveWithCells/><x:SizeWithCells/><x:AutoFill>False</x:AutoFill><x:Row>${note.row}</x:Row><x:Column>${note.col}</x:Column></x:ClientData>` +\n '</v:shape>',\n )\n .join('') +\n '</xml>'\n )\n}\n"],"mappings":"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"}
|
package/dist/xml-read.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// src/xml-read.ts
|
|
2
|
+
var ENTITIES = {
|
|
3
|
+
lt: "<",
|
|
4
|
+
gt: ">",
|
|
5
|
+
amp: "&",
|
|
6
|
+
quot: "\"",
|
|
7
|
+
apos: "'"
|
|
8
|
+
};
|
|
9
|
+
/** Text with its entities, such as `&` and `中`, turned back into characters. */
|
|
10
|
+
function unescape(text) {
|
|
11
|
+
if (!text.includes("&")) return text;
|
|
12
|
+
return text.replace(/&(#x[0-9a-f]+|#\d+|\w+);/gi, (match, name) => {
|
|
13
|
+
if (name[0] !== "#") return ENTITIES[name] ?? match;
|
|
14
|
+
const code = name[1] === "x" || name[1] === "X" ? parseInt(name.slice(2), 16) : +name.slice(1);
|
|
15
|
+
return Number.isFinite(code) && code <= 1114111 ? String.fromCodePoint(code) : match;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/** An element's attributes by name, without their prefixes: `r:id` is `id`. */
|
|
19
|
+
function attrsOf(raw) {
|
|
20
|
+
const out = {};
|
|
21
|
+
const length = raw.length;
|
|
22
|
+
let at = 0;
|
|
23
|
+
while (at < length) {
|
|
24
|
+
if (raw.charCodeAt(at) <= 32) {
|
|
25
|
+
at++;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const eq = raw.indexOf("=", at);
|
|
29
|
+
if (eq === -1) break;
|
|
30
|
+
const name = raw.slice(at, eq).trim();
|
|
31
|
+
let start = eq + 1;
|
|
32
|
+
while (start < length && raw.charCodeAt(start) <= 32) start++;
|
|
33
|
+
const quote = raw[start];
|
|
34
|
+
if (quote !== "\"" && quote !== "'") break;
|
|
35
|
+
const end = raw.indexOf(quote, start + 1);
|
|
36
|
+
if (end === -1) break;
|
|
37
|
+
if (name !== "xmlns" && !name.startsWith("xmlns:")) {
|
|
38
|
+
const colon = name.indexOf(":");
|
|
39
|
+
out[colon === -1 ? name : name.slice(colon + 1)] = unescape(raw.slice(start + 1, end));
|
|
40
|
+
}
|
|
41
|
+
at = end + 1;
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
/** A yes-or-no attribute, which files write as `1` or `true`. */
|
|
46
|
+
var isOn = (value) => value === "1" || value === "true";
|
|
47
|
+
/** Whether a true-or-false attribute is off; one left out is neither. */
|
|
48
|
+
var isOff = (value) => value === "0" || value === "false";
|
|
49
|
+
/** An attribute that is on unless it says `0` or `false`. */
|
|
50
|
+
var isNotOff = (value) => value !== "0" && value !== "false";
|
|
51
|
+
/**
|
|
52
|
+
* Goes through XML text, telling `handler` what it meets. `step` reads up
|
|
53
|
+
* to `budget` tags and says whether there is more, so a big part can be
|
|
54
|
+
* read in pieces with pauses between.
|
|
55
|
+
*/
|
|
56
|
+
var XmlReader = class {
|
|
57
|
+
xml;
|
|
58
|
+
handler;
|
|
59
|
+
at = 0;
|
|
60
|
+
constructor(xml, handler) {
|
|
61
|
+
this.xml = xml;
|
|
62
|
+
this.handler = handler;
|
|
63
|
+
}
|
|
64
|
+
/** Reads on; `false` once the text is done. */
|
|
65
|
+
step(budget = Infinity) {
|
|
66
|
+
const { xml, handler } = this;
|
|
67
|
+
const length = xml.length;
|
|
68
|
+
let at = this.at;
|
|
69
|
+
for (let n = 0; n < budget; n++) {
|
|
70
|
+
const open = xml.indexOf("<", at);
|
|
71
|
+
if (open === -1) {
|
|
72
|
+
if (handler.text && at < length) handler.text(unescape(xml.slice(at)));
|
|
73
|
+
this.at = length;
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (handler.text && open > at) handler.text(unescape(xml.slice(at, open)));
|
|
77
|
+
const next = xml.charCodeAt(open + 1);
|
|
78
|
+
if (next === 33) {
|
|
79
|
+
if (xml.startsWith("<![CDATA[", open)) {
|
|
80
|
+
const end = xml.indexOf("]]>", open);
|
|
81
|
+
handler.text?.(xml.slice(open + 9, end === -1 ? length : end));
|
|
82
|
+
at = end === -1 ? length : end + 3;
|
|
83
|
+
} else if (xml.startsWith("<!--", open)) {
|
|
84
|
+
const end = xml.indexOf("-->", open);
|
|
85
|
+
at = end === -1 ? length : end + 3;
|
|
86
|
+
} else {
|
|
87
|
+
const end = xml.indexOf(">", open);
|
|
88
|
+
at = end === -1 ? length : end + 1;
|
|
89
|
+
}
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (next === 63) {
|
|
93
|
+
const end = xml.indexOf("?>", open);
|
|
94
|
+
at = end === -1 ? length : end + 2;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
let end = open + 1;
|
|
98
|
+
let quote = 0;
|
|
99
|
+
for (; end < length; end++) {
|
|
100
|
+
const char = xml.charCodeAt(end);
|
|
101
|
+
if (quote) {
|
|
102
|
+
if (char === quote) quote = 0;
|
|
103
|
+
} else if (char === 34 || char === 39) quote = char;
|
|
104
|
+
else if (char === 62) break;
|
|
105
|
+
}
|
|
106
|
+
const closing = next === 47;
|
|
107
|
+
const nameStart = closing ? open + 2 : open + 1;
|
|
108
|
+
let nameEnd = nameStart;
|
|
109
|
+
while (nameEnd < end) {
|
|
110
|
+
const char = xml.charCodeAt(nameEnd);
|
|
111
|
+
if (char <= 32 || char === 47) break;
|
|
112
|
+
nameEnd++;
|
|
113
|
+
}
|
|
114
|
+
let name = xml.slice(nameStart, nameEnd);
|
|
115
|
+
const colon = name.indexOf(":");
|
|
116
|
+
if (colon !== -1) name = name.slice(colon + 1);
|
|
117
|
+
if (closing) handler.close?.(name);
|
|
118
|
+
else {
|
|
119
|
+
const empty = xml.charCodeAt(end - 1) === 47;
|
|
120
|
+
handler.open(name, xml.slice(nameEnd, empty ? end - 1 : end), empty);
|
|
121
|
+
if (empty) handler.close?.(name);
|
|
122
|
+
}
|
|
123
|
+
at = end + 1;
|
|
124
|
+
}
|
|
125
|
+
this.at = at;
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
/** Reads a small part, such as the workbook or the styles, as a tree. */
|
|
130
|
+
function parseXml(xml) {
|
|
131
|
+
const root = {
|
|
132
|
+
name: "",
|
|
133
|
+
attrs: {},
|
|
134
|
+
children: [],
|
|
135
|
+
text: ""
|
|
136
|
+
};
|
|
137
|
+
const stack = [root];
|
|
138
|
+
new XmlReader(xml, {
|
|
139
|
+
open(name, raw) {
|
|
140
|
+
const node = {
|
|
141
|
+
name,
|
|
142
|
+
attrs: attrsOf(raw),
|
|
143
|
+
children: [],
|
|
144
|
+
text: ""
|
|
145
|
+
};
|
|
146
|
+
stack.at(-1).children.push(node);
|
|
147
|
+
stack.push(node);
|
|
148
|
+
},
|
|
149
|
+
close() {
|
|
150
|
+
const node = stack.pop();
|
|
151
|
+
if (stack.length) stack.at(-1).text += node.text;
|
|
152
|
+
else stack.push(node);
|
|
153
|
+
},
|
|
154
|
+
text(text) {
|
|
155
|
+
stack.at(-1).text += text;
|
|
156
|
+
}
|
|
157
|
+
}).step();
|
|
158
|
+
return root.children[0] ?? root;
|
|
159
|
+
}
|
|
160
|
+
/** The children of a node with this name. */
|
|
161
|
+
var childrenOf = (node, name) => node ? node.children.filter((child) => child.name === name) : [];
|
|
162
|
+
/** The first child of a node with this name. */
|
|
163
|
+
var childOf = (node, name) => node?.children.find((child) => child.name === name);
|
|
164
|
+
export { XmlReader, attrsOf, childOf, childrenOf, isNotOff, isOff, isOn, parseXml, unescape };
|
|
165
|
+
|
|
166
|
+
//# sourceMappingURL=xml-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-read.js","names":[],"sources":["../src/xml-read.ts"],"sourcesContent":["/*\n * A small XML reader, enough for the parts of an .xlsx file. It doesn't\n * need `DOMParser`, which Workers don't have, and it goes through a big\n * sheet a piece at a time.\n */\n\nconst ENTITIES: Record<string, string> = { lt: '<', gt: '>', amp: '&', quot: '\"', apos: \"'\" }\n\n/** Text with its entities, such as `&` and `中`, turned back into characters. */\nexport function unescape(text: string) {\n if (!text.includes('&')) return text\n return text.replace(/&(#x[0-9a-f]+|#\\d+|\\w+);/gi, (match, name: string) => {\n if (name[0] !== '#') return ENTITIES[name] ?? match\n const code = name[1] === 'x' || name[1] === 'X' ? parseInt(name.slice(2), 16) : +name.slice(1)\n return Number.isFinite(code) && code <= 0x10ffff ? String.fromCodePoint(code) : match\n })\n}\n\n/** An element's attributes by name, without their prefixes: `r:id` is `id`. */\nexport function attrsOf(raw: string) {\n const out: Record<string, string> = {}\n const length = raw.length\n let at = 0\n while (at < length) {\n if (raw.charCodeAt(at) <= 32) {\n at++\n continue\n }\n const eq = raw.indexOf('=', at)\n if (eq === -1) break\n const name = raw.slice(at, eq).trim()\n let start = eq + 1\n while (start < length && raw.charCodeAt(start) <= 32) start++\n const quote = raw[start]\n if (quote !== '\"' && quote !== \"'\") break\n const end = raw.indexOf(quote, start + 1)\n if (end === -1) break\n // namespace declarations aren't attributes of the content\n if (name !== 'xmlns' && !name.startsWith('xmlns:')) {\n const colon = name.indexOf(':')\n out[colon === -1 ? name : name.slice(colon + 1)] = unescape(raw.slice(start + 1, end))\n }\n at = end + 1\n }\n return out\n}\n\n/** A yes-or-no attribute, which files write as `1` or `true`. */\nexport const isOn = (value: string | undefined) => value === '1' || value === 'true'\n/** Whether a true-or-false attribute is off; one left out is neither. */\nexport const isOff = (value: string | undefined) => value === '0' || value === 'false'\n\n/** An attribute that is on unless it says `0` or `false`. */\nexport const isNotOff = (value: string | undefined) => value !== '0' && value !== 'false'\n\n/** What a reader is told as it goes through the text. */\nexport interface XmlHandler {\n /** An element starts; `empty` when it ends there too, as `<a/>`. Names are without prefixes. */\n open(name: string, attrs: string, empty: boolean): void\n close?(name: string): void\n /** Text between elements, its entities already turned back. */\n text?(text: string): void\n}\n\n/**\n * Goes through XML text, telling `handler` what it meets. `step` reads up\n * to `budget` tags and says whether there is more, so a big part can be\n * read in pieces with pauses between.\n */\nexport class XmlReader {\n private at = 0\n\n constructor(\n private readonly xml: string,\n private readonly handler: XmlHandler,\n ) {}\n\n /** Reads on; `false` once the text is done. */\n step(budget = Infinity) {\n const { xml, handler } = this\n const length = xml.length\n let at = this.at\n for (let n = 0; n < budget; n++) {\n const open = xml.indexOf('<', at)\n if (open === -1) {\n if (handler.text && at < length) handler.text(unescape(xml.slice(at)))\n this.at = length\n return false\n }\n if (handler.text && open > at) handler.text(unescape(xml.slice(at, open)))\n const next = xml.charCodeAt(open + 1)\n // a comment, a CDATA section or a doctype\n if (next === 33) {\n if (xml.startsWith('<![CDATA[', open)) {\n const end = xml.indexOf(']]>', open)\n handler.text?.(xml.slice(open + 9, end === -1 ? length : end))\n at = end === -1 ? length : end + 3\n } else if (xml.startsWith('<!--', open)) {\n const end = xml.indexOf('-->', open)\n at = end === -1 ? length : end + 3\n } else {\n const end = xml.indexOf('>', open)\n at = end === -1 ? length : end + 1\n }\n continue\n }\n // a declaration, such as `<?xml …?>`\n if (next === 63) {\n const end = xml.indexOf('?>', open)\n at = end === -1 ? length : end + 2\n continue\n }\n // the tag's end, past any `>` in a quoted attribute\n let end = open + 1\n let quote = 0\n for (; end < length; end++) {\n const char = xml.charCodeAt(end)\n if (quote) {\n if (char === quote) quote = 0\n } else if (char === 34 || char === 39) quote = char\n else if (char === 62) break\n }\n const closing = next === 47\n const nameStart = closing ? open + 2 : open + 1\n let nameEnd = nameStart\n while (nameEnd < end) {\n const char = xml.charCodeAt(nameEnd)\n if (char <= 32 || char === 47) break\n nameEnd++\n }\n let name = xml.slice(nameStart, nameEnd)\n const colon = name.indexOf(':')\n if (colon !== -1) name = name.slice(colon + 1)\n if (closing) handler.close?.(name)\n else {\n const empty = xml.charCodeAt(end - 1) === 47\n handler.open(name, xml.slice(nameEnd, empty ? end - 1 : end), empty)\n if (empty) handler.close?.(name)\n }\n at = end + 1\n }\n this.at = at\n return true\n }\n}\n\n/** An element of a small part, read whole. */\nexport interface XmlNode {\n name: string\n attrs: Record<string, string>\n children: XmlNode[]\n /** The text inside it, its children's included. */\n text: string\n}\n\n/** Reads a small part, such as the workbook or the styles, as a tree. */\nexport function parseXml(xml: string): XmlNode {\n const root: XmlNode = { name: '', attrs: {}, children: [], text: '' }\n const stack = [root]\n new XmlReader(xml, {\n open(name, raw) {\n const node: XmlNode = { name, attrs: attrsOf(raw), children: [], text: '' }\n stack.at(-1)!.children.push(node)\n stack.push(node)\n },\n close() {\n const node = stack.pop()!\n if (stack.length) stack.at(-1)!.text += node.text\n else stack.push(node)\n },\n text(text) {\n stack.at(-1)!.text += text\n },\n }).step()\n return root.children[0] ?? root\n}\n\n/** The children of a node with this name. */\nexport const childrenOf = (node: XmlNode | undefined, name: string) =>\n node ? node.children.filter((child) => child.name === name) : []\n\n/** The first child of a node with this name. */\nexport const childOf = (node: XmlNode | undefined, name: string) =>\n node?.children.find((child) => child.name === name)\n"],"mappings":"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"}
|
package/dist/xml.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// src/xml.ts
|
|
2
|
+
var INVALID = /[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g;
|
|
3
|
+
/** Text for an XML element's content or attribute. */
|
|
4
|
+
var esc = (text) => text.replace(INVALID, "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5
|
+
/** Attributes, leaving out the ones without a value. */
|
|
6
|
+
function attrs(list) {
|
|
7
|
+
let out = "";
|
|
8
|
+
for (const [name, value] of Object.entries(list)) {
|
|
9
|
+
if (value == null || value === false) continue;
|
|
10
|
+
out += ` ${name}="${value === true ? 1 : esc(String(value))}"`;
|
|
11
|
+
}
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
var HEAD = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
|
|
15
|
+
var NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
|
|
16
|
+
var NS_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
17
|
+
var NS_PKG = "http://schemas.openxmlformats.org/package/2006/relationships";
|
|
18
|
+
export { HEAD, NS, NS_PKG, NS_R, attrs, esc };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=xml.js.map
|
package/dist/xml.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml.js","names":[],"sources":["../src/xml.ts"],"sourcesContent":["// characters XML 1.0 can't hold, even escaped\n// oxlint-disable-next-line no-control-regex\nconst INVALID = /[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F]/g\n\n/** Text for an XML element's content or attribute. */\nexport const esc = (text: string) =>\n text\n .replace(INVALID, '')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n\n/** Attributes, leaving out the ones without a value. */\nexport function attrs(list: Record<string, string | number | boolean | undefined | null>) {\n let out = ''\n for (const [name, value] of Object.entries(list)) {\n if (value == null || value === false) continue\n out += ` ${name}=\"${value === true ? 1 : esc(String(value))}\"`\n }\n return out\n}\n\nexport const HEAD = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n'\n\nexport const NS = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'\nexport const NS_R = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'\nexport const NS_PKG = 'http://schemas.openxmlformats.org/package/2006/relationships'\n"],"mappings":";AAEA,IAAM,UAAU;;AAGhB,IAAa,OAAO,SAClB,KACG,QAAQ,SAAS,EAAE,CAAC,CACpB,QAAQ,MAAM,OAAO,CAAC,CACtB,QAAQ,MAAM,MAAM,CAAC,CACrB,QAAQ,MAAM,MAAM,CAAC,CACrB,QAAQ,MAAM,QAAQ;;AAG3B,SAAgB,MAAM,MAAoE;CACxF,IAAI,MAAM;CACV,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,IAAI,GAAG;EAChD,IAAI,SAAS,QAAQ,UAAU,OAAO;EACtC,OAAO,IAAI,KAAK,IAAI,UAAU,OAAO,IAAI,IAAI,OAAO,KAAK,CAAC,EAAE;CAC9D;CACA,OAAO;AACT;AAEA,IAAa,OAAO;AAEpB,IAAa,KAAK;AAClB,IAAa,OAAO;AACpB,IAAa,SAAS"}
|
package/dist/zip.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// src/zip.ts
|
|
2
|
+
var encoder = new TextEncoder();
|
|
3
|
+
/** Lets the page handle what is waiting, such as input, before going on. */
|
|
4
|
+
var pause = () => new Promise((resolve) => setTimeout(resolve));
|
|
5
|
+
/** What `zip` and `unzip` need of the platform, checked so the error says so. */
|
|
6
|
+
function streams() {
|
|
7
|
+
if (typeof CompressionStream !== "function" || typeof DecompressionStream !== "function") throw new Error("[@dou-ui/sheet-xlsx] needs CompressionStream (browsers since 2023, Node 18, Bun, Deno) to write and read .xlsx files");
|
|
8
|
+
}
|
|
9
|
+
/** The bytes the stream's other end gives. */
|
|
10
|
+
async function collect(readable) {
|
|
11
|
+
const pieces = [];
|
|
12
|
+
let size = 0;
|
|
13
|
+
const reader = readable.getReader();
|
|
14
|
+
for (;;) {
|
|
15
|
+
const { done, value } = await reader.read();
|
|
16
|
+
if (done) break;
|
|
17
|
+
pieces.push(value);
|
|
18
|
+
size += value.length;
|
|
19
|
+
}
|
|
20
|
+
const out = new Uint8Array(size);
|
|
21
|
+
let at = 0;
|
|
22
|
+
for (const piece of pieces) {
|
|
23
|
+
out.set(piece, at);
|
|
24
|
+
at += piece.length;
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
var PIECE = 1 << 18;
|
|
29
|
+
/** Bytes through a compressor or decompressor, a piece at a time, letting the page go on between pieces. */
|
|
30
|
+
async function through(bytes, stream, pacing) {
|
|
31
|
+
const result = collect(stream.readable);
|
|
32
|
+
const writer = stream.writable.getWriter();
|
|
33
|
+
try {
|
|
34
|
+
for (const bytesPiece of bytes) for (let at = 0; at < bytesPiece.length; at += PIECE) {
|
|
35
|
+
await writer.write(bytesPiece.subarray(at, at + PIECE));
|
|
36
|
+
if (pacing && performance.now() - pacing.lastPause.at > 50) {
|
|
37
|
+
await pause();
|
|
38
|
+
pacing.signal?.throwIfAborted();
|
|
39
|
+
pacing.lastPause.at = performance.now();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
await writer.close();
|
|
43
|
+
} catch (error) {
|
|
44
|
+
await writer.abort(error).catch(() => {});
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
/** The deflated bytes of a gzip stream, with the CRC-32 and size of what went in. */
|
|
50
|
+
function fromGzip(gz) {
|
|
51
|
+
if (gz[0] !== 31 || gz[1] !== 139) throw new Error("[@dou-ui/sheet-xlsx] not a gzip stream");
|
|
52
|
+
const flags = gz[3];
|
|
53
|
+
let at = 10;
|
|
54
|
+
if (flags & 4) at += 2 + (gz[at] | gz[at + 1] << 8);
|
|
55
|
+
if (flags & 8) while (gz[at++] !== 0);
|
|
56
|
+
if (flags & 16) while (gz[at++] !== 0);
|
|
57
|
+
if (flags & 2) at += 2;
|
|
58
|
+
const view = new DataView(gz.buffer, gz.byteOffset, gz.byteLength);
|
|
59
|
+
return {
|
|
60
|
+
packed: gz.subarray(at, gz.length - 8),
|
|
61
|
+
crc: view.getUint32(gz.length - 8, true),
|
|
62
|
+
length: view.getUint32(gz.length - 4, true)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Packs files into a zip, compressed. The files' times are left at the
|
|
67
|
+
* zip format's first day, so the same files give the same bytes.
|
|
68
|
+
*/
|
|
69
|
+
async function zip(entries, pacing) {
|
|
70
|
+
streams();
|
|
71
|
+
const parts = [];
|
|
72
|
+
const central = [];
|
|
73
|
+
let offset = 0;
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
const name = encoder.encode(entry.path);
|
|
76
|
+
const { packed, crc, length } = fromGzip(await through(typeof entry.data === "string" ? [encoder.encode(entry.data)] : Array.isArray(entry.data) ? entry.data : [entry.data], new CompressionStream("gzip"), pacing));
|
|
77
|
+
const time = 0;
|
|
78
|
+
const date = 33;
|
|
79
|
+
const local = /* @__PURE__ */ new DataView(/* @__PURE__ */ new ArrayBuffer(30));
|
|
80
|
+
local.setUint32(0, 67324752, true);
|
|
81
|
+
local.setUint16(4, 20, true);
|
|
82
|
+
local.setUint16(6, 2048, true);
|
|
83
|
+
local.setUint16(8, 8, true);
|
|
84
|
+
local.setUint16(10, time, true);
|
|
85
|
+
local.setUint16(12, date, true);
|
|
86
|
+
local.setUint32(14, crc, true);
|
|
87
|
+
local.setUint32(18, packed.length, true);
|
|
88
|
+
local.setUint32(22, length, true);
|
|
89
|
+
local.setUint16(26, name.length, true);
|
|
90
|
+
local.setUint16(28, 0, true);
|
|
91
|
+
parts.push(new Uint8Array(local.buffer), name, packed);
|
|
92
|
+
const head = /* @__PURE__ */ new DataView(/* @__PURE__ */ new ArrayBuffer(46));
|
|
93
|
+
head.setUint32(0, 33639248, true);
|
|
94
|
+
head.setUint16(4, 20, true);
|
|
95
|
+
head.setUint16(6, 20, true);
|
|
96
|
+
head.setUint16(8, 2048, true);
|
|
97
|
+
head.setUint16(10, 8, true);
|
|
98
|
+
head.setUint16(12, time, true);
|
|
99
|
+
head.setUint16(14, date, true);
|
|
100
|
+
head.setUint32(16, crc, true);
|
|
101
|
+
head.setUint32(20, packed.length, true);
|
|
102
|
+
head.setUint32(24, length, true);
|
|
103
|
+
head.setUint16(28, name.length, true);
|
|
104
|
+
head.setUint32(42, offset, true);
|
|
105
|
+
central.push(new Uint8Array(head.buffer), name);
|
|
106
|
+
offset += 30 + name.length + packed.length;
|
|
107
|
+
}
|
|
108
|
+
const size = central.reduce((total, part) => total + part.length, 0);
|
|
109
|
+
const end = /* @__PURE__ */ new DataView(/* @__PURE__ */ new ArrayBuffer(22));
|
|
110
|
+
end.setUint32(0, 101010256, true);
|
|
111
|
+
end.setUint16(8, entries.length, true);
|
|
112
|
+
end.setUint16(10, entries.length, true);
|
|
113
|
+
end.setUint32(12, size, true);
|
|
114
|
+
end.setUint32(16, offset, true);
|
|
115
|
+
const all = [
|
|
116
|
+
...parts,
|
|
117
|
+
...central,
|
|
118
|
+
new Uint8Array(end.buffer)
|
|
119
|
+
];
|
|
120
|
+
const out = new Uint8Array(all.reduce((total, part) => total + part.length, 0));
|
|
121
|
+
let at = 0;
|
|
122
|
+
for (const part of all) {
|
|
123
|
+
out.set(part, at);
|
|
124
|
+
at += part.length;
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
/** The files of a zip, by path, each read when asked for. Only stored and deflated files, as .xlsx files have. */
|
|
129
|
+
function zipFiles(bytes) {
|
|
130
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
131
|
+
let end = -1;
|
|
132
|
+
for (let i = bytes.length - 22; i >= Math.max(0, bytes.length - 22 - 65535); i--) if (view.getUint32(i, true) === 101010256) {
|
|
133
|
+
end = i;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
if (end === -1) throw new Error("[@dou-ui/sheet-xlsx] the file isn't a zip, so it isn't an .xlsx file");
|
|
137
|
+
const count = view.getUint16(end + 10, true);
|
|
138
|
+
let at = view.getUint32(end + 16, true);
|
|
139
|
+
const files = /* @__PURE__ */ new Map();
|
|
140
|
+
const decoder = new TextDecoder();
|
|
141
|
+
for (let n = 0; n < count; n++) {
|
|
142
|
+
if (at + 46 > bytes.length || view.getUint32(at, true) !== 33639248) throw new Error("[@dou-ui/sheet-xlsx] the zip is damaged");
|
|
143
|
+
const method = view.getUint16(at + 10, true);
|
|
144
|
+
const packedSize = view.getUint32(at + 20, true);
|
|
145
|
+
const nameLength = view.getUint16(at + 28, true);
|
|
146
|
+
const extraLength = view.getUint16(at + 30, true);
|
|
147
|
+
const commentLength = view.getUint16(at + 32, true);
|
|
148
|
+
const local = view.getUint32(at + 42, true);
|
|
149
|
+
const path = decoder.decode(bytes.subarray(at + 46, at + 46 + nameLength));
|
|
150
|
+
at += 46 + nameLength + extraLength + commentLength;
|
|
151
|
+
if (local + 30 > bytes.length) throw new Error("[@dou-ui/sheet-xlsx] the zip is damaged");
|
|
152
|
+
const start = local + 30 + view.getUint16(local + 26, true) + view.getUint16(local + 28, true);
|
|
153
|
+
const packed = bytes.subarray(start, start + packedSize);
|
|
154
|
+
files.set(path, {
|
|
155
|
+
path,
|
|
156
|
+
async read(pacing) {
|
|
157
|
+
if (method === 0) return packed.slice();
|
|
158
|
+
if (method !== 8) throw new Error(`[@dou-ui/sheet-xlsx] "${path}" is packed in a way that can't be read`);
|
|
159
|
+
streams();
|
|
160
|
+
return through([packed], new DecompressionStream("deflate-raw"), pacing);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return files;
|
|
165
|
+
}
|
|
166
|
+
export { pause, zip, zipFiles };
|
|
167
|
+
|
|
168
|
+
//# sourceMappingURL=zip.js.map
|
package/dist/zip.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip.js","names":[],"sources":["../src/zip.ts"],"sourcesContent":["/*\n * A small zip writer and reader, enough for the parts of an .xlsx file.\n * Compression uses the platform's `CompressionStream`, which browsers,\n * Bun and Node all have.\n */\n\nconst encoder = new TextEncoder()\n\n/** Lets the page handle what is waiting, such as input, before going on. */\nexport const pause = () => new Promise<void>((resolve) => setTimeout(resolve))\n\n/** How long work goes on before letting the page go on, in ms. */\nexport const SLICE = 50\n\n/** What `zip` and `unzip` need of the platform, checked so the error says so. */\nfunction streams() {\n if (typeof CompressionStream !== 'function' || typeof DecompressionStream !== 'function')\n throw new Error(\n '[@dou-ui/sheet-xlsx] needs CompressionStream (browsers since 2023, Node 18, Bun, Deno) to write and read .xlsx files',\n )\n}\n\n/** The bytes the stream's other end gives. */\nasync function collect(readable: ReadableStream<Uint8Array>) {\n const pieces: Uint8Array[] = []\n let size = 0\n const reader = readable.getReader()\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n pieces.push(value)\n size += value.length\n }\n const out = new Uint8Array(size)\n let at = 0\n for (const piece of pieces) {\n out.set(piece, at)\n at += piece.length\n }\n return out\n}\n\n/** How `zip` goes on with a big file: when to let the page go on, and when to stop. */\nexport interface ZipPacing {\n signal?: AbortSignal\n /** When work last let the page go on, from `performance.now()`; kept up to date. */\n lastPause: { at: number }\n}\n\n// a file goes through the compressor this much at a time, so the page can go on in between\nconst PIECE = 1 << 18\n\n/** Bytes through a compressor or decompressor, a piece at a time, letting the page go on between pieces. */\nasync function through(\n bytes: Uint8Array[],\n stream: CompressionStream | DecompressionStream,\n pacing?: ZipPacing,\n) {\n const result = collect(stream.readable)\n const writer = stream.writable.getWriter()\n try {\n for (const bytesPiece of bytes)\n for (let at = 0; at < bytesPiece.length; at += PIECE) {\n await writer.write(bytesPiece.subarray(at, at + PIECE) as Uint8Array<ArrayBuffer>)\n if (pacing && performance.now() - pacing.lastPause.at > SLICE) {\n await pause()\n pacing.signal?.throwIfAborted()\n pacing.lastPause.at = performance.now()\n }\n }\n await writer.close()\n } catch (error) {\n await writer.abort(error).catch(() => {})\n throw error\n }\n return result\n}\n\n/** The deflated bytes of a gzip stream, with the CRC-32 and size of what went in. */\nfunction fromGzip(gz: Uint8Array) {\n if (gz[0] !== 0x1f || gz[1] !== 0x8b) throw new Error('[@dou-ui/sheet-xlsx] not a gzip stream')\n const flags = gz[3]!\n let at = 10\n if (flags & 4) at += 2 + (gz[at]! | (gz[at + 1]! << 8))\n if (flags & 8) while (gz[at++] !== 0);\n if (flags & 16) while (gz[at++] !== 0);\n if (flags & 2) at += 2\n const view = new DataView(gz.buffer, gz.byteOffset, gz.byteLength)\n return {\n packed: gz.subarray(at, gz.length - 8),\n crc: view.getUint32(gz.length - 8, true),\n length: view.getUint32(gz.length - 4, true),\n }\n}\n\n/** A file to put in a zip: its path, and its text or bytes, whole or in pieces. */\nexport interface ZipEntry {\n path: string\n data: string | Uint8Array | Uint8Array[]\n}\n\n/**\n * Packs files into a zip, compressed. The files' times are left at the\n * zip format's first day, so the same files give the same bytes.\n */\nexport async function zip(entries: readonly ZipEntry[], pacing?: ZipPacing): Promise<Uint8Array> {\n streams()\n const parts: Uint8Array[] = []\n const central: Uint8Array[] = []\n let offset = 0\n for (const entry of entries) {\n const name = encoder.encode(entry.path)\n const raw =\n typeof entry.data === 'string'\n ? [encoder.encode(entry.data)]\n : Array.isArray(entry.data)\n ? entry.data\n : [entry.data]\n // gzip is deflate with the CRC-32 and size after it, worked out by the platform\n const { packed, crc, length } = fromGzip(\n await through(raw, new CompressionStream('gzip'), pacing),\n )\n // DOS date 1980-01-01, time 00:00\n const time = 0\n const date = (0 << 9) | (1 << 5) | 1\n const local = new DataView(new ArrayBuffer(30))\n local.setUint32(0, 0x04034b50, true)\n local.setUint16(4, 20, true)\n local.setUint16(6, 0x0800, true) // names in UTF-8\n local.setUint16(8, 8, true) // deflate\n local.setUint16(10, time, true)\n local.setUint16(12, date, true)\n local.setUint32(14, crc, true)\n local.setUint32(18, packed.length, true)\n local.setUint32(22, length, true)\n local.setUint16(26, name.length, true)\n local.setUint16(28, 0, true)\n parts.push(new Uint8Array(local.buffer), name, packed)\n\n const head = new DataView(new ArrayBuffer(46))\n head.setUint32(0, 0x02014b50, true)\n head.setUint16(4, 20, true)\n head.setUint16(6, 20, true)\n head.setUint16(8, 0x0800, true)\n head.setUint16(10, 8, true)\n head.setUint16(12, time, true)\n head.setUint16(14, date, true)\n head.setUint32(16, crc, true)\n head.setUint32(20, packed.length, true)\n head.setUint32(24, length, true)\n head.setUint16(28, name.length, true)\n head.setUint32(42, offset, true)\n central.push(new Uint8Array(head.buffer), name)\n offset += 30 + name.length + packed.length\n }\n const size = central.reduce((total, part) => total + part.length, 0)\n const end = new DataView(new ArrayBuffer(22))\n end.setUint32(0, 0x06054b50, true)\n end.setUint16(8, entries.length, true)\n end.setUint16(10, entries.length, true)\n end.setUint32(12, size, true)\n end.setUint32(16, offset, true)\n const all = [...parts, ...central, new Uint8Array(end.buffer)]\n const out = new Uint8Array(all.reduce((total, part) => total + part.length, 0))\n let at = 0\n for (const part of all) {\n out.set(part, at)\n at += part.length\n }\n return out\n}\n\n/** A file in a zip, as its directory lists it. */\nexport interface ZipFile {\n path: string\n /** Read it: its bytes, unpacked. */\n read(pacing?: ZipPacing): Promise<Uint8Array>\n}\n\n/** The files of a zip, by path, each read when asked for. Only stored and deflated files, as .xlsx files have. */\nexport function zipFiles(bytes: Uint8Array): Map<string, ZipFile> {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n let end = -1\n for (let i = bytes.length - 22; i >= Math.max(0, bytes.length - 22 - 65_535); i--)\n if (view.getUint32(i, true) === 0x06054b50) {\n end = i\n break\n }\n if (end === -1)\n throw new Error(\"[@dou-ui/sheet-xlsx] the file isn't a zip, so it isn't an .xlsx file\")\n const count = view.getUint16(end + 10, true)\n let at = view.getUint32(end + 16, true)\n const files = new Map<string, ZipFile>()\n const decoder = new TextDecoder()\n for (let n = 0; n < count; n++) {\n if (at + 46 > bytes.length || view.getUint32(at, true) !== 0x02014b50)\n throw new Error('[@dou-ui/sheet-xlsx] the zip is damaged')\n const method = view.getUint16(at + 10, true)\n const packedSize = view.getUint32(at + 20, true)\n const nameLength = view.getUint16(at + 28, true)\n const extraLength = view.getUint16(at + 30, true)\n const commentLength = view.getUint16(at + 32, true)\n const local = view.getUint32(at + 42, true)\n const path = decoder.decode(bytes.subarray(at + 46, at + 46 + nameLength))\n at += 46 + nameLength + extraLength + commentLength\n if (local + 30 > bytes.length) throw new Error('[@dou-ui/sheet-xlsx] the zip is damaged')\n const start = local + 30 + view.getUint16(local + 26, true) + view.getUint16(local + 28, true)\n const packed = bytes.subarray(start, start + packedSize)\n files.set(path, {\n path,\n async read(pacing) {\n if (method === 0) return packed.slice()\n if (method !== 8)\n throw new Error(`[@dou-ui/sheet-xlsx] \"${path}\" is packed in a way that can't be read`)\n streams()\n return through([packed], new DecompressionStream('deflate-raw'), pacing)\n },\n })\n }\n return files\n}\n\n/** Reads all the files of a zip, by path. */\nexport async function unzip(bytes: Uint8Array): Promise<Map<string, Uint8Array>> {\n streams()\n const out = new Map<string, Uint8Array>()\n for (const [path, file] of zipFiles(bytes)) out.set(path, await file.read())\n return out\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dou-ui/sheet-xlsx",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "DouUI 电子表格的 .xlsx 导入导出,不依赖第三方库",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"vue",
|
|
7
|
+
"spreadsheet",
|
|
8
|
+
"xlsx",
|
|
9
|
+
"excel",
|
|
10
|
+
"export",
|
|
11
|
+
"import"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": "daidr <daidr@daidr.me>",
|
|
15
|
+
"homepage": "https://github.com/daidr/dou-ui#readme",
|
|
16
|
+
"bugs": "https://github.com/daidr/dou-ui/issues",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/daidr/dou-ui.git",
|
|
20
|
+
"directory": "packages/sheet-xlsx"
|
|
21
|
+
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"module": "./dist/index.js",
|
|
26
|
+
"types": "./dist/types/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/types/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./package.json": "./package.json"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "vite build && vue-tsc -p tsconfig.build.json"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"@dou-ui/sheet": "0.1.0-alpha.1"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
}
|
|
46
|
+
}
|