@cj-tech-master/excelts 5.1.3 → 5.1.4
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/browser/modules/excel/stream/workbook-writer.browser.js +7 -1
- package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +2 -4
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +10 -5
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +12 -7
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +7 -1
- package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +2 -4
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +10 -5
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +11 -6
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +7 -1
- package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +2 -4
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +10 -5
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +12 -7
- package/dist/iife/excelts.iife.js +20 -16
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +4 -4
- package/package.json +1 -1
|
@@ -224,8 +224,14 @@ export class WorkbookWriterBase {
|
|
|
224
224
|
}
|
|
225
225
|
addContentTypes() {
|
|
226
226
|
return new Promise(resolve => {
|
|
227
|
+
const worksheets = this._worksheets.filter(Boolean);
|
|
228
|
+
// In the streaming path, ZIP entries use ws.id which is always sequential.
|
|
229
|
+
// Set fileIndex = id to satisfy the ContentTypesXform contract.
|
|
230
|
+
worksheets.forEach((ws) => {
|
|
231
|
+
ws.fileIndex = ws.id;
|
|
232
|
+
});
|
|
227
233
|
const model = {
|
|
228
|
-
worksheets
|
|
234
|
+
worksheets,
|
|
229
235
|
sharedStrings: this.sharedStrings,
|
|
230
236
|
commentRefs: this.commentRefs,
|
|
231
237
|
media: this.media,
|
|
@@ -29,11 +29,9 @@ class ContentTypesXform extends BaseXform {
|
|
|
29
29
|
PartName: toContentTypesPartName(OOXML_PATHS.xlWorkbook),
|
|
30
30
|
ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"
|
|
31
31
|
});
|
|
32
|
-
model.worksheets.forEach((worksheet
|
|
33
|
-
// Use fileIndex if set, otherwise use sequential index (1-based)
|
|
34
|
-
const fileIndex = worksheet.fileIndex || index + 1;
|
|
32
|
+
model.worksheets.forEach((worksheet) => {
|
|
35
33
|
xmlStream.leafNode("Override", {
|
|
36
|
-
PartName: toContentTypesPartName(worksheetPath(fileIndex)),
|
|
34
|
+
PartName: toContentTypesPartName(worksheetPath(worksheet.fileIndex)),
|
|
37
35
|
ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"
|
|
38
36
|
});
|
|
39
37
|
});
|
|
@@ -167,25 +167,30 @@ class WorkSheetXform extends BaseXform {
|
|
|
167
167
|
});
|
|
168
168
|
});
|
|
169
169
|
// prepare comment relationships
|
|
170
|
+
// Use fileIndex (sequential 1-based) for file naming instead of model.id
|
|
171
|
+
// (the workbook-level sheet ID) because model.id can have gaps when sheets
|
|
172
|
+
// have been deleted, causing a mismatch between the relationship targets
|
|
173
|
+
// and the actual ZIP entry paths written by addWorksheets().
|
|
174
|
+
const { fileIndex } = model;
|
|
170
175
|
if (model.comments.length > 0) {
|
|
171
176
|
const comment = {
|
|
172
177
|
Id: nextRid(rels),
|
|
173
178
|
Type: RelType.Comments,
|
|
174
|
-
Target: commentsRelTargetFromWorksheet(
|
|
179
|
+
Target: commentsRelTargetFromWorksheet(fileIndex)
|
|
175
180
|
};
|
|
176
181
|
rels.push(comment);
|
|
177
182
|
const vmlDrawing = {
|
|
178
183
|
Id: nextRid(rels),
|
|
179
184
|
Type: RelType.VmlDrawing,
|
|
180
|
-
Target: vmlDrawingRelTargetFromWorksheet(
|
|
185
|
+
Target: vmlDrawingRelTargetFromWorksheet(fileIndex)
|
|
181
186
|
};
|
|
182
187
|
rels.push(vmlDrawing);
|
|
183
188
|
model.comments.forEach(item => {
|
|
184
189
|
item.refAddress = colCache.decodeAddress(item.ref);
|
|
185
190
|
});
|
|
186
191
|
options.commentRefs.push({
|
|
187
|
-
commentName: `comments${
|
|
188
|
-
vmlDrawing: `vmlDrawing${
|
|
192
|
+
commentName: `comments${fileIndex}`,
|
|
193
|
+
vmlDrawing: `vmlDrawing${fileIndex}`
|
|
189
194
|
});
|
|
190
195
|
}
|
|
191
196
|
// Handle pre-loaded drawing (from file read) that may contain charts or other non-image content.
|
|
@@ -338,7 +343,7 @@ class WorkSheetXform extends BaseXform {
|
|
|
338
343
|
rels.push({
|
|
339
344
|
Id: nextRid(rels),
|
|
340
345
|
Type: RelType.VmlDrawing,
|
|
341
|
-
Target: vmlDrawingRelTargetFromWorksheet(
|
|
346
|
+
Target: vmlDrawingRelTargetFromWorksheet(fileIndex)
|
|
342
347
|
});
|
|
343
348
|
}
|
|
344
349
|
// Add hidden DrawingML shapes that bridge to the VML shape ids.
|
|
@@ -33,7 +33,7 @@ import { bufferToString, base64ToUint8Array } from "../../../utils/utils.browser
|
|
|
33
33
|
import { StreamingZip, ZipDeflateFile } from "../../archive/zip/stream.js";
|
|
34
34
|
import { ZipParser } from "../../archive/unzip/zip-parser.js";
|
|
35
35
|
import { PassThrough, concatUint8Arrays } from "../../stream/index.browser.js";
|
|
36
|
-
import { commentsPath, commentsRelTargetFromWorksheetName, ctrlPropPath, drawingPath, drawingRelsPath, OOXML_REL_TARGETS, pivotTableRelTargetFromWorksheetName, pivotCacheDefinitionRelTargetFromWorkbook, getCommentsIndexFromPath, getDrawingNameFromPath, getDrawingNameFromRelsPath, getMediaFilenameFromPath, mediaPath, getPivotCacheDefinitionNameFromPath, getPivotCacheDefinitionNameFromRelsPath, getPivotCacheRecordsNameFromPath, getPivotTableNameFromPath, getPivotTableNameFromRelsPath, pivotCacheDefinitionPath, pivotCacheDefinitionRelsPath, pivotCacheDefinitionRelTargetFromPivotTable, pivotCacheRecordsPath, pivotCacheRecordsRelTarget, pivotTablePath, pivotTableRelsPath, getTableNameFromPath, tablePath, tableRelTargetFromWorksheetName, themePath, getThemeNameFromPath, getVmlDrawingNameFromPath, getWorksheetNoFromWorksheetPath, getWorksheetNoFromWorksheetRelsPath, isBinaryEntryPath, normalizeZipPath, OOXML_PATHS, vmlDrawingRelTargetFromWorksheetName, vmlDrawingPath, worksheetPath, worksheetRelsPath } from "../utils/ooxml-paths.js";
|
|
36
|
+
import { commentsPath, commentsRelTargetFromWorksheetName, ctrlPropPath, drawingPath, drawingRelsPath, OOXML_REL_TARGETS, pivotTableRelTargetFromWorksheetName, pivotCacheDefinitionRelTargetFromWorkbook, getCommentsIndexFromPath, getDrawingNameFromPath, getDrawingNameFromRelsPath, getMediaFilenameFromPath, mediaPath, getPivotCacheDefinitionNameFromPath, getPivotCacheDefinitionNameFromRelsPath, getPivotCacheRecordsNameFromPath, getPivotTableNameFromPath, getPivotTableNameFromRelsPath, pivotCacheDefinitionPath, pivotCacheDefinitionRelsPath, pivotCacheDefinitionRelTargetFromPivotTable, pivotCacheRecordsPath, pivotCacheRecordsRelTarget, pivotTablePath, pivotTableRelsPath, getTableNameFromPath, tablePath, tableRelTargetFromWorksheetName, themePath, getThemeNameFromPath, getVmlDrawingNameFromPath, getWorksheetNoFromWorksheetPath, getWorksheetNoFromWorksheetRelsPath, isBinaryEntryPath, normalizeZipPath, OOXML_PATHS, vmlDrawingRelTargetFromWorksheetName, vmlDrawingPath, worksheetPath, worksheetRelsPath, worksheetRelTarget } from "../utils/ooxml-paths.js";
|
|
37
37
|
import { PassthroughManager } from "../utils/passthrough-manager.js";
|
|
38
38
|
class StreamingZipWriterAdapter {
|
|
39
39
|
constructor(options) {
|
|
@@ -1050,13 +1050,13 @@ class XLSX {
|
|
|
1050
1050
|
});
|
|
1051
1051
|
}
|
|
1052
1052
|
});
|
|
1053
|
-
model.worksheets.forEach((worksheet
|
|
1053
|
+
model.worksheets.forEach((worksheet) => {
|
|
1054
1054
|
worksheet.rId = `rId${count++}`;
|
|
1055
|
-
|
|
1055
|
+
// fileIndex is assigned once in prepareModel() — use it directly
|
|
1056
1056
|
relationships.push({
|
|
1057
1057
|
Id: worksheet.rId,
|
|
1058
1058
|
Type: XLSX.RelType.Worksheet,
|
|
1059
|
-
Target:
|
|
1059
|
+
Target: worksheetRelTarget(worksheet.fileIndex)
|
|
1060
1060
|
});
|
|
1061
1061
|
});
|
|
1062
1062
|
const xform = new RelationshipsXform();
|
|
@@ -1091,8 +1091,8 @@ class XLSX {
|
|
|
1091
1091
|
const commentsXform = new CommentsXform();
|
|
1092
1092
|
const vmlDrawingXform = new VmlDrawingXform();
|
|
1093
1093
|
const ctrlPropXform = new CtrlPropXform();
|
|
1094
|
-
model.worksheets.forEach((worksheet
|
|
1095
|
-
const fileIndex = worksheet
|
|
1094
|
+
model.worksheets.forEach((worksheet) => {
|
|
1095
|
+
const { fileIndex } = worksheet;
|
|
1096
1096
|
let xmlStream = new XmlStream();
|
|
1097
1097
|
worksheetXform.render(xmlStream, worksheet);
|
|
1098
1098
|
zip.append(xmlStream.xml, { name: worksheetPath(fileIndex) });
|
|
@@ -1299,7 +1299,12 @@ class XLSX {
|
|
|
1299
1299
|
worksheetOptions.formControlRefs = model.formControlRefs = [];
|
|
1300
1300
|
let tableCount = 0;
|
|
1301
1301
|
model.tables = [];
|
|
1302
|
-
model.worksheets.forEach((worksheet) => {
|
|
1302
|
+
model.worksheets.forEach((worksheet, index) => {
|
|
1303
|
+
// Assign fileIndex early so that worksheet-xform.prepare() can use it
|
|
1304
|
+
// for comment/VML relationship targets and content type names.
|
|
1305
|
+
// This ensures consistency with addWorksheets() which writes ZIP entries
|
|
1306
|
+
// using the same fileIndex.
|
|
1307
|
+
worksheet.fileIndex = index + 1;
|
|
1303
1308
|
worksheet.tables.forEach((table) => {
|
|
1304
1309
|
tableCount++;
|
|
1305
1310
|
table.target = `table${tableCount}.xml`;
|
|
@@ -227,8 +227,14 @@ class WorkbookWriterBase {
|
|
|
227
227
|
}
|
|
228
228
|
addContentTypes() {
|
|
229
229
|
return new Promise(resolve => {
|
|
230
|
+
const worksheets = this._worksheets.filter(Boolean);
|
|
231
|
+
// In the streaming path, ZIP entries use ws.id which is always sequential.
|
|
232
|
+
// Set fileIndex = id to satisfy the ContentTypesXform contract.
|
|
233
|
+
worksheets.forEach((ws) => {
|
|
234
|
+
ws.fileIndex = ws.id;
|
|
235
|
+
});
|
|
230
236
|
const model = {
|
|
231
|
-
worksheets
|
|
237
|
+
worksheets,
|
|
232
238
|
sharedStrings: this.sharedStrings,
|
|
233
239
|
commentRefs: this.commentRefs,
|
|
234
240
|
media: this.media,
|
|
@@ -32,11 +32,9 @@ class ContentTypesXform extends base_xform_1.BaseXform {
|
|
|
32
32
|
PartName: (0, ooxml_paths_1.toContentTypesPartName)(ooxml_paths_1.OOXML_PATHS.xlWorkbook),
|
|
33
33
|
ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"
|
|
34
34
|
});
|
|
35
|
-
model.worksheets.forEach((worksheet
|
|
36
|
-
// Use fileIndex if set, otherwise use sequential index (1-based)
|
|
37
|
-
const fileIndex = worksheet.fileIndex || index + 1;
|
|
35
|
+
model.worksheets.forEach((worksheet) => {
|
|
38
36
|
xmlStream.leafNode("Override", {
|
|
39
|
-
PartName: (0, ooxml_paths_1.toContentTypesPartName)((0, ooxml_paths_1.worksheetPath)(fileIndex)),
|
|
37
|
+
PartName: (0, ooxml_paths_1.toContentTypesPartName)((0, ooxml_paths_1.worksheetPath)(worksheet.fileIndex)),
|
|
40
38
|
ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"
|
|
41
39
|
});
|
|
42
40
|
});
|
|
@@ -170,25 +170,30 @@ class WorkSheetXform extends base_xform_1.BaseXform {
|
|
|
170
170
|
});
|
|
171
171
|
});
|
|
172
172
|
// prepare comment relationships
|
|
173
|
+
// Use fileIndex (sequential 1-based) for file naming instead of model.id
|
|
174
|
+
// (the workbook-level sheet ID) because model.id can have gaps when sheets
|
|
175
|
+
// have been deleted, causing a mismatch between the relationship targets
|
|
176
|
+
// and the actual ZIP entry paths written by addWorksheets().
|
|
177
|
+
const { fileIndex } = model;
|
|
173
178
|
if (model.comments.length > 0) {
|
|
174
179
|
const comment = {
|
|
175
180
|
Id: nextRid(rels),
|
|
176
181
|
Type: rel_type_1.RelType.Comments,
|
|
177
|
-
Target: (0, ooxml_paths_1.commentsRelTargetFromWorksheet)(
|
|
182
|
+
Target: (0, ooxml_paths_1.commentsRelTargetFromWorksheet)(fileIndex)
|
|
178
183
|
};
|
|
179
184
|
rels.push(comment);
|
|
180
185
|
const vmlDrawing = {
|
|
181
186
|
Id: nextRid(rels),
|
|
182
187
|
Type: rel_type_1.RelType.VmlDrawing,
|
|
183
|
-
Target: (0, ooxml_paths_1.vmlDrawingRelTargetFromWorksheet)(
|
|
188
|
+
Target: (0, ooxml_paths_1.vmlDrawingRelTargetFromWorksheet)(fileIndex)
|
|
184
189
|
};
|
|
185
190
|
rels.push(vmlDrawing);
|
|
186
191
|
model.comments.forEach(item => {
|
|
187
192
|
item.refAddress = col_cache_1.colCache.decodeAddress(item.ref);
|
|
188
193
|
});
|
|
189
194
|
options.commentRefs.push({
|
|
190
|
-
commentName: `comments${
|
|
191
|
-
vmlDrawing: `vmlDrawing${
|
|
195
|
+
commentName: `comments${fileIndex}`,
|
|
196
|
+
vmlDrawing: `vmlDrawing${fileIndex}`
|
|
192
197
|
});
|
|
193
198
|
}
|
|
194
199
|
// Handle pre-loaded drawing (from file read) that may contain charts or other non-image content.
|
|
@@ -341,7 +346,7 @@ class WorkSheetXform extends base_xform_1.BaseXform {
|
|
|
341
346
|
rels.push({
|
|
342
347
|
Id: nextRid(rels),
|
|
343
348
|
Type: rel_type_1.RelType.VmlDrawing,
|
|
344
|
-
Target: (0, ooxml_paths_1.vmlDrawingRelTargetFromWorksheet)(
|
|
349
|
+
Target: (0, ooxml_paths_1.vmlDrawingRelTargetFromWorksheet)(fileIndex)
|
|
345
350
|
});
|
|
346
351
|
}
|
|
347
352
|
// Add hidden DrawingML shapes that bridge to the VML shape ids.
|
|
@@ -1053,13 +1053,13 @@ class XLSX {
|
|
|
1053
1053
|
});
|
|
1054
1054
|
}
|
|
1055
1055
|
});
|
|
1056
|
-
model.worksheets.forEach((worksheet
|
|
1056
|
+
model.worksheets.forEach((worksheet) => {
|
|
1057
1057
|
worksheet.rId = `rId${count++}`;
|
|
1058
|
-
|
|
1058
|
+
// fileIndex is assigned once in prepareModel() — use it directly
|
|
1059
1059
|
relationships.push({
|
|
1060
1060
|
Id: worksheet.rId,
|
|
1061
1061
|
Type: XLSX.RelType.Worksheet,
|
|
1062
|
-
Target:
|
|
1062
|
+
Target: (0, ooxml_paths_1.worksheetRelTarget)(worksheet.fileIndex)
|
|
1063
1063
|
});
|
|
1064
1064
|
});
|
|
1065
1065
|
const xform = new relationships_xform_1.RelationshipsXform();
|
|
@@ -1094,8 +1094,8 @@ class XLSX {
|
|
|
1094
1094
|
const commentsXform = new comments_xform_1.CommentsXform();
|
|
1095
1095
|
const vmlDrawingXform = new vml_drawing_xform_1.VmlDrawingXform();
|
|
1096
1096
|
const ctrlPropXform = new ctrl_prop_xform_1.CtrlPropXform();
|
|
1097
|
-
model.worksheets.forEach((worksheet
|
|
1098
|
-
const fileIndex = worksheet
|
|
1097
|
+
model.worksheets.forEach((worksheet) => {
|
|
1098
|
+
const { fileIndex } = worksheet;
|
|
1099
1099
|
let xmlStream = new xml_stream_1.XmlStream();
|
|
1100
1100
|
worksheetXform.render(xmlStream, worksheet);
|
|
1101
1101
|
zip.append(xmlStream.xml, { name: (0, ooxml_paths_1.worksheetPath)(fileIndex) });
|
|
@@ -1302,7 +1302,12 @@ class XLSX {
|
|
|
1302
1302
|
worksheetOptions.formControlRefs = model.formControlRefs = [];
|
|
1303
1303
|
let tableCount = 0;
|
|
1304
1304
|
model.tables = [];
|
|
1305
|
-
model.worksheets.forEach((worksheet) => {
|
|
1305
|
+
model.worksheets.forEach((worksheet, index) => {
|
|
1306
|
+
// Assign fileIndex early so that worksheet-xform.prepare() can use it
|
|
1307
|
+
// for comment/VML relationship targets and content type names.
|
|
1308
|
+
// This ensures consistency with addWorksheets() which writes ZIP entries
|
|
1309
|
+
// using the same fileIndex.
|
|
1310
|
+
worksheet.fileIndex = index + 1;
|
|
1306
1311
|
worksheet.tables.forEach((table) => {
|
|
1307
1312
|
tableCount++;
|
|
1308
1313
|
table.target = `table${tableCount}.xml`;
|
|
@@ -224,8 +224,14 @@ export class WorkbookWriterBase {
|
|
|
224
224
|
}
|
|
225
225
|
addContentTypes() {
|
|
226
226
|
return new Promise(resolve => {
|
|
227
|
+
const worksheets = this._worksheets.filter(Boolean);
|
|
228
|
+
// In the streaming path, ZIP entries use ws.id which is always sequential.
|
|
229
|
+
// Set fileIndex = id to satisfy the ContentTypesXform contract.
|
|
230
|
+
worksheets.forEach((ws) => {
|
|
231
|
+
ws.fileIndex = ws.id;
|
|
232
|
+
});
|
|
227
233
|
const model = {
|
|
228
|
-
worksheets
|
|
234
|
+
worksheets,
|
|
229
235
|
sharedStrings: this.sharedStrings,
|
|
230
236
|
commentRefs: this.commentRefs,
|
|
231
237
|
media: this.media,
|
|
@@ -29,11 +29,9 @@ class ContentTypesXform extends BaseXform {
|
|
|
29
29
|
PartName: toContentTypesPartName(OOXML_PATHS.xlWorkbook),
|
|
30
30
|
ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"
|
|
31
31
|
});
|
|
32
|
-
model.worksheets.forEach((worksheet
|
|
33
|
-
// Use fileIndex if set, otherwise use sequential index (1-based)
|
|
34
|
-
const fileIndex = worksheet.fileIndex || index + 1;
|
|
32
|
+
model.worksheets.forEach((worksheet) => {
|
|
35
33
|
xmlStream.leafNode("Override", {
|
|
36
|
-
PartName: toContentTypesPartName(worksheetPath(fileIndex)),
|
|
34
|
+
PartName: toContentTypesPartName(worksheetPath(worksheet.fileIndex)),
|
|
37
35
|
ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"
|
|
38
36
|
});
|
|
39
37
|
});
|
|
@@ -167,25 +167,30 @@ class WorkSheetXform extends BaseXform {
|
|
|
167
167
|
});
|
|
168
168
|
});
|
|
169
169
|
// prepare comment relationships
|
|
170
|
+
// Use fileIndex (sequential 1-based) for file naming instead of model.id
|
|
171
|
+
// (the workbook-level sheet ID) because model.id can have gaps when sheets
|
|
172
|
+
// have been deleted, causing a mismatch between the relationship targets
|
|
173
|
+
// and the actual ZIP entry paths written by addWorksheets().
|
|
174
|
+
const { fileIndex } = model;
|
|
170
175
|
if (model.comments.length > 0) {
|
|
171
176
|
const comment = {
|
|
172
177
|
Id: nextRid(rels),
|
|
173
178
|
Type: RelType.Comments,
|
|
174
|
-
Target: commentsRelTargetFromWorksheet(
|
|
179
|
+
Target: commentsRelTargetFromWorksheet(fileIndex)
|
|
175
180
|
};
|
|
176
181
|
rels.push(comment);
|
|
177
182
|
const vmlDrawing = {
|
|
178
183
|
Id: nextRid(rels),
|
|
179
184
|
Type: RelType.VmlDrawing,
|
|
180
|
-
Target: vmlDrawingRelTargetFromWorksheet(
|
|
185
|
+
Target: vmlDrawingRelTargetFromWorksheet(fileIndex)
|
|
181
186
|
};
|
|
182
187
|
rels.push(vmlDrawing);
|
|
183
188
|
model.comments.forEach(item => {
|
|
184
189
|
item.refAddress = colCache.decodeAddress(item.ref);
|
|
185
190
|
});
|
|
186
191
|
options.commentRefs.push({
|
|
187
|
-
commentName: `comments${
|
|
188
|
-
vmlDrawing: `vmlDrawing${
|
|
192
|
+
commentName: `comments${fileIndex}`,
|
|
193
|
+
vmlDrawing: `vmlDrawing${fileIndex}`
|
|
189
194
|
});
|
|
190
195
|
}
|
|
191
196
|
// Handle pre-loaded drawing (from file read) that may contain charts or other non-image content.
|
|
@@ -338,7 +343,7 @@ class WorkSheetXform extends BaseXform {
|
|
|
338
343
|
rels.push({
|
|
339
344
|
Id: nextRid(rels),
|
|
340
345
|
Type: RelType.VmlDrawing,
|
|
341
|
-
Target: vmlDrawingRelTargetFromWorksheet(
|
|
346
|
+
Target: vmlDrawingRelTargetFromWorksheet(fileIndex)
|
|
342
347
|
});
|
|
343
348
|
}
|
|
344
349
|
// Add hidden DrawingML shapes that bridge to the VML shape ids.
|
|
@@ -33,7 +33,7 @@ import { bufferToString, base64ToUint8Array } from "../../../utils/utils.js";
|
|
|
33
33
|
import { StreamingZip, ZipDeflateFile } from "../../archive/zip/stream.js";
|
|
34
34
|
import { ZipParser } from "../../archive/unzip/zip-parser.js";
|
|
35
35
|
import { PassThrough, concatUint8Arrays } from "../../stream/index.js";
|
|
36
|
-
import { commentsPath, commentsRelTargetFromWorksheetName, ctrlPropPath, drawingPath, drawingRelsPath, OOXML_REL_TARGETS, pivotTableRelTargetFromWorksheetName, pivotCacheDefinitionRelTargetFromWorkbook, getCommentsIndexFromPath, getDrawingNameFromPath, getDrawingNameFromRelsPath, getMediaFilenameFromPath, mediaPath, getPivotCacheDefinitionNameFromPath, getPivotCacheDefinitionNameFromRelsPath, getPivotCacheRecordsNameFromPath, getPivotTableNameFromPath, getPivotTableNameFromRelsPath, pivotCacheDefinitionPath, pivotCacheDefinitionRelsPath, pivotCacheDefinitionRelTargetFromPivotTable, pivotCacheRecordsPath, pivotCacheRecordsRelTarget, pivotTablePath, pivotTableRelsPath, getTableNameFromPath, tablePath, tableRelTargetFromWorksheetName, themePath, getThemeNameFromPath, getVmlDrawingNameFromPath, getWorksheetNoFromWorksheetPath, getWorksheetNoFromWorksheetRelsPath, isBinaryEntryPath, normalizeZipPath, OOXML_PATHS, vmlDrawingRelTargetFromWorksheetName, vmlDrawingPath, worksheetPath, worksheetRelsPath } from "../utils/ooxml-paths.js";
|
|
36
|
+
import { commentsPath, commentsRelTargetFromWorksheetName, ctrlPropPath, drawingPath, drawingRelsPath, OOXML_REL_TARGETS, pivotTableRelTargetFromWorksheetName, pivotCacheDefinitionRelTargetFromWorkbook, getCommentsIndexFromPath, getDrawingNameFromPath, getDrawingNameFromRelsPath, getMediaFilenameFromPath, mediaPath, getPivotCacheDefinitionNameFromPath, getPivotCacheDefinitionNameFromRelsPath, getPivotCacheRecordsNameFromPath, getPivotTableNameFromPath, getPivotTableNameFromRelsPath, pivotCacheDefinitionPath, pivotCacheDefinitionRelsPath, pivotCacheDefinitionRelTargetFromPivotTable, pivotCacheRecordsPath, pivotCacheRecordsRelTarget, pivotTablePath, pivotTableRelsPath, getTableNameFromPath, tablePath, tableRelTargetFromWorksheetName, themePath, getThemeNameFromPath, getVmlDrawingNameFromPath, getWorksheetNoFromWorksheetPath, getWorksheetNoFromWorksheetRelsPath, isBinaryEntryPath, normalizeZipPath, OOXML_PATHS, vmlDrawingRelTargetFromWorksheetName, vmlDrawingPath, worksheetPath, worksheetRelsPath, worksheetRelTarget } from "../utils/ooxml-paths.js";
|
|
37
37
|
import { PassthroughManager } from "../utils/passthrough-manager.js";
|
|
38
38
|
class StreamingZipWriterAdapter {
|
|
39
39
|
constructor(options) {
|
|
@@ -1050,13 +1050,13 @@ class XLSX {
|
|
|
1050
1050
|
});
|
|
1051
1051
|
}
|
|
1052
1052
|
});
|
|
1053
|
-
model.worksheets.forEach((worksheet
|
|
1053
|
+
model.worksheets.forEach((worksheet) => {
|
|
1054
1054
|
worksheet.rId = `rId${count++}`;
|
|
1055
|
-
|
|
1055
|
+
// fileIndex is assigned once in prepareModel() — use it directly
|
|
1056
1056
|
relationships.push({
|
|
1057
1057
|
Id: worksheet.rId,
|
|
1058
1058
|
Type: XLSX.RelType.Worksheet,
|
|
1059
|
-
Target:
|
|
1059
|
+
Target: worksheetRelTarget(worksheet.fileIndex)
|
|
1060
1060
|
});
|
|
1061
1061
|
});
|
|
1062
1062
|
const xform = new RelationshipsXform();
|
|
@@ -1091,8 +1091,8 @@ class XLSX {
|
|
|
1091
1091
|
const commentsXform = new CommentsXform();
|
|
1092
1092
|
const vmlDrawingXform = new VmlDrawingXform();
|
|
1093
1093
|
const ctrlPropXform = new CtrlPropXform();
|
|
1094
|
-
model.worksheets.forEach((worksheet
|
|
1095
|
-
const fileIndex = worksheet
|
|
1094
|
+
model.worksheets.forEach((worksheet) => {
|
|
1095
|
+
const { fileIndex } = worksheet;
|
|
1096
1096
|
let xmlStream = new XmlStream();
|
|
1097
1097
|
worksheetXform.render(xmlStream, worksheet);
|
|
1098
1098
|
zip.append(xmlStream.xml, { name: worksheetPath(fileIndex) });
|
|
@@ -1299,7 +1299,12 @@ class XLSX {
|
|
|
1299
1299
|
worksheetOptions.formControlRefs = model.formControlRefs = [];
|
|
1300
1300
|
let tableCount = 0;
|
|
1301
1301
|
model.tables = [];
|
|
1302
|
-
model.worksheets.forEach((worksheet) => {
|
|
1302
|
+
model.worksheets.forEach((worksheet, index) => {
|
|
1303
|
+
// Assign fileIndex early so that worksheet-xform.prepare() can use it
|
|
1304
|
+
// for comment/VML relationship targets and content type names.
|
|
1305
|
+
// This ensures consistency with addWorksheets() which writes ZIP entries
|
|
1306
|
+
// using the same fileIndex.
|
|
1307
|
+
worksheet.fileIndex = index + 1;
|
|
1303
1308
|
worksheet.tables.forEach((table) => {
|
|
1304
1309
|
tableCount++;
|
|
1305
1310
|
table.target = `table${tableCount}.xml`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @cj-tech-master/excelts v5.1.
|
|
2
|
+
* @cj-tech-master/excelts v5.1.4
|
|
3
3
|
* TypeScript Excel Workbook Manager - Read and Write xlsx and csv Files.
|
|
4
4
|
* (c) 2026 cjnoname
|
|
5
5
|
* Released under the MIT License
|
|
@@ -10733,10 +10733,9 @@ var ExcelTS = (function(exports) {
|
|
|
10733
10733
|
PartName: toContentTypesPartName(OOXML_PATHS.xlWorkbook),
|
|
10734
10734
|
ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"
|
|
10735
10735
|
});
|
|
10736
|
-
model.worksheets.forEach((worksheet
|
|
10737
|
-
const fileIndex = worksheet.fileIndex || index + 1;
|
|
10736
|
+
model.worksheets.forEach((worksheet) => {
|
|
10738
10737
|
xmlStream.leafNode("Override", {
|
|
10739
|
-
PartName: toContentTypesPartName(worksheetPath(fileIndex)),
|
|
10738
|
+
PartName: toContentTypesPartName(worksheetPath(worksheet.fileIndex)),
|
|
10740
10739
|
ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"
|
|
10741
10740
|
});
|
|
10742
10741
|
});
|
|
@@ -14239,25 +14238,26 @@ var ExcelTS = (function(exports) {
|
|
|
14239
14238
|
TargetMode: "External"
|
|
14240
14239
|
});
|
|
14241
14240
|
});
|
|
14241
|
+
const { fileIndex } = model;
|
|
14242
14242
|
if (model.comments.length > 0) {
|
|
14243
14243
|
const comment = {
|
|
14244
14244
|
Id: nextRid(rels),
|
|
14245
14245
|
Type: RelType.Comments,
|
|
14246
|
-
Target: commentsRelTargetFromWorksheet(
|
|
14246
|
+
Target: commentsRelTargetFromWorksheet(fileIndex)
|
|
14247
14247
|
};
|
|
14248
14248
|
rels.push(comment);
|
|
14249
14249
|
const vmlDrawing = {
|
|
14250
14250
|
Id: nextRid(rels),
|
|
14251
14251
|
Type: RelType.VmlDrawing,
|
|
14252
|
-
Target: vmlDrawingRelTargetFromWorksheet(
|
|
14252
|
+
Target: vmlDrawingRelTargetFromWorksheet(fileIndex)
|
|
14253
14253
|
};
|
|
14254
14254
|
rels.push(vmlDrawing);
|
|
14255
14255
|
model.comments.forEach((item) => {
|
|
14256
14256
|
item.refAddress = colCache.decodeAddress(item.ref);
|
|
14257
14257
|
});
|
|
14258
14258
|
options.commentRefs.push({
|
|
14259
|
-
commentName: `comments${
|
|
14260
|
-
vmlDrawing: `vmlDrawing${
|
|
14259
|
+
commentName: `comments${fileIndex}`,
|
|
14260
|
+
vmlDrawing: `vmlDrawing${fileIndex}`
|
|
14261
14261
|
});
|
|
14262
14262
|
}
|
|
14263
14263
|
if (model.drawing && model.drawing.anchors) {
|
|
@@ -14375,7 +14375,7 @@ var ExcelTS = (function(exports) {
|
|
|
14375
14375
|
if (model.comments.length === 0) rels.push({
|
|
14376
14376
|
Id: nextRid(rels),
|
|
14377
14377
|
Type: RelType.VmlDrawing,
|
|
14378
|
-
Target: vmlDrawingRelTargetFromWorksheet(
|
|
14378
|
+
Target: vmlDrawingRelTargetFromWorksheet(fileIndex)
|
|
14379
14379
|
});
|
|
14380
14380
|
const toNativePos = (p) => ({
|
|
14381
14381
|
nativeCol: p.col,
|
|
@@ -22319,13 +22319,12 @@ var ExcelTS = (function(exports) {
|
|
|
22319
22319
|
});
|
|
22320
22320
|
}
|
|
22321
22321
|
});
|
|
22322
|
-
model.worksheets.forEach((worksheet
|
|
22322
|
+
model.worksheets.forEach((worksheet) => {
|
|
22323
22323
|
worksheet.rId = `rId${count++}`;
|
|
22324
|
-
worksheet.fileIndex = index + 1;
|
|
22325
22324
|
relationships.push({
|
|
22326
22325
|
Id: worksheet.rId,
|
|
22327
22326
|
Type: XLSX.RelType.Worksheet,
|
|
22328
|
-
Target:
|
|
22327
|
+
Target: worksheetRelTarget(worksheet.fileIndex)
|
|
22329
22328
|
});
|
|
22330
22329
|
});
|
|
22331
22330
|
const xml = new RelationshipsXform().toXml(relationships);
|
|
@@ -22353,8 +22352,8 @@ var ExcelTS = (function(exports) {
|
|
|
22353
22352
|
const commentsXform = new CommentsXform();
|
|
22354
22353
|
const vmlDrawingXform = new VmlDrawingXform();
|
|
22355
22354
|
const ctrlPropXform = new CtrlPropXform();
|
|
22356
|
-
model.worksheets.forEach((worksheet
|
|
22357
|
-
const fileIndex = worksheet
|
|
22355
|
+
model.worksheets.forEach((worksheet) => {
|
|
22356
|
+
const { fileIndex } = worksheet;
|
|
22358
22357
|
let xmlStream = new XmlStream();
|
|
22359
22358
|
worksheetXform.render(xmlStream, worksheet);
|
|
22360
22359
|
zip.append(xmlStream.xml, { name: worksheetPath(fileIndex) });
|
|
@@ -22517,7 +22516,8 @@ var ExcelTS = (function(exports) {
|
|
|
22517
22516
|
worksheetOptions.formControlRefs = model.formControlRefs = [];
|
|
22518
22517
|
let tableCount = 0;
|
|
22519
22518
|
model.tables = [];
|
|
22520
|
-
model.worksheets.forEach((worksheet) => {
|
|
22519
|
+
model.worksheets.forEach((worksheet, index) => {
|
|
22520
|
+
worksheet.fileIndex = index + 1;
|
|
22521
22521
|
worksheet.tables.forEach((table) => {
|
|
22522
22522
|
tableCount++;
|
|
22523
22523
|
table.target = `table${tableCount}.xml`;
|
|
@@ -24646,8 +24646,12 @@ var ExcelTS = (function(exports) {
|
|
|
24646
24646
|
}
|
|
24647
24647
|
addContentTypes() {
|
|
24648
24648
|
return new Promise((resolve) => {
|
|
24649
|
+
const worksheets = this._worksheets.filter(Boolean);
|
|
24650
|
+
worksheets.forEach((ws) => {
|
|
24651
|
+
ws.fileIndex = ws.id;
|
|
24652
|
+
});
|
|
24649
24653
|
const model = {
|
|
24650
|
-
worksheets
|
|
24654
|
+
worksheets,
|
|
24651
24655
|
sharedStrings: this.sharedStrings,
|
|
24652
24656
|
commentRefs: this.commentRefs,
|
|
24653
24657
|
media: this.media,
|