@xlsxflow/core 1.1.0 → 1.1.2
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/CHANGELOG.md +19 -0
- package/README.md +4 -4
- package/dist/index.cjs +90 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.mjs +90 -45
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
package/dist/index.d.cts
CHANGED
|
@@ -579,6 +579,28 @@ declare class CfbReader {
|
|
|
579
579
|
read(path: string): Uint8Array | undefined;
|
|
580
580
|
}
|
|
581
581
|
|
|
582
|
+
declare class StylePatcher {
|
|
583
|
+
private xml;
|
|
584
|
+
private p;
|
|
585
|
+
private fonts;
|
|
586
|
+
private fills;
|
|
587
|
+
private borders;
|
|
588
|
+
private xfs;
|
|
589
|
+
private numFmts;
|
|
590
|
+
private nextNumFmt;
|
|
591
|
+
private added;
|
|
592
|
+
private memo;
|
|
593
|
+
constructor(xml: string);
|
|
594
|
+
get changed(): boolean;
|
|
595
|
+
patch(base: number, style: CellStyle): number;
|
|
596
|
+
dateFormat(base: number, d: Date): number;
|
|
597
|
+
toXml(): string;
|
|
598
|
+
private existing;
|
|
599
|
+
private add;
|
|
600
|
+
private items;
|
|
601
|
+
private prefix;
|
|
602
|
+
}
|
|
603
|
+
|
|
582
604
|
type Placement = {
|
|
583
605
|
range: string;
|
|
584
606
|
} | {
|
|
@@ -597,5 +619,5 @@ declare const XlsxFlow: {
|
|
|
597
619
|
readFile(filePath: string, options?: ParseOptions): Promise<ParseResult>;
|
|
598
620
|
};
|
|
599
621
|
|
|
600
|
-
export { CfbReader, ConditionalFormatter, DRAWING_NS, FormulaEngine, OdsWriter, SheetEditor, SheetReader, SheetWriter, StyleEngine, XlsxFlow, ZipRandomAccessParser, ZipStreamWriter, anchorXml, colIndex, colLetter, crc32, createBlobReader, createFileReader, createXmlStreamParser, dateToSerial, decodeXString, drawingPartXml, encodeXString, isCfb, legacyPasswordHash, mapFormulaRefs, parseCsv, parseWorksheet, partRelationships, readSharedStrings, recalcOnOpen, resolveWorkbookParts, sheetToJson, shiftFormula, streamToCsv };
|
|
622
|
+
export { CfbReader, ConditionalFormatter, DRAWING_NS, FormulaEngine, OdsWriter, SheetEditor, SheetReader, SheetWriter, StyleEngine, StylePatcher, XlsxFlow, ZipRandomAccessParser, ZipStreamWriter, anchorXml, colIndex, colLetter, crc32, createBlobReader, createFileReader, createXmlStreamParser, dateToSerial, decodeXString, drawingPartXml, encodeXString, isCfb, legacyPasswordHash, mapFormulaRefs, parseCsv, parseWorksheet, partRelationships, readSharedStrings, recalcOnOpen, resolveWorkbookParts, sheetToJson, shiftFormula, streamToCsv };
|
|
601
623
|
export type { BorderSide, CellAlignment, CellBorder, CellComment, CellEdit, CellFill, CellFont, CellStyle, CellValue$1 as CellValue, CfbEntry, ColumnOptions, ComparisonOperator, ConditionalFormat, ConditionalFormatRule, CsvOptions, DataValidation, DefinedName, GradientFill, HighlightStyle, OdsSheetOptions, OdsWriterOptions, PageSetup, ParseOptions, Placement, RandomAccessReader, RefMapper, RefRole, Relationship, RichTextRun, Row, RowData, RowOptions, SheetComment, SheetImage, SheetMetadata, SheetOptions, SheetProtection, SheetView, StyledCell, TableOptions, WorkbookInfo, WorkbookParts, WorkbookProperties, WriterOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -579,6 +579,28 @@ declare class CfbReader {
|
|
|
579
579
|
read(path: string): Uint8Array | undefined;
|
|
580
580
|
}
|
|
581
581
|
|
|
582
|
+
declare class StylePatcher {
|
|
583
|
+
private xml;
|
|
584
|
+
private p;
|
|
585
|
+
private fonts;
|
|
586
|
+
private fills;
|
|
587
|
+
private borders;
|
|
588
|
+
private xfs;
|
|
589
|
+
private numFmts;
|
|
590
|
+
private nextNumFmt;
|
|
591
|
+
private added;
|
|
592
|
+
private memo;
|
|
593
|
+
constructor(xml: string);
|
|
594
|
+
get changed(): boolean;
|
|
595
|
+
patch(base: number, style: CellStyle): number;
|
|
596
|
+
dateFormat(base: number, d: Date): number;
|
|
597
|
+
toXml(): string;
|
|
598
|
+
private existing;
|
|
599
|
+
private add;
|
|
600
|
+
private items;
|
|
601
|
+
private prefix;
|
|
602
|
+
}
|
|
603
|
+
|
|
582
604
|
type Placement = {
|
|
583
605
|
range: string;
|
|
584
606
|
} | {
|
|
@@ -597,5 +619,5 @@ declare const XlsxFlow: {
|
|
|
597
619
|
readFile(filePath: string, options?: ParseOptions): Promise<ParseResult>;
|
|
598
620
|
};
|
|
599
621
|
|
|
600
|
-
export { CfbReader, ConditionalFormatter, DRAWING_NS, FormulaEngine, OdsWriter, SheetEditor, SheetReader, SheetWriter, StyleEngine, XlsxFlow, ZipRandomAccessParser, ZipStreamWriter, anchorXml, colIndex, colLetter, crc32, createBlobReader, createFileReader, createXmlStreamParser, dateToSerial, decodeXString, drawingPartXml, encodeXString, isCfb, legacyPasswordHash, mapFormulaRefs, parseCsv, parseWorksheet, partRelationships, readSharedStrings, recalcOnOpen, resolveWorkbookParts, sheetToJson, shiftFormula, streamToCsv };
|
|
622
|
+
export { CfbReader, ConditionalFormatter, DRAWING_NS, FormulaEngine, OdsWriter, SheetEditor, SheetReader, SheetWriter, StyleEngine, StylePatcher, XlsxFlow, ZipRandomAccessParser, ZipStreamWriter, anchorXml, colIndex, colLetter, crc32, createBlobReader, createFileReader, createXmlStreamParser, dateToSerial, decodeXString, drawingPartXml, encodeXString, isCfb, legacyPasswordHash, mapFormulaRefs, parseCsv, parseWorksheet, partRelationships, readSharedStrings, recalcOnOpen, resolveWorkbookParts, sheetToJson, shiftFormula, streamToCsv };
|
|
601
623
|
export type { BorderSide, CellAlignment, CellBorder, CellComment, CellEdit, CellFill, CellFont, CellStyle, CellValue$1 as CellValue, CfbEntry, ColumnOptions, ComparisonOperator, ConditionalFormat, ConditionalFormatRule, CsvOptions, DataValidation, DefinedName, GradientFill, HighlightStyle, OdsSheetOptions, OdsWriterOptions, PageSetup, ParseOptions, Placement, RandomAccessReader, RefMapper, RefRole, Relationship, RichTextRun, Row, RowData, RowOptions, SheetComment, SheetImage, SheetMetadata, SheetOptions, SheetProtection, SheetView, StyledCell, TableOptions, WorkbookInfo, WorkbookParts, WorkbookProperties, WriterOptions };
|
package/dist/index.mjs
CHANGED
|
@@ -348,7 +348,16 @@ async function sheetToJson(parseResult, headerRowIndex = 0) {
|
|
|
348
348
|
if (skip-- > 0)
|
|
349
349
|
continue;
|
|
350
350
|
if (headers.length === 0) {
|
|
351
|
-
|
|
351
|
+
const seen = new Set();
|
|
352
|
+
headers = row.cells.map((c, i) => {
|
|
353
|
+
const base = c !== null && c !== undefined ? String(c) : `Column${i + 1}`;
|
|
354
|
+
// A repeated header gets a suffix ("Name_2") so its column isn't lost
|
|
355
|
+
let name = base;
|
|
356
|
+
for (let n = 2; seen.has(name); n++)
|
|
357
|
+
name = `${base}_${n}`;
|
|
358
|
+
seen.add(name);
|
|
359
|
+
return name;
|
|
360
|
+
});
|
|
352
361
|
continue;
|
|
353
362
|
}
|
|
354
363
|
const obj = {};
|
|
@@ -552,6 +561,8 @@ function encodeXString(s) {
|
|
|
552
561
|
.replace(/_(?=x[0-9A-Fa-f]{4}_)/g, '_x005F_')
|
|
553
562
|
.replace(/[\x00-\x08\x0B\x0C\r\x0E-\x1F]/g, c => `_x${c.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0')}_`);
|
|
554
563
|
}
|
|
564
|
+
// The format SheetWriter gives a date without one: the time only when there is one
|
|
565
|
+
const defaultDateFormat = (d) => d.getTime() % 86400000 === 0 ? 'yyyy-mm-dd' : 'yyyy-mm-dd hh:mm:ss';
|
|
555
566
|
// True when a number format renders dates/times. Ignores quoted text, escapes, colours and
|
|
556
567
|
// locale tags, so "0 \"days\"", "[Red]0.0" and "#,##0 \"USD\"" are not mistaken for dates.
|
|
557
568
|
function isDateFormatCode(code) {
|
|
@@ -3360,7 +3371,6 @@ function escapeXml$1(val) {
|
|
|
3360
3371
|
function isStyledCell$1(v) {
|
|
3361
3372
|
return typeof v === 'object' && v !== null && 'value' in v;
|
|
3362
3373
|
}
|
|
3363
|
-
const DAY_MS = 86400000;
|
|
3364
3374
|
// "A1:C10" -> "$A$1:$C$10"
|
|
3365
3375
|
const absoluteRef = (ref) => ref.replace(/([A-Za-z]+)(\d+)/g, '$$$1$$$2');
|
|
3366
3376
|
function stringXml(s) {
|
|
@@ -3387,13 +3397,13 @@ const W3CDTF = (d) => d.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
|
3387
3397
|
const propXml = (tag, v) => v === undefined ? '' : `<${tag}>${escapeXml$1(v)}</${tag}>`;
|
|
3388
3398
|
function corePropsXml(p) {
|
|
3389
3399
|
const created = p.created ? `<dcterms:created xsi:type="dcterms:W3CDTF">${W3CDTF(p.created)}</dcterms:created>` : '';
|
|
3390
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3400
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3391
3401
|
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">` +
|
|
3392
3402
|
propXml('dc:title', p.title) + propXml('dc:subject', p.subject) + propXml('dc:creator', p.creator) + propXml('cp:keywords', p.keywords) +
|
|
3393
3403
|
propXml('dc:description', p.description) + propXml('cp:category', p.category) + created + '</cp:coreProperties>';
|
|
3394
3404
|
}
|
|
3395
3405
|
function appPropsXml(p) {
|
|
3396
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3406
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3397
3407
|
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"><Application>XlsxFlow</Application>${propXml('Manager', p.manager)}${propXml('Company', p.company)}</Properties>`;
|
|
3398
3408
|
}
|
|
3399
3409
|
// A name Excel accepts: letters, digits, _ . and \, not a cell reference (A1, R1C1) and not reserved
|
|
@@ -3561,7 +3571,7 @@ class SheetWriter {
|
|
|
3561
3571
|
});
|
|
3562
3572
|
await this.streamString(zip, `xl/drawings/drawing${n}.xml`, drawingXml(images, images.map(img => this.media.get(img.data).info), rIds));
|
|
3563
3573
|
const rels = targets.map((t, k) => `<Relationship Id="rId${k + 1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="${t}"/>`).join('');
|
|
3564
|
-
await this.streamString(zip, `xl/drawings/_rels/drawing${n}.xml.rels`, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3574
|
+
await this.streamString(zip, `xl/drawings/_rels/drawing${n}.xml.rels`, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3565
3575
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${rels}</Relationships>`);
|
|
3566
3576
|
}
|
|
3567
3577
|
applyAutoFit(rows, options) {
|
|
@@ -3676,6 +3686,11 @@ class SheetWriter {
|
|
|
3676
3686
|
if (done)
|
|
3677
3687
|
break;
|
|
3678
3688
|
const rowNum = ri + 1;
|
|
3689
|
+
// Past Excel's sheet size the file is damaged, so refuse it instead
|
|
3690
|
+
if (rowNum > MAX_ROWS$1)
|
|
3691
|
+
throw new Error(`Row ${rowNum} is past Excel's last row (${MAX_ROWS$1}).`);
|
|
3692
|
+
if (row.length > MAX_COLUMNS$1)
|
|
3693
|
+
throw new Error(`Row ${rowNum} has ${row.length} cells, more than Excel's ${MAX_COLUMNS$1} columns.`);
|
|
3679
3694
|
chunkStr += optionRowsBefore(rowNum);
|
|
3680
3695
|
if (rowOptions[nextRowOption]?.[0] === rowNum)
|
|
3681
3696
|
nextRowOption++;
|
|
@@ -3686,7 +3701,7 @@ class SheetWriter {
|
|
|
3686
3701
|
let cellStyle = styledCell.style;
|
|
3687
3702
|
if (val instanceof Date && !cellStyle?.numFmt) {
|
|
3688
3703
|
// A date needs a date format, or Excel shows the bare serial number
|
|
3689
|
-
cellStyle = { ...cellStyle, numFmt: val
|
|
3704
|
+
cellStyle = { ...cellStyle, numFmt: defaultDateFormat(val) };
|
|
3690
3705
|
}
|
|
3691
3706
|
const style = cellStyle ? this.styleEngine.registerStyle(cellStyle) : 0;
|
|
3692
3707
|
const sAttr = style > 0 ? ` s="${style}"` : '';
|
|
@@ -3824,7 +3839,7 @@ class SheetWriter {
|
|
|
3824
3839
|
let items = '';
|
|
3825
3840
|
for (const s of this.sharedStrings.keys())
|
|
3826
3841
|
items += `<si>${stringXml(s)}</si>`;
|
|
3827
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3842
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3828
3843
|
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="${this.sharedStringRefs}" uniqueCount="${this.sharedStrings.size}">${items}</sst>`;
|
|
3829
3844
|
}
|
|
3830
3845
|
// '' when the sheet has no relationships
|
|
@@ -3839,7 +3854,7 @@ class SheetWriter {
|
|
|
3839
3854
|
tableIds.forEach((id, k) => { rels += `<Relationship Id="rIdTable${k + 1}" Type="${REL}/table" Target="../tables/table${id}.xml"/>`; });
|
|
3840
3855
|
if (!rels)
|
|
3841
3856
|
return '';
|
|
3842
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3857
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3843
3858
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${rels}</Relationships>`;
|
|
3844
3859
|
}
|
|
3845
3860
|
buildWorkbookXml() {
|
|
@@ -3864,14 +3879,14 @@ class SheetWriter {
|
|
|
3864
3879
|
}
|
|
3865
3880
|
return names;
|
|
3866
3881
|
}).join('');
|
|
3867
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3868
|
-
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
3869
|
-
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
|
3870
|
-
${active > 0 ? `<bookViews><workbookView firstSheet="${active}" activeTab="${active}"/></bookViews>` : ''}
|
|
3871
|
-
<sheets>
|
|
3872
|
-
${sheetsXml}
|
|
3873
|
-
</sheets>
|
|
3874
|
-
${filterNames || userNames ? `<definedNames>${filterNames}${userNames}</definedNames>` : ''}
|
|
3882
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3883
|
+
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
3884
|
+
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
|
3885
|
+
${active > 0 ? `<bookViews><workbookView firstSheet="${active}" activeTab="${active}"/></bookViews>` : ''}
|
|
3886
|
+
<sheets>
|
|
3887
|
+
${sheetsXml}
|
|
3888
|
+
</sheets>
|
|
3889
|
+
${filterNames || userNames ? `<definedNames>${filterNames}${userNames}</definedNames>` : ''}
|
|
3875
3890
|
</workbook>`;
|
|
3876
3891
|
}
|
|
3877
3892
|
// The first visible sheet, which Excel opens on
|
|
@@ -3882,19 +3897,19 @@ class SheetWriter {
|
|
|
3882
3897
|
const sheetRels = this.sheets.map((_, i) => `<Relationship Id="rId${i + 1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet${i + 1}.xml"/>`).join('\n ');
|
|
3883
3898
|
const ssId = this.sheets.length + 1;
|
|
3884
3899
|
const stylesId = this.sheets.length + 2;
|
|
3885
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3886
|
-
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
3887
|
-
${sheetRels}
|
|
3888
|
-
<Relationship Id="rId${ssId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>
|
|
3889
|
-
<Relationship Id="rId${stylesId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
|
|
3900
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3901
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
3902
|
+
${sheetRels}
|
|
3903
|
+
<Relationship Id="rId${ssId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>
|
|
3904
|
+
<Relationship Id="rId${stylesId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
|
|
3890
3905
|
</Relationships>`;
|
|
3891
3906
|
}
|
|
3892
3907
|
buildRootRels() {
|
|
3893
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3894
|
-
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
3895
|
-
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>${this.writerOptions.properties ? `
|
|
3896
|
-
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
|
|
3897
|
-
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>` : ''}
|
|
3908
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3909
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
3910
|
+
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>${this.writerOptions.properties ? `
|
|
3911
|
+
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
|
|
3912
|
+
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>` : ''}
|
|
3898
3913
|
</Relationships>`;
|
|
3899
3914
|
}
|
|
3900
3915
|
buildContentTypes(drawings, commentSheets, tables) {
|
|
@@ -3905,17 +3920,17 @@ class SheetWriter {
|
|
|
3905
3920
|
commentSheets.map(n => `<Override PartName="/xl/comments${n}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"/>`).join('') +
|
|
3906
3921
|
Array.from({ length: tables }, (_, i) => `<Override PartName="/xl/tables/table${i + 1}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"/>`).join('') +
|
|
3907
3922
|
(commentSheets.length ? '<Default Extension="vml" ContentType="application/vnd.openxmlformats-officedocument.vmlDrawing"/>' : '');
|
|
3908
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3909
|
-
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
|
3910
|
-
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
|
|
3911
|
-
<Default Extension="xml" ContentType="application/xml"/>
|
|
3912
|
-
${imageTypes}${drawingOverrides}
|
|
3913
|
-
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
|
|
3914
|
-
${sheetOverrides}
|
|
3915
|
-
<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
|
|
3916
|
-
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>${this.writerOptions.properties ? `
|
|
3917
|
-
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
|
|
3918
|
-
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>` : ''}
|
|
3923
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3924
|
+
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
|
3925
|
+
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
|
|
3926
|
+
<Default Extension="xml" ContentType="application/xml"/>
|
|
3927
|
+
${imageTypes}${drawingOverrides}
|
|
3928
|
+
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
|
|
3929
|
+
${sheetOverrides}
|
|
3930
|
+
<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
|
|
3931
|
+
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>${this.writerOptions.properties ? `
|
|
3932
|
+
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
|
|
3933
|
+
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>` : ''}
|
|
3919
3934
|
</Types>`;
|
|
3920
3935
|
}
|
|
3921
3936
|
}
|
|
@@ -3947,7 +3962,7 @@ function pageSetupXml(page) {
|
|
|
3947
3962
|
function commentsXml(comments) {
|
|
3948
3963
|
const authors = [...new Set(comments.map(c => c.comment.author ?? ''))];
|
|
3949
3964
|
const list = comments.map(c => `<comment ref="${c.ref}" authorId="${authors.indexOf(c.comment.author ?? '')}"><text>${runsXml(c.comment.text)}</text></comment>`).join('');
|
|
3950
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3965
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3951
3966
|
<comments xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><authors>${authors.map(a => `<author>${escapeXml$1(a)}</author>`).join('')}</authors><commentList>${list}</commentList></comments>`;
|
|
3952
3967
|
}
|
|
3953
3968
|
// The legacy VML shapes Excel needs to show the note boxes (hidden until the cell is hovered)
|
|
@@ -3967,7 +3982,7 @@ function tableXml(table, id, columns) {
|
|
|
3967
3982
|
const ref = table.ref.replace(/\$/g, '');
|
|
3968
3983
|
const filter = table.autoFilter === false ? '' : `<autoFilter ref="${ref}"/>`;
|
|
3969
3984
|
const cols = columns.map((c, k) => `<tableColumn id="${k + 1}" name="${escapeXml$1(c)}"/>`).join('');
|
|
3970
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3985
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3971
3986
|
<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" id="${id}" name="${escapeXml$1(table.name)}" displayName="${escapeXml$1(table.name)}" ref="${ref}" totalsRowShown="0">` +
|
|
3972
3987
|
`${filter}<tableColumns count="${columns.length}">${cols}</tableColumns>` +
|
|
3973
3988
|
`<tableStyleInfo name="${escapeXml$1(table.style ?? 'TableStyleMedium2')}" showFirstColumn="0" showLastColumn="0" showRowStripes="${table.showRowStripes === false ? 0 : 1}" showColumnStripes="0"/></table>`;
|
|
@@ -4142,6 +4157,16 @@ class StylePatcher {
|
|
|
4142
4157
|
this.memo.set(key, id);
|
|
4143
4158
|
return id;
|
|
4144
4159
|
}
|
|
4160
|
+
// The format for date `d` in a cell of format `base`: `base` when it already shows dates, otherwise
|
|
4161
|
+
// `base` with a date format, since a date in a General cell shows as its serial number
|
|
4162
|
+
dateFormat(base, d) {
|
|
4163
|
+
const xf = this.xfs[base] ?? this.added.cellXfs[base - this.xfs.length] ?? '';
|
|
4164
|
+
const id = parseInt(attr(/^<[^>]*>/.exec(xf)?.[0] ?? '', 'numFmtId') ?? '0', 10);
|
|
4165
|
+
const code = [...this.numFmts].find(([, v]) => v === id)?.[0];
|
|
4166
|
+
if (isBuiltinDateFormat(id) || (code !== undefined && isDateFormatCode(code)))
|
|
4167
|
+
return base;
|
|
4168
|
+
return this.patch(base, { numFmt: defaultDateFormat(d) });
|
|
4169
|
+
}
|
|
4145
4170
|
toXml() {
|
|
4146
4171
|
let xml = this.xml;
|
|
4147
4172
|
for (const section of ['numFmts', 'fonts', 'fills', 'borders', 'cellXfs']) {
|
|
@@ -4936,7 +4961,10 @@ class SheetEditor {
|
|
|
4936
4961
|
let patcher;
|
|
4937
4962
|
const styled = [...editsByPath.values(), ...added.values()]
|
|
4938
4963
|
.some(rows => [...rows.values()].some(cells => [...cells.values()].some(e => styleOf(e))));
|
|
4939
|
-
|
|
4964
|
+
// Dates may need a date format added to their cells
|
|
4965
|
+
const dated = [...editsByPath.values(), ...added.values()]
|
|
4966
|
+
.some(rows => [...rows.values()].some(cells => [...cells.values()].some(e => contentOf(e) instanceof Date)));
|
|
4967
|
+
if (styled || (dated && parts.styles)) {
|
|
4940
4968
|
if (!parts.styles)
|
|
4941
4969
|
throw new Error('Workbook has no styles part.');
|
|
4942
4970
|
patcher = new StylePatcher(await read(parts.styles));
|
|
@@ -5013,6 +5041,10 @@ class SheetEditor {
|
|
|
5013
5041
|
attrs = `${attrs.replace(/\ss="[^"]*"/, '')} s="${patcher.patch(base, style)}"`;
|
|
5014
5042
|
}
|
|
5015
5043
|
const content = contentOf(edit);
|
|
5044
|
+
if (content instanceof Date && patcher) {
|
|
5045
|
+
const base = parseInt(/\ss="(\d+)"/.exec(attrs)?.[1] ?? '0', 10);
|
|
5046
|
+
attrs = `${attrs.replace(/\ss="[^"]*"/, '')} s="${patcher.dateFormat(base, content)}"`;
|
|
5047
|
+
}
|
|
5016
5048
|
if (content === KEEP) {
|
|
5017
5049
|
return existing?.[2] !== undefined ? `<${p}c r="${ref}"${attrs}>${existing[2]}</${p}c>` : `<${p}c r="${ref}"${attrs}/>`;
|
|
5018
5050
|
}
|
|
@@ -5774,7 +5806,8 @@ async function* parseCsv(input, options = {}) {
|
|
|
5774
5806
|
let first = true;
|
|
5775
5807
|
const rows = [];
|
|
5776
5808
|
const endField = () => {
|
|
5777
|
-
|
|
5809
|
+
// An empty unquoted field is null in both modes; a quoted "" stays an empty string
|
|
5810
|
+
row.push(quoted ? field : !convert ? (field === '' ? null : field) : convertField(field));
|
|
5778
5811
|
field = '';
|
|
5779
5812
|
quoted = false;
|
|
5780
5813
|
};
|
|
@@ -5906,11 +5939,14 @@ function textXml(s) {
|
|
|
5906
5939
|
}
|
|
5907
5940
|
const dateValue = (d) => d.toISOString().slice(0, 19); // UTC, like SheetWriter
|
|
5908
5941
|
const hasTime = (d) => d.getTime() % 86400000 !== 0;
|
|
5909
|
-
function cellXml(cell, span, covered) {
|
|
5942
|
+
function cellXml(cell, span, covered, evaluate) {
|
|
5910
5943
|
if (covered)
|
|
5911
5944
|
return '<table:covered-table-cell/>';
|
|
5912
|
-
|
|
5945
|
+
let value = isStyledCell(cell) ? cell.value : cell;
|
|
5913
5946
|
const formula = isStyledCell(cell) && cell.formula ? ` table:formula="${escapeXml(toOpenFormula(cell.formula))}"` : '';
|
|
5947
|
+
// A formula without a value gets its result stored, as SheetWriter does, for readers that don't recalculate
|
|
5948
|
+
if (formula && value == null)
|
|
5949
|
+
value = evaluate(cell.formula);
|
|
5914
5950
|
if (value === null || value === undefined || (typeof value === 'number' && !isFinite(value))) {
|
|
5915
5951
|
return formula || span ? `<table:table-cell${formula}${span}/>` : '<table:table-cell/>';
|
|
5916
5952
|
}
|
|
@@ -6003,6 +6039,15 @@ class OdsWriter {
|
|
|
6003
6039
|
const merges = (sheet.options.mergeCells ?? []).map(parseRange);
|
|
6004
6040
|
const lastMergeRow = Math.max(-1, ...merges.map(m => m.r2));
|
|
6005
6041
|
const mergeAt = (r, c) => merges.find(m => m.r1 === r && m.c1 === c);
|
|
6042
|
+
// Formulas resolve against the sheet they live in; streamed rows can't be looked back at
|
|
6043
|
+
const engine = new FormulaEngine();
|
|
6044
|
+
if (Array.isArray(sheet.rows)) {
|
|
6045
|
+
engine.loadData(sheet.rows.map(row => row.map(cell => {
|
|
6046
|
+
const v = isStyledCell(cell) ? cell.value : cell;
|
|
6047
|
+
return v instanceof Date ? dateToSerial(v) : v ?? null;
|
|
6048
|
+
})));
|
|
6049
|
+
}
|
|
6050
|
+
const evaluate = (f) => engine.evaluate(f);
|
|
6006
6051
|
const covered = (r, c) => merges.some(m => r >= m.r1 && r <= m.r2 && c >= m.c1 && c <= m.c2 && (r !== m.r1 || c !== m.c1));
|
|
6007
6052
|
let r = 0, batch = '';
|
|
6008
6053
|
const writeRow = (row) => {
|
|
@@ -6011,7 +6056,7 @@ class OdsWriter {
|
|
|
6011
6056
|
for (let c = 0; c < width; c++) {
|
|
6012
6057
|
const m = mergeAt(r, c);
|
|
6013
6058
|
const span = m ? ` table:number-columns-spanned="${m.c2 - m.c1 + 1}" table:number-rows-spanned="${m.r2 - m.r1 + 1}"` : '';
|
|
6014
|
-
xml += cellXml(row[c], span, covered(r, c));
|
|
6059
|
+
xml += cellXml(row[c], span, covered(r, c), evaluate);
|
|
6015
6060
|
}
|
|
6016
6061
|
r++;
|
|
6017
6062
|
return xml + (width ? '' : '<table:table-cell/>') + '</table:table-row>';
|
|
@@ -6095,5 +6140,5 @@ const XlsxFlow = {
|
|
|
6095
6140
|
}
|
|
6096
6141
|
};
|
|
6097
6142
|
|
|
6098
|
-
export { CfbReader, ConditionalFormatter, DRAWING_NS, FormulaEngine, OdsWriter, SheetEditor, SheetReader, SheetWriter, StyleEngine, XlsxFlow, ZipRandomAccessParser, ZipStreamWriter, anchorXml, colIndex, colLetter, crc32, createBlobReader, createFileReader, createXmlStreamParser, dateToSerial, decodeXString, drawingPartXml, encodeXString, isCfb, legacyPasswordHash, mapFormulaRefs, parseCsv, parseWorksheet, partRelationships, readSharedStrings, recalcOnOpen, resolveWorkbookParts, sheetToJson, shiftFormula, streamToCsv };
|
|
6143
|
+
export { CfbReader, ConditionalFormatter, DRAWING_NS, FormulaEngine, OdsWriter, SheetEditor, SheetReader, SheetWriter, StyleEngine, StylePatcher, XlsxFlow, ZipRandomAccessParser, ZipStreamWriter, anchorXml, colIndex, colLetter, crc32, createBlobReader, createFileReader, createXmlStreamParser, dateToSerial, decodeXString, drawingPartXml, encodeXString, isCfb, legacyPasswordHash, mapFormulaRefs, parseCsv, parseWorksheet, partRelationships, readSharedStrings, recalcOnOpen, resolveWorkbookParts, sheetToJson, shiftFormula, streamToCsv };
|
|
6099
6144
|
//# sourceMappingURL=index.mjs.map
|