@xlsxflow/core 1.1.2 → 1.1.3

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/dist/index.d.cts CHANGED
@@ -372,6 +372,7 @@ interface WorkbookParts {
372
372
  declare function resolveWorkbookParts(readText: (path: string) => Promise<string>): Promise<WorkbookParts>;
373
373
  declare function partRelationships(readText: (path: string) => Promise<string>, partPath: string): Promise<Relationship[]>;
374
374
  declare function decodeXString(s: string): string;
375
+ declare function checkCellText(s: string, ref: string): string;
375
376
  declare function colIndex(ref: string): number;
376
377
  declare function colLetter(index: number): string;
377
378
  type RefRole = 'single' | 'start' | 'end';
@@ -619,5 +620,5 @@ declare const XlsxFlow: {
619
620
  readFile(filePath: string, options?: ParseOptions): Promise<ParseResult>;
620
621
  };
621
622
 
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 };
623
+ export { CfbReader, ConditionalFormatter, DRAWING_NS, FormulaEngine, OdsWriter, SheetEditor, SheetReader, SheetWriter, StyleEngine, StylePatcher, XlsxFlow, ZipRandomAccessParser, ZipStreamWriter, anchorXml, checkCellText, colIndex, colLetter, crc32, createBlobReader, createFileReader, createXmlStreamParser, dateToSerial, decodeXString, drawingPartXml, encodeXString, isCfb, legacyPasswordHash, mapFormulaRefs, parseCsv, parseWorksheet, partRelationships, readSharedStrings, recalcOnOpen, resolveWorkbookParts, sheetToJson, shiftFormula, streamToCsv };
623
624
  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
@@ -372,6 +372,7 @@ interface WorkbookParts {
372
372
  declare function resolveWorkbookParts(readText: (path: string) => Promise<string>): Promise<WorkbookParts>;
373
373
  declare function partRelationships(readText: (path: string) => Promise<string>, partPath: string): Promise<Relationship[]>;
374
374
  declare function decodeXString(s: string): string;
375
+ declare function checkCellText(s: string, ref: string): string;
375
376
  declare function colIndex(ref: string): number;
376
377
  declare function colLetter(index: number): string;
377
378
  type RefRole = 'single' | 'start' | 'end';
@@ -619,5 +620,5 @@ declare const XlsxFlow: {
619
620
  readFile(filePath: string, options?: ParseOptions): Promise<ParseResult>;
620
621
  };
621
622
 
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 };
623
+ export { CfbReader, ConditionalFormatter, DRAWING_NS, FormulaEngine, OdsWriter, SheetEditor, SheetReader, SheetWriter, StyleEngine, StylePatcher, XlsxFlow, ZipRandomAccessParser, ZipStreamWriter, anchorXml, checkCellText, colIndex, colLetter, crc32, createBlobReader, createFileReader, createXmlStreamParser, dateToSerial, decodeXString, drawingPartXml, encodeXString, isCfb, legacyPasswordHash, mapFormulaRefs, parseCsv, parseWorksheet, partRelationships, readSharedStrings, recalcOnOpen, resolveWorkbookParts, sheetToJson, shiftFormula, streamToCsv };
623
624
  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
@@ -462,6 +462,21 @@ function decodeXString(s) {
462
462
  // Excel's sheet size (A..XFD, 1..1048576)
463
463
  const MAX_COLUMNS$1 = 16384;
464
464
  const MAX_ROWS$1 = 1048576;
465
+ // Excel's limit on the characters in one cell
466
+ const MAX_CELL_TEXT = 32767;
467
+ function checkCellText(s, ref) {
468
+ if (s.length > MAX_CELL_TEXT)
469
+ throw new Error(`Cell ${ref} has ${s.length} characters, more than Excel's ${MAX_CELL_TEXT}.`);
470
+ return s;
471
+ }
472
+ // Colours are ARGB hex ("FFFF0000"); "FF0000" and "#FF0000" get an opaque alpha. Anything else
473
+ // makes Excel repair the file.
474
+ function argb(c) {
475
+ const m = /^#?([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.exec(String(c));
476
+ if (!m)
477
+ throw new Error(`Invalid colour "${c}": use ARGB hex such as "FFFF0000".`);
478
+ return (m[1].length === 6 ? 'FF' + m[1] : m[1]).toUpperCase();
479
+ }
465
480
  // 0-based column of letters like "BC" (or a reference like "BC12"); -1 when there are none
466
481
  function colIndex(ref) {
467
482
  const match = ref.match(/[A-Za-z]+/);
@@ -1459,7 +1474,8 @@ function parseWorksheet(xmlTokenStream, sharedStrings, styles, is1904 = false, o
1459
1474
  }
1460
1475
  else if (currentCellType === 's') {
1461
1476
  const index = parseInt(currentCellValue, 10);
1462
- resolvedValue = sharedStrings.get(index) ?? currentCellValue;
1477
+ // An index past the table points nowhere: the cell is empty
1478
+ resolvedValue = sharedStrings.get(index) ?? null;
1463
1479
  }
1464
1480
  else if (currentCellType === 'b') {
1465
1481
  resolvedValue = currentCellValue === '1' || currentCellValue === 'true';
@@ -1633,9 +1649,10 @@ async function readSheetImages(readText, readBytes, sheetPath) {
1633
1649
  const escapeXml$4 = (s) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
1634
1650
  const cellPos = (ref) => {
1635
1651
  const m = /^\$?([A-Za-z]{1,3})\$?(\d+)$/.exec(ref.trim());
1636
- if (!m)
1652
+ const col = m ? colIndex(m[1]) : -1, row = m ? parseInt(m[2], 10) - 1 : -1;
1653
+ if (col < 0 || col >= MAX_COLUMNS$1 || row < 0 || row >= MAX_ROWS$1)
1637
1654
  throw new Error(`Invalid anchor cell "${ref}".`);
1638
- return { col: colIndex(m[1]), row: parseInt(m[2], 10) - 1 };
1655
+ return { col, row };
1639
1656
  };
1640
1657
  const marker = (tag, { col, row }) => `<xdr:${tag}><xdr:col>${col}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${row}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:${tag}>`;
1641
1658
  const DRAWING_NS = 'xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" ' +
@@ -1647,9 +1664,11 @@ const DRAWING_NS = 'xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/
1647
1664
  function anchorXml(place, natural, body, attrs = '') {
1648
1665
  if ('range' in place) {
1649
1666
  const [from, to = from] = place.range.split(':');
1650
- const end = cellPos(to);
1651
- // The object fills the range: it ends at the far edge of the last cell
1652
- return `<xdr:twoCellAnchor editAs="oneCell"${attrs}>${marker('from', cellPos(from))}${marker('to', { col: end.col + 1, row: end.row + 1 })}${body}<xdr:clientData/></xdr:twoCellAnchor>`;
1667
+ const a = cellPos(from), b = cellPos(to);
1668
+ // The object fills the range, given either way round: it ends at the far edge of the last cell
1669
+ const start = { col: Math.min(a.col, b.col), row: Math.min(a.row, b.row) };
1670
+ const end = { col: Math.max(a.col, b.col) + 1, row: Math.max(a.row, b.row) + 1 };
1671
+ return `<xdr:twoCellAnchor editAs="oneCell"${attrs}>${marker('from', start)}${marker('to', end)}${body}<xdr:clientData/></xdr:twoCellAnchor>`;
1653
1672
  }
1654
1673
  const { width: w, height: h } = natural;
1655
1674
  const width = place.width ?? (place.height ? w * place.height / h : w);
@@ -2634,22 +2653,22 @@ function fontXml(font, nameTag = 'name') {
2634
2653
  if (font.size)
2635
2654
  xml += `<sz val="${escapeXml$3(font.size)}"/>`;
2636
2655
  if (font.color)
2637
- xml += `<color rgb="${escapeXml$3(font.color)}"/>`;
2656
+ xml += `<color rgb="${argb(font.color)}"/>`;
2638
2657
  if (font.name)
2639
2658
  xml += `<${nameTag} val="${escapeXml$3(font.name)}"/>`;
2640
2659
  return xml;
2641
2660
  }
2642
- const borderSideXml = (tag, s) => s ? `<${tag} style="${escapeXml$3(s.style)}">${s.color ? `<color rgb="${escapeXml$3(s.color)}"/>` : ''}</${tag}>` : `<${tag}/>`;
2661
+ const borderSideXml = (tag, s) => s ? `<${tag} style="${escapeXml$3(s.style)}">${s.color ? `<color rgb="${argb(s.color)}"/>` : ''}</${tag}>` : `<${tag}/>`;
2643
2662
  function borderXml(b) {
2644
2663
  const side = borderSideXml;
2645
2664
  return `<border>${side('left', b.left)}${side('right', b.right)}${side('top', b.top)}${side('bottom', b.bottom)}<diagonal/></border>`;
2646
2665
  }
2647
2666
  function fillXml(fill) {
2648
2667
  if (fill.type === 'gradient') {
2649
- const stops = fill.stops.map(s => `<stop position="${s.position}"><color rgb="${escapeXml$3(s.color)}"/></stop>`).join('');
2668
+ const stops = fill.stops.map(s => `<stop position="${s.position}"><color rgb="${argb(s.color)}"/></stop>`).join('');
2650
2669
  return `<fill><gradientFill degree="${escapeXml$3(fill.degree ?? 0)}">${stops}</gradientFill></fill>`;
2651
2670
  }
2652
- return `<fill><patternFill patternType="solid"><fgColor rgb="${escapeXml$3(fill.fgColor)}"/></patternFill></fill>`;
2671
+ return `<fill><patternFill patternType="solid"><fgColor rgb="${argb(fill.fgColor)}"/></patternFill></fill>`;
2653
2672
  }
2654
2673
  // Attributes of an <alignment> element
2655
2674
  function alignmentAttrs(alignment) {
@@ -2691,7 +2710,7 @@ class StyleEngine {
2691
2710
  xml += `<numFmt numFmtId="${this.registerNumFmt(style.numFmt)}" formatCode="${escapeXml$3(style.numFmt)}"/>`;
2692
2711
  if (style.fill?.type === 'solid') {
2693
2712
  // A differential solid fill takes its colour from bgColor
2694
- const c = escapeXml$3(style.fill.fgColor);
2713
+ const c = argb(style.fill.fgColor);
2695
2714
  xml += `<fill><patternFill patternType="solid"><fgColor rgb="${c}"/><bgColor rgb="${c}"/></patternFill></fill>`;
2696
2715
  }
2697
2716
  if (style.border)
@@ -2819,7 +2838,7 @@ ${this.dxfs.size ? `<dxfs count="${this.dxfs.size}">${[...this.dxfs.keys()].map(
2819
2838
  function escapeXml$2(val) {
2820
2839
  return String(val).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
2821
2840
  }
2822
- const color = (rgb) => `<color rgb="${escapeXml$2(rgb)}"/>`;
2841
+ const color = (rgb) => `<color rgb="${argb(rgb)}"/>`;
2823
2842
  const bound = (type, value) => value === undefined ? `<cfvo type="${type}"/>` : `<cfvo type="num" val="${escapeXml$2(value)}"/>`;
2824
2843
  const formula = (f) => `<formula>${escapeXml$2(String(f).replace(/^=/, ''))}</formula>`;
2825
2844
  // Excel string literal inside a formula
@@ -3397,13 +3416,13 @@ const W3CDTF = (d) => d.toISOString().replace(/\.\d{3}Z$/, 'Z');
3397
3416
  const propXml = (tag, v) => v === undefined ? '' : `<${tag}>${escapeXml$1(v)}</${tag}>`;
3398
3417
  function corePropsXml(p) {
3399
3418
  const created = p.created ? `<dcterms:created xsi:type="dcterms:W3CDTF">${W3CDTF(p.created)}</dcterms:created>` : '';
3400
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3419
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3401
3420
  <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">` +
3402
3421
  propXml('dc:title', p.title) + propXml('dc:subject', p.subject) + propXml('dc:creator', p.creator) + propXml('cp:keywords', p.keywords) +
3403
3422
  propXml('dc:description', p.description) + propXml('cp:category', p.category) + created + '</cp:coreProperties>';
3404
3423
  }
3405
3424
  function appPropsXml(p) {
3406
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3425
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3407
3426
  <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"><Application>XlsxFlow</Application>${propXml('Manager', p.manager)}${propXml('Company', p.company)}</Properties>`;
3408
3427
  }
3409
3428
  // A name Excel accepts: letters, digits, _ . and \, not a cell reference (A1, R1C1) and not reserved
@@ -3571,7 +3590,7 @@ class SheetWriter {
3571
3590
  });
3572
3591
  await this.streamString(zip, `xl/drawings/drawing${n}.xml`, drawingXml(images, images.map(img => this.media.get(img.data).info), rIds));
3573
3592
  const rels = targets.map((t, k) => `<Relationship Id="rId${k + 1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="${t}"/>`).join('');
3574
- await this.streamString(zip, `xl/drawings/_rels/drawing${n}.xml.rels`, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3593
+ await this.streamString(zip, `xl/drawings/_rels/drawing${n}.xml.rels`, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3575
3594
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${rels}</Relationships>`);
3576
3595
  }
3577
3596
  applyAutoFit(rows, options) {
@@ -3648,7 +3667,7 @@ class SheetWriter {
3648
3667
  const page = options.pageSetup;
3649
3668
  const fitToPage = page && (page.fitToWidth !== undefined || page.fitToHeight !== undefined);
3650
3669
  const sheetPr = options.tabColor || fitToPage
3651
- ? `<sheetPr>${options.tabColor ? `<tabColor rgb="${escapeXml$1(options.tabColor)}"/>` : ''}${fitToPage ? '<pageSetUpPr fitToPage="1"/>' : ''}</sheetPr>`
3670
+ ? `<sheetPr>${options.tabColor ? `<tabColor rgb="${argb(options.tabColor)}"/>` : ''}${fitToPage ? '<pageSetUpPr fitToPage="1"/>' : ''}</sheetPr>`
3652
3671
  : '';
3653
3672
  const sheetFormatPr = outlineRow || outlineCol
3654
3673
  ? `<sheetFormatPr defaultRowHeight="15"${outlineRow ? ` outlineLevelRow="${outlineRow}"` : ''}${outlineCol ? ` outlineLevelCol="${outlineCol}"` : ''}/>`
@@ -3752,6 +3771,7 @@ class SheetWriter {
3752
3771
  return `<c r="${colRef}"${sAttr}><v>${dateToSerial(val)}</v></c>`;
3753
3772
  }
3754
3773
  if (typeof val === 'string') {
3774
+ checkCellText(val, colRef);
3755
3775
  if (this.writerOptions.sharedStrings) {
3756
3776
  let index = this.sharedStrings.get(val);
3757
3777
  if (index === undefined)
@@ -3839,7 +3859,7 @@ class SheetWriter {
3839
3859
  let items = '';
3840
3860
  for (const s of this.sharedStrings.keys())
3841
3861
  items += `<si>${stringXml(s)}</si>`;
3842
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3862
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3843
3863
  <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="${this.sharedStringRefs}" uniqueCount="${this.sharedStrings.size}">${items}</sst>`;
3844
3864
  }
3845
3865
  // '' when the sheet has no relationships
@@ -3854,7 +3874,7 @@ class SheetWriter {
3854
3874
  tableIds.forEach((id, k) => { rels += `<Relationship Id="rIdTable${k + 1}" Type="${REL}/table" Target="../tables/table${id}.xml"/>`; });
3855
3875
  if (!rels)
3856
3876
  return '';
3857
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3877
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3858
3878
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${rels}</Relationships>`;
3859
3879
  }
3860
3880
  buildWorkbookXml() {
@@ -3879,14 +3899,14 @@ class SheetWriter {
3879
3899
  }
3880
3900
  return names;
3881
3901
  }).join('');
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>` : ''}
3902
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3903
+ <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
3904
+ xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
3905
+ ${active > 0 ? `<bookViews><workbookView firstSheet="${active}" activeTab="${active}"/></bookViews>` : ''}
3906
+ <sheets>
3907
+ ${sheetsXml}
3908
+ </sheets>
3909
+ ${filterNames || userNames ? `<definedNames>${filterNames}${userNames}</definedNames>` : ''}
3890
3910
  </workbook>`;
3891
3911
  }
3892
3912
  // The first visible sheet, which Excel opens on
@@ -3897,19 +3917,19 @@ class SheetWriter {
3897
3917
  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 ');
3898
3918
  const ssId = this.sheets.length + 1;
3899
3919
  const stylesId = this.sheets.length + 2;
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"/>
3920
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3921
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
3922
+ ${sheetRels}
3923
+ <Relationship Id="rId${ssId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>
3924
+ <Relationship Id="rId${stylesId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
3905
3925
  </Relationships>`;
3906
3926
  }
3907
3927
  buildRootRels() {
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"/>` : ''}
3928
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3929
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
3930
+ <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>${this.writerOptions.properties ? `
3931
+ <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
3932
+ <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>` : ''}
3913
3933
  </Relationships>`;
3914
3934
  }
3915
3935
  buildContentTypes(drawings, commentSheets, tables) {
@@ -3920,17 +3940,17 @@ class SheetWriter {
3920
3940
  commentSheets.map(n => `<Override PartName="/xl/comments${n}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"/>`).join('') +
3921
3941
  Array.from({ length: tables }, (_, i) => `<Override PartName="/xl/tables/table${i + 1}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"/>`).join('') +
3922
3942
  (commentSheets.length ? '<Default Extension="vml" ContentType="application/vnd.openxmlformats-officedocument.vmlDrawing"/>' : '');
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"/>` : ''}
3943
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3944
+ <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
3945
+ <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
3946
+ <Default Extension="xml" ContentType="application/xml"/>
3947
+ ${imageTypes}${drawingOverrides}
3948
+ <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
3949
+ ${sheetOverrides}
3950
+ <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
3951
+ <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>${this.writerOptions.properties ? `
3952
+ <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
3953
+ <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>` : ''}
3934
3954
  </Types>`;
3935
3955
  }
3936
3956
  }
@@ -3962,7 +3982,7 @@ function pageSetupXml(page) {
3962
3982
  function commentsXml(comments) {
3963
3983
  const authors = [...new Set(comments.map(c => c.comment.author ?? ''))];
3964
3984
  const list = comments.map(c => `<comment ref="${c.ref}" authorId="${authors.indexOf(c.comment.author ?? '')}"><text>${runsXml(c.comment.text)}</text></comment>`).join('');
3965
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3985
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3966
3986
  <comments xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><authors>${authors.map(a => `<author>${escapeXml$1(a)}</author>`).join('')}</authors><commentList>${list}</commentList></comments>`;
3967
3987
  }
3968
3988
  // The legacy VML shapes Excel needs to show the note boxes (hidden until the cell is hovered)
@@ -3982,7 +4002,7 @@ function tableXml(table, id, columns) {
3982
4002
  const ref = table.ref.replace(/\$/g, '');
3983
4003
  const filter = table.autoFilter === false ? '' : `<autoFilter ref="${ref}"/>`;
3984
4004
  const cols = columns.map((c, k) => `<tableColumn id="${k + 1}" name="${escapeXml$1(c)}"/>`).join('');
3985
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
4005
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3986
4006
  <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">` +
3987
4007
  `${filter}<tableColumns count="${columns.length}">${cols}</tableColumns>` +
3988
4008
  `<tableStyleInfo name="${escapeXml$1(table.style ?? 'TableStyleMedium2')}" showFirstColumn="0" showLastColumn="0" showRowStripes="${table.showRowStripes === false ? 0 : 1}" showColumnStripes="0"/></table>`;
@@ -4722,7 +4742,7 @@ function editedCell(p, ref, attrs, edit) {
4722
4742
  }
4723
4743
  if (typeof edit === 'object')
4724
4744
  return `<${p}c r="${ref}"${attrs}><${p}f>${escapeXml$5(edit.formula.replace(/^=/, ''))}</${p}f></${p}c>`;
4725
- const text = escapeXml$5(encodeXString(edit));
4745
+ const text = escapeXml$5(encodeXString(checkCellText(edit, ref)));
4726
4746
  const t = /^\s|\s$/.test(edit) ? `<${p}t xml:space="preserve">${text}</${p}t>` : `<${p}t>${text}</${p}t>`;
4727
4747
  return `<${p}c r="${ref}"${attrs} t="inlineStr"><${p}is>${t}</${p}is></${p}c>`;
4728
4748
  }
@@ -4773,9 +4793,9 @@ class SheetEditor {
4773
4793
  this.cellEdits.set(sheetName, rows = new Map());
4774
4794
  for (const [ref, edit] of Object.entries(cells)) {
4775
4795
  const m = /^\$?([A-Za-z]{1,3})\$?(\d+)$/.exec(ref);
4776
- if (!m || parseInt(m[2], 10) < 1)
4796
+ const r = m ? parseInt(m[2], 10) : 0;
4797
+ if (!m || r < 1 || r > MAX_ROWS$1 || colIndex(m[1]) >= MAX_COLUMNS$1)
4777
4798
  throw new Error(`Invalid cell reference "${ref}".`);
4778
- const r = parseInt(m[2], 10);
4779
4799
  if (!rows.has(r))
4780
4800
  rows.set(r, new Map());
4781
4801
  rows.get(r).set(colIndex(m[1]), edit);
@@ -5194,7 +5214,7 @@ class SheetEditor {
5194
5214
  if (typeof val === 'number')
5195
5215
  return `<c r="${colRef}"><v>${val}</v></c>`;
5196
5216
  if (typeof val === 'string') {
5197
- return `<c r="${colRef}" t="inlineStr"><is><t xml:space="preserve">${escapeXml$5(encodeXString(val))}</t></is></c>`;
5217
+ return `<c r="${colRef}" t="inlineStr"><is><t xml:space="preserve">${escapeXml$5(encodeXString(checkCellText(val, colRef)))}</t></is></c>`;
5198
5218
  }
5199
5219
  return `<c r="${colRef}"/>`;
5200
5220
  }).join('');
@@ -6140,5 +6160,5 @@ const XlsxFlow = {
6140
6160
  }
6141
6161
  };
6142
6162
 
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 };
6163
+ export { CfbReader, ConditionalFormatter, DRAWING_NS, FormulaEngine, OdsWriter, SheetEditor, SheetReader, SheetWriter, StyleEngine, StylePatcher, XlsxFlow, ZipRandomAccessParser, ZipStreamWriter, anchorXml, checkCellText, colIndex, colLetter, crc32, createBlobReader, createFileReader, createXmlStreamParser, dateToSerial, decodeXString, drawingPartXml, encodeXString, isCfb, legacyPasswordHash, mapFormulaRefs, parseCsv, parseWorksheet, partRelationships, readSharedStrings, recalcOnOpen, resolveWorkbookParts, sheetToJson, shiftFormula, streamToCsv };
6144
6164
  //# sourceMappingURL=index.mjs.map