@cj-tech-master/excelts 6.0.0 → 6.1.0
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/anchor.js +10 -4
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +13 -0
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +32 -1
- package/dist/browser/modules/excel/stream/worksheet-writer.d.ts +56 -2
- package/dist/browser/modules/excel/stream/worksheet-writer.js +90 -3
- package/dist/browser/modules/excel/utils/drawing-utils.d.ts +77 -0
- package/dist/browser/modules/excel/utils/drawing-utils.js +113 -0
- package/dist/browser/modules/excel/worksheet.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.d.ts +0 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +43 -64
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +2 -19
- package/dist/cjs/modules/excel/anchor.js +10 -4
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +31 -0
- package/dist/cjs/modules/excel/stream/worksheet-writer.js +89 -2
- package/dist/cjs/modules/excel/utils/drawing-utils.js +118 -0
- package/dist/cjs/modules/excel/worksheet.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +42 -63
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +2 -19
- package/dist/esm/modules/excel/anchor.js +10 -4
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +32 -1
- package/dist/esm/modules/excel/stream/worksheet-writer.js +90 -3
- package/dist/esm/modules/excel/utils/drawing-utils.js +113 -0
- package/dist/esm/modules/excel/worksheet.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +43 -64
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +2 -19
- package/dist/iife/excelts.iife.js +237 -73
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +34 -34
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +13 -0
- package/dist/types/modules/excel/stream/worksheet-writer.d.ts +56 -2
- package/dist/types/modules/excel/utils/drawing-utils.d.ts +77 -0
- package/dist/types/modules/excel/xlsx/xform/sheet/worksheet-xform.d.ts +0 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @cj-tech-master/excelts v6.
|
|
2
|
+
* @cj-tech-master/excelts v6.1.0
|
|
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
|
|
@@ -2520,18 +2520,20 @@ var ExcelTS = (function(exports) {
|
|
|
2520
2520
|
return new Anchor(void 0, model);
|
|
2521
2521
|
}
|
|
2522
2522
|
get col() {
|
|
2523
|
-
return this.nativeCol + Math.min(this.colWidth - 1, this.nativeColOff) / this.colWidth;
|
|
2523
|
+
return this.nativeColOff === 0 ? this.nativeCol : this.nativeCol + Math.min(this.colWidth - 1, this.nativeColOff) / this.colWidth;
|
|
2524
2524
|
}
|
|
2525
2525
|
set col(v) {
|
|
2526
2526
|
this.nativeCol = Math.floor(v);
|
|
2527
|
-
|
|
2527
|
+
const fraction = v - this.nativeCol;
|
|
2528
|
+
this.nativeColOff = fraction === 0 ? 0 : Math.floor(fraction * this.colWidth);
|
|
2528
2529
|
}
|
|
2529
2530
|
get row() {
|
|
2530
|
-
return this.nativeRow + Math.min(this.rowHeight - 1, this.nativeRowOff) / this.rowHeight;
|
|
2531
|
+
return this.nativeRowOff === 0 ? this.nativeRow : this.nativeRow + Math.min(this.rowHeight - 1, this.nativeRowOff) / this.rowHeight;
|
|
2531
2532
|
}
|
|
2532
2533
|
set row(v) {
|
|
2533
2534
|
this.nativeRow = Math.floor(v);
|
|
2534
|
-
|
|
2535
|
+
const fraction = v - this.nativeRow;
|
|
2536
|
+
this.nativeRowOff = fraction === 0 ? 0 : Math.floor(fraction * this.rowHeight);
|
|
2535
2537
|
}
|
|
2536
2538
|
get colWidth() {
|
|
2537
2539
|
return this.worksheet && this.worksheet.getColumn(this.nativeCol + 1) && this.worksheet.getColumn(this.nativeCol + 1).isCustomWidth ? Math.floor(this.worksheet.getColumn(this.nativeCol + 1).width * 1e4) : 64e4;
|
|
@@ -5257,7 +5259,7 @@ var ExcelTS = (function(exports) {
|
|
|
5257
5259
|
* Duplicate rows and insert new rows
|
|
5258
5260
|
*/
|
|
5259
5261
|
duplicateRow(rowNum, count, insert = false) {
|
|
5260
|
-
const rSrc = this.
|
|
5262
|
+
const rSrc = this.getRow(rowNum);
|
|
5261
5263
|
const inserts = Array.from({ length: count }).fill(rSrc.values);
|
|
5262
5264
|
const srcMerges = [];
|
|
5263
5265
|
for (const merge of Object.values(this._merges)) if (merge.top === rowNum && merge.bottom === rowNum) srcMerges.push(merge);
|
|
@@ -13440,6 +13442,94 @@ var ExcelTS = (function(exports) {
|
|
|
13440
13442
|
}
|
|
13441
13443
|
};
|
|
13442
13444
|
//#endregion
|
|
13445
|
+
//#region src/modules/excel/utils/drawing-utils.ts
|
|
13446
|
+
/**
|
|
13447
|
+
* Shared utilities for building drawing models (anchors + relationships)
|
|
13448
|
+
* used by both the streaming WorksheetWriter and the non-streaming WorkSheetXform.
|
|
13449
|
+
*
|
|
13450
|
+
* This eliminates the duplicated anchor/rel building logic and provides
|
|
13451
|
+
* a single, correct image-rel deduplication strategy.
|
|
13452
|
+
*/
|
|
13453
|
+
/**
|
|
13454
|
+
* Resolves a media filename into the drawing-level relative target path.
|
|
13455
|
+
*
|
|
13456
|
+
* In the non-streaming path, media entries have separate `name` and `extension`
|
|
13457
|
+
* fields (e.g. name="image0", extension="png").
|
|
13458
|
+
* In the streaming path, `name` already includes the extension (e.g. "image0.png").
|
|
13459
|
+
*
|
|
13460
|
+
* This function accepts both forms and returns e.g. `"../media/image0.png"`.
|
|
13461
|
+
*/
|
|
13462
|
+
function resolveMediaTarget(medium) {
|
|
13463
|
+
return mediaRelTargetFromRels(medium.name && medium.extension && medium.name.endsWith(`.${medium.extension}`) ? medium.name : `${medium.name}.${medium.extension}`);
|
|
13464
|
+
}
|
|
13465
|
+
/**
|
|
13466
|
+
* Build the drawing anchors and relationships from a list of image media entries.
|
|
13467
|
+
*
|
|
13468
|
+
* This is the core logic shared between:
|
|
13469
|
+
* - `WorksheetWriter._writeDrawing()` (streaming)
|
|
13470
|
+
* - `WorkSheetXform.prepare()` (non-streaming)
|
|
13471
|
+
*
|
|
13472
|
+
* It correctly deduplicates image rels: if the same `imageId` is used for
|
|
13473
|
+
* multiple anchors, only one image relationship is created and shared.
|
|
13474
|
+
*/
|
|
13475
|
+
function buildDrawingAnchorsAndRels(media, existingRels, options) {
|
|
13476
|
+
const anchors = [];
|
|
13477
|
+
const rels = [...existingRels];
|
|
13478
|
+
const imageRIdMap = {};
|
|
13479
|
+
for (const medium of media) {
|
|
13480
|
+
const imageId = String(medium.imageId);
|
|
13481
|
+
const bookImage = options.getBookImage(medium.imageId);
|
|
13482
|
+
if (!bookImage) continue;
|
|
13483
|
+
let rIdImage = imageRIdMap[imageId];
|
|
13484
|
+
if (!rIdImage) {
|
|
13485
|
+
rIdImage = options.nextRId(rels);
|
|
13486
|
+
imageRIdMap[imageId] = rIdImage;
|
|
13487
|
+
rels.push({
|
|
13488
|
+
Id: rIdImage,
|
|
13489
|
+
Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
|
13490
|
+
Target: resolveMediaTarget(bookImage)
|
|
13491
|
+
});
|
|
13492
|
+
}
|
|
13493
|
+
const anchor = {
|
|
13494
|
+
picture: { rId: rIdImage },
|
|
13495
|
+
range: medium.range
|
|
13496
|
+
};
|
|
13497
|
+
if (medium.hyperlinks && medium.hyperlinks.hyperlink) {
|
|
13498
|
+
const rIdHyperlink = options.nextRId(rels);
|
|
13499
|
+
anchor.picture.hyperlinks = {
|
|
13500
|
+
tooltip: medium.hyperlinks.tooltip,
|
|
13501
|
+
rId: rIdHyperlink
|
|
13502
|
+
};
|
|
13503
|
+
rels.push({
|
|
13504
|
+
Id: rIdHyperlink,
|
|
13505
|
+
Type: RelType.Hyperlink,
|
|
13506
|
+
Target: medium.hyperlinks.hyperlink,
|
|
13507
|
+
TargetMode: "External"
|
|
13508
|
+
});
|
|
13509
|
+
}
|
|
13510
|
+
anchors.push(anchor);
|
|
13511
|
+
}
|
|
13512
|
+
return {
|
|
13513
|
+
anchors,
|
|
13514
|
+
rels
|
|
13515
|
+
};
|
|
13516
|
+
}
|
|
13517
|
+
/**
|
|
13518
|
+
* Filter drawing anchors to remove invalid entries before XML generation.
|
|
13519
|
+
*
|
|
13520
|
+
* Shared between streaming `WorkbookWriterBase.addDrawings()` and
|
|
13521
|
+
* non-streaming `XLSX.addDrawings()`.
|
|
13522
|
+
*/
|
|
13523
|
+
function filterDrawingAnchors(anchors) {
|
|
13524
|
+
return anchors.filter((a) => {
|
|
13525
|
+
if (a == null) return false;
|
|
13526
|
+
if (a.range?.br && a.shape) return true;
|
|
13527
|
+
if (!a.range?.br && !a.picture) return false;
|
|
13528
|
+
if (a.range?.br && !a.picture && !a.shape) return false;
|
|
13529
|
+
return true;
|
|
13530
|
+
});
|
|
13531
|
+
}
|
|
13532
|
+
//#endregion
|
|
13443
13533
|
//#region src/modules/excel/xlsx/xform/sheet/worksheet-xform.ts
|
|
13444
13534
|
const mergeRule = (rule, extRule) => {
|
|
13445
13535
|
Object.keys(extRule).forEach((key) => {
|
|
@@ -13601,68 +13691,46 @@ var ExcelTS = (function(exports) {
|
|
|
13601
13691
|
Target: drawingRelTargetFromWorksheet(drawing.name)
|
|
13602
13692
|
});
|
|
13603
13693
|
}
|
|
13604
|
-
const
|
|
13605
|
-
|
|
13694
|
+
const backgroundMedia = [];
|
|
13695
|
+
const imageMedia = [];
|
|
13606
13696
|
model.media.forEach((medium) => {
|
|
13607
|
-
if (medium.type === "background")
|
|
13608
|
-
|
|
13609
|
-
|
|
13697
|
+
if (medium.type === "background") backgroundMedia.push(medium);
|
|
13698
|
+
else if (medium.type === "image") imageMedia.push(medium);
|
|
13699
|
+
});
|
|
13700
|
+
backgroundMedia.forEach((medium) => {
|
|
13701
|
+
const rId = nextRid(rels);
|
|
13702
|
+
const bookImage = options.media[medium.imageId];
|
|
13703
|
+
rels.push({
|
|
13704
|
+
Id: rId,
|
|
13705
|
+
Type: RelType.Image,
|
|
13706
|
+
Target: resolveMediaTarget(bookImage)
|
|
13707
|
+
});
|
|
13708
|
+
model.background = { rId };
|
|
13709
|
+
model.image = options.media[medium.imageId];
|
|
13710
|
+
});
|
|
13711
|
+
if (imageMedia.length > 0) {
|
|
13712
|
+
let { drawing } = model;
|
|
13713
|
+
if (!drawing) {
|
|
13714
|
+
drawing = model.drawing = {
|
|
13715
|
+
rId: nextRid(rels),
|
|
13716
|
+
name: `drawing${++options.drawingsCount}`,
|
|
13717
|
+
anchors: [],
|
|
13718
|
+
rels: []
|
|
13719
|
+
};
|
|
13720
|
+
options.drawings.push(drawing);
|
|
13610
13721
|
rels.push({
|
|
13611
|
-
Id: rId,
|
|
13612
|
-
Type:
|
|
13613
|
-
Target:
|
|
13722
|
+
Id: drawing.rId,
|
|
13723
|
+
Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
|
|
13724
|
+
Target: drawingRelTargetFromWorksheet(drawing.name)
|
|
13614
13725
|
});
|
|
13615
|
-
model.background = { rId };
|
|
13616
|
-
model.image = options.media[medium.imageId];
|
|
13617
|
-
} else if (medium.type === "image") {
|
|
13618
|
-
let { drawing } = model;
|
|
13619
|
-
bookImage = options.media[medium.imageId];
|
|
13620
|
-
if (!drawing) {
|
|
13621
|
-
drawing = model.drawing = {
|
|
13622
|
-
rId: nextRid(rels),
|
|
13623
|
-
name: `drawing${++options.drawingsCount}`,
|
|
13624
|
-
anchors: [],
|
|
13625
|
-
rels: []
|
|
13626
|
-
};
|
|
13627
|
-
options.drawings.push(drawing);
|
|
13628
|
-
rels.push({
|
|
13629
|
-
Id: drawing.rId,
|
|
13630
|
-
Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
|
|
13631
|
-
Target: drawingRelTargetFromWorksheet(drawing.name)
|
|
13632
|
-
});
|
|
13633
|
-
}
|
|
13634
|
-
let rIdImage = this.preImageId === medium.imageId ? drawingRelsHash[medium.imageId] : drawingRelsHash[drawing.rels.length];
|
|
13635
|
-
if (!rIdImage) {
|
|
13636
|
-
rIdImage = nextRid(drawing.rels);
|
|
13637
|
-
drawingRelsHash[drawing.rels.length] = rIdImage;
|
|
13638
|
-
drawing.rels.push({
|
|
13639
|
-
Id: rIdImage,
|
|
13640
|
-
Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
|
13641
|
-
Target: mediaRelTargetFromRels(`${bookImage.name}.${bookImage.extension}`)
|
|
13642
|
-
});
|
|
13643
|
-
}
|
|
13644
|
-
const anchor = {
|
|
13645
|
-
picture: { rId: rIdImage },
|
|
13646
|
-
range: medium.range
|
|
13647
|
-
};
|
|
13648
|
-
if (medium.hyperlinks && medium.hyperlinks.hyperlink) {
|
|
13649
|
-
const rIdHyperLink = nextRid(drawing.rels);
|
|
13650
|
-
drawingRelsHash[drawing.rels.length] = rIdHyperLink;
|
|
13651
|
-
anchor.picture.hyperlinks = {
|
|
13652
|
-
tooltip: medium.hyperlinks.tooltip,
|
|
13653
|
-
rId: rIdHyperLink
|
|
13654
|
-
};
|
|
13655
|
-
drawing.rels.push({
|
|
13656
|
-
Id: rIdHyperLink,
|
|
13657
|
-
Type: RelType.Hyperlink,
|
|
13658
|
-
Target: medium.hyperlinks.hyperlink,
|
|
13659
|
-
TargetMode: "External"
|
|
13660
|
-
});
|
|
13661
|
-
}
|
|
13662
|
-
this.preImageId = medium.imageId;
|
|
13663
|
-
drawing.anchors.push(anchor);
|
|
13664
13726
|
}
|
|
13665
|
-
|
|
13727
|
+
const result = buildDrawingAnchorsAndRels(imageMedia, drawing.rels, {
|
|
13728
|
+
getBookImage: (id) => options.media[id],
|
|
13729
|
+
nextRId: (currentRels) => nextRid(currentRels)
|
|
13730
|
+
});
|
|
13731
|
+
drawing.anchors.push(...result.anchors);
|
|
13732
|
+
drawing.rels = result.rels;
|
|
13733
|
+
}
|
|
13666
13734
|
model.tables.forEach((table) => {
|
|
13667
13735
|
const rId = nextRid(rels);
|
|
13668
13736
|
table.rId = rId;
|
|
@@ -29647,13 +29715,7 @@ self.onmessage = async function(event) {
|
|
|
29647
29715
|
if (drawing) {
|
|
29648
29716
|
if (this.drawingHasChartReference(drawing) && rawDrawings[drawing.name]) zip.append(rawDrawings[drawing.name], { name: drawingPath(drawing.name) });
|
|
29649
29717
|
else {
|
|
29650
|
-
const filteredAnchors = (drawing.anchors ?? [])
|
|
29651
|
-
if (a == null) return false;
|
|
29652
|
-
if (a.range?.br && a.shape) return true;
|
|
29653
|
-
if (!a.br && !a.picture) return false;
|
|
29654
|
-
if (a.br && !a.picture && !a.shape) return false;
|
|
29655
|
-
return true;
|
|
29656
|
-
});
|
|
29718
|
+
const filteredAnchors = filterDrawingAnchors(drawing.anchors ?? []);
|
|
29657
29719
|
const drawingForWrite = drawing.anchors ? {
|
|
29658
29720
|
...drawing,
|
|
29659
29721
|
anchors: filteredAnchors
|
|
@@ -29995,6 +30057,7 @@ self.onmessage = async function(event) {
|
|
|
29995
30057
|
pageSeteup: new PageSetupXform(),
|
|
29996
30058
|
autoFilter: new AutoFilterXform$1(),
|
|
29997
30059
|
picture: new PictureXform(),
|
|
30060
|
+
drawing: new DrawingXform$1(),
|
|
29998
30061
|
conditionalFormattings: new ConditionalFormattingsXform(),
|
|
29999
30062
|
headerFooter: new HeaderFooterXform(),
|
|
30000
30063
|
rowBreaks: new RowBreaksXform(),
|
|
@@ -30103,10 +30166,11 @@ self.onmessage = async function(event) {
|
|
|
30103
30166
|
this._writeDataValidations();
|
|
30104
30167
|
this._writePageMargins();
|
|
30105
30168
|
this._writePageSetup();
|
|
30106
|
-
this._writeBackground();
|
|
30107
30169
|
this._writeHeaderFooter();
|
|
30108
30170
|
this._writeRowBreaks();
|
|
30109
30171
|
this._writeColBreaks();
|
|
30172
|
+
this._writeDrawing();
|
|
30173
|
+
this._writeBackground();
|
|
30110
30174
|
this._writeLegacyData();
|
|
30111
30175
|
this._writeCloseWorksheet();
|
|
30112
30176
|
this.stream.end();
|
|
@@ -30253,11 +30317,62 @@ self.onmessage = async function(event) {
|
|
|
30253
30317
|
else this.conditionalFormatting = [];
|
|
30254
30318
|
}
|
|
30255
30319
|
addBackgroundImage(imageId) {
|
|
30256
|
-
this._background = { imageId };
|
|
30320
|
+
this._background = { imageId: Number(imageId) };
|
|
30257
30321
|
}
|
|
30258
30322
|
getBackgroundImageId() {
|
|
30259
30323
|
return this._background && this._background.imageId;
|
|
30260
30324
|
}
|
|
30325
|
+
/**
|
|
30326
|
+
* Using the image id from `WorkbookWriter.addImage`,
|
|
30327
|
+
* embed an image within the worksheet to cover a range.
|
|
30328
|
+
*/
|
|
30329
|
+
addImage(imageId, range) {
|
|
30330
|
+
const model = this._parseImageRange(String(imageId), range);
|
|
30331
|
+
this._media.push(model);
|
|
30332
|
+
}
|
|
30333
|
+
/**
|
|
30334
|
+
* Return the images that have been added to this worksheet.
|
|
30335
|
+
* Each entry contains imageId and the normalised range (with native anchors).
|
|
30336
|
+
*/
|
|
30337
|
+
getImages() {
|
|
30338
|
+
return this._media;
|
|
30339
|
+
}
|
|
30340
|
+
/**
|
|
30341
|
+
* Parse the user-supplied range into a normalised internal model
|
|
30342
|
+
* mirroring what the regular Worksheet / Image class does.
|
|
30343
|
+
*/
|
|
30344
|
+
_parseImageRange(imageId, range) {
|
|
30345
|
+
if (typeof range === "string") {
|
|
30346
|
+
const decoded = colCache.decode(range);
|
|
30347
|
+
if ("top" in decoded) return {
|
|
30348
|
+
type: "image",
|
|
30349
|
+
imageId,
|
|
30350
|
+
range: {
|
|
30351
|
+
tl: new Anchor(this, {
|
|
30352
|
+
col: decoded.left,
|
|
30353
|
+
row: decoded.top
|
|
30354
|
+
}, -1).model,
|
|
30355
|
+
br: new Anchor(this, {
|
|
30356
|
+
col: decoded.right,
|
|
30357
|
+
row: decoded.bottom
|
|
30358
|
+
}, 0).model,
|
|
30359
|
+
editAs: "oneCell"
|
|
30360
|
+
}
|
|
30361
|
+
};
|
|
30362
|
+
throw new Error(`Invalid image range: "${range}". Expected a range like "A1:C3".`);
|
|
30363
|
+
}
|
|
30364
|
+
return {
|
|
30365
|
+
type: "image",
|
|
30366
|
+
imageId,
|
|
30367
|
+
range: {
|
|
30368
|
+
tl: new Anchor(this, range.tl, 0).model,
|
|
30369
|
+
br: range.br ? new Anchor(this, range.br, 0).model : void 0,
|
|
30370
|
+
ext: range.ext,
|
|
30371
|
+
editAs: range.editAs
|
|
30372
|
+
},
|
|
30373
|
+
hyperlinks: range.hyperlinks
|
|
30374
|
+
};
|
|
30375
|
+
}
|
|
30261
30376
|
async protect(password, options) {
|
|
30262
30377
|
this.sheetProtection = { sheet: true };
|
|
30263
30378
|
if (options && "spinCount" in options) options.spinCount = Number.isFinite(options.spinCount) ? Math.round(Math.max(0, options.spinCount)) : 1e5;
|
|
@@ -30388,6 +30503,29 @@ self.onmessage = async function(event) {
|
|
|
30388
30503
|
_writeAutoFilter() {
|
|
30389
30504
|
this.stream.write(xform.autoFilter.toXml(this.autoFilter));
|
|
30390
30505
|
}
|
|
30506
|
+
_writeDrawing() {
|
|
30507
|
+
if (this._media.length === 0) return;
|
|
30508
|
+
const drawingName = `drawing${this.id}`;
|
|
30509
|
+
const drawingRId = this._sheetRelsWriter.addRelationship({
|
|
30510
|
+
Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
|
|
30511
|
+
Target: drawingRelTargetFromWorksheet(drawingName)
|
|
30512
|
+
});
|
|
30513
|
+
const { anchors, rels } = buildDrawingAnchorsAndRels(this._media, [], {
|
|
30514
|
+
getBookImage: (id) => this._workbook.getImage(Number(id)),
|
|
30515
|
+
nextRId: (currentRels) => `rId${currentRels.length + 1}`
|
|
30516
|
+
});
|
|
30517
|
+
this._drawing = {
|
|
30518
|
+
rId: drawingRId,
|
|
30519
|
+
name: drawingName,
|
|
30520
|
+
anchors,
|
|
30521
|
+
rels
|
|
30522
|
+
};
|
|
30523
|
+
this.stream.write(xform.drawing.toXml({ rId: drawingRId }));
|
|
30524
|
+
}
|
|
30525
|
+
/** Returns the drawing model if images were added, for the workbook writer. */
|
|
30526
|
+
get drawing() {
|
|
30527
|
+
return this._drawing;
|
|
30528
|
+
}
|
|
30391
30529
|
_writeBackground() {
|
|
30392
30530
|
if (this._background) {
|
|
30393
30531
|
if (this._background.imageId !== void 0) {
|
|
@@ -30510,6 +30648,7 @@ self.onmessage = async function(event) {
|
|
|
30510
30648
|
await this.promise;
|
|
30511
30649
|
await this._commitWorksheets();
|
|
30512
30650
|
await this.addMedia();
|
|
30651
|
+
this.addDrawings();
|
|
30513
30652
|
await Promise.all([
|
|
30514
30653
|
this.addThemes(),
|
|
30515
30654
|
this.addOfficeRels(),
|
|
@@ -30614,11 +30753,13 @@ self.onmessage = async function(event) {
|
|
|
30614
30753
|
worksheets.forEach((ws) => {
|
|
30615
30754
|
ws.fileIndex = ws.id;
|
|
30616
30755
|
});
|
|
30756
|
+
const drawings = worksheets.filter((ws) => ws.drawing).map((ws) => ws.drawing);
|
|
30617
30757
|
const model = {
|
|
30618
30758
|
worksheets,
|
|
30619
30759
|
sharedStrings: this.sharedStrings,
|
|
30620
30760
|
commentRefs: this.commentRefs,
|
|
30621
30761
|
media: this.media,
|
|
30762
|
+
drawings,
|
|
30622
30763
|
hasCheckboxes: this.styles.hasCheckboxes
|
|
30623
30764
|
};
|
|
30624
30765
|
const xform = new ContentTypesXform();
|
|
@@ -30647,6 +30788,29 @@ self.onmessage = async function(event) {
|
|
|
30647
30788
|
throw new ImageError("Unsupported media");
|
|
30648
30789
|
}));
|
|
30649
30790
|
}
|
|
30791
|
+
/**
|
|
30792
|
+
* Generate drawing XML and drawing relationship files for worksheets that have images.
|
|
30793
|
+
* Must be called after _commitWorksheets() so that each WorksheetWriter has built its
|
|
30794
|
+
* drawing model, and after addMedia() so that media files are already in the ZIP.
|
|
30795
|
+
*/
|
|
30796
|
+
addDrawings() {
|
|
30797
|
+
const drawingXform = new DrawingXform();
|
|
30798
|
+
const relsXform = new RelationshipsXform();
|
|
30799
|
+
for (const ws of this._worksheets) {
|
|
30800
|
+
if (!ws?.drawing) continue;
|
|
30801
|
+
const { drawing } = ws;
|
|
30802
|
+
const filteredAnchors = filterDrawingAnchors(drawing.anchors);
|
|
30803
|
+
const drawingForWrite = {
|
|
30804
|
+
...drawing,
|
|
30805
|
+
anchors: filteredAnchors
|
|
30806
|
+
};
|
|
30807
|
+
drawingXform.prepare(drawingForWrite);
|
|
30808
|
+
const xml = drawingXform.toXml(drawingForWrite);
|
|
30809
|
+
this._addFile(xml, drawingPath(drawing.name));
|
|
30810
|
+
const relsXml = relsXform.toXml(drawing.rels);
|
|
30811
|
+
this._addFile(relsXml, drawingRelsPath(drawing.name));
|
|
30812
|
+
}
|
|
30813
|
+
}
|
|
30650
30814
|
addApp() {
|
|
30651
30815
|
return new Promise((resolve) => {
|
|
30652
30816
|
const xform = new AppXform();
|