@visactor/vtable-plugins 1.19.1-alpha.0 → 1.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,7 @@ export interface ExportOptions {
5
5
  quality?: number;
6
6
  backgroundColor?: string;
7
7
  scale?: number;
8
+ download?: boolean;
8
9
  }
9
10
  export declare class ExportGanttPlugin implements VTableGantt.plugins.IGanttPlugin {
10
11
  id: string;
@@ -12,6 +13,7 @@ export declare class ExportGanttPlugin implements VTableGantt.plugins.IGanttPlug
12
13
  private _gantt;
13
14
  run(...args: any[]): void;
14
15
  exportToImage(options?: ExportOptions): Promise<string | undefined>;
16
+ exportToBase64(options?: Omit<ExportOptions, 'download'>): Promise<string | undefined>;
15
17
  private createFullSizeContainer;
16
18
  private finalizeExport;
17
19
  release(): void;
@@ -67,7 +67,7 @@ class ExportGanttPlugin {
67
67
  var _a;
68
68
  return __awaiter(this, void 0, void 0, (function*() {
69
69
  if (!this._gantt) return;
70
- const {fileName: fileName = "gantt-export", type: type = "png", quality: quality = 1, backgroundColor: backgroundColor = "#ffffff", scale: scale = window.devicePixelRatio || 1} = options;
70
+ const {fileName: fileName = "gantt-export", type: type = "png", quality: quality = 1, backgroundColor: backgroundColor = "#ffffff", scale: scale = window.devicePixelRatio || 1, download: download = !0} = options;
71
71
  try {
72
72
  const {tempContainer: tempContainer, clonedGantt: clonedGantt} = this.createFullSizeContainer(scale);
73
73
  try {
@@ -80,7 +80,7 @@ class ExportGanttPlugin {
80
80
  ctx.fillStyle = "rgb(225, 228, 232)", ctx.fillRect(splitLineX - splitLineWidth / 2, 0, splitLineWidth, totalHeight);
81
81
  const sourceX = 4 * scale, sourceWidth = clonedGantt.canvas.width - sourceX;
82
82
  return clonedGantt.canvas && ctx.drawImage(clonedGantt.canvas, sourceX, 0, sourceWidth, clonedGantt.canvas.height, (clonedGantt.taskListTableInstance.getAllColsWidth() + 1.5) * scale, 0, (clonedGantt.getAllDateColsWidth() - 1.5) * scale, totalHeight),
83
- this.finalizeExport(exportCanvas, fileName, type, quality);
83
+ this.finalizeExport(exportCanvas, fileName, type, quality, download);
84
84
  } finally {
85
85
  tempContainer.remove(), clonedGantt.release();
86
86
  }
@@ -89,6 +89,13 @@ class ExportGanttPlugin {
89
89
  }
90
90
  }));
91
91
  }
92
+ exportToBase64(options = {}) {
93
+ return __awaiter(this, void 0, void 0, (function*() {
94
+ return this.exportToImage(Object.assign(Object.assign({}, options), {
95
+ download: !1
96
+ }));
97
+ }));
98
+ }
92
99
  createFullSizeContainer(scale) {
93
100
  var _a, _b, _c;
94
101
  if (!this._gantt) throw new Error("ExportGanttPlugin: Gantt instance not available to create container.");
@@ -105,7 +112,8 @@ class ExportGanttPlugin {
105
112
  tableWidth: void 0,
106
113
  minTableWidth: void 0,
107
114
  maxTableWidth: void 0
108
- })
115
+ }),
116
+ plugins: []
109
117
  }));
110
118
  return clonedGantt.setPixelRatio(scale), (null === (_a = clonedGantt.scenegraph) || void 0 === _a ? void 0 : _a.ganttGroup) && clonedGantt.scenegraph.ganttGroup.setAttribute("clip", !1),
111
119
  (null === (_c = null === (_b = clonedGantt.taskListTableInstance) || void 0 === _b ? void 0 : _b.scenegraph) || void 0 === _c ? void 0 : _c.tableGroup) && clonedGantt.taskListTableInstance.scenegraph.tableGroup.setAttribute("clip", !1),
@@ -114,10 +122,14 @@ class ExportGanttPlugin {
114
122
  clonedGantt: clonedGantt
115
123
  };
116
124
  }
117
- finalizeExport(canvas, fileName, type, quality) {
118
- const base64 = canvas.toDataURL(`image/${type}`, quality), link = document.createElement("a");
119
- return link.download = `${fileName}.${type}`, link.href = base64, document.body.appendChild(link),
120
- link.click(), document.body.removeChild(link), base64;
125
+ finalizeExport(canvas, fileName, type, quality, download = !0) {
126
+ const base64 = canvas.toDataURL(`image/${type}`, quality);
127
+ if (download) {
128
+ const link = document.createElement("a");
129
+ link.download = `${fileName}.${type}`, link.href = base64, document.body.appendChild(link),
130
+ link.click(), document.body.removeChild(link);
131
+ }
132
+ return base64;
121
133
  }
122
134
  release() {
123
135
  this._gantt = null;
@@ -1 +1 @@
1
- {"version":3,"sources":["gantt-export-image.ts"],"names":[],"mappings":"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","file":"gantt-export-image.js","sourcesContent":["import * as VTableGantt from '@visactor/vtable-gantt';\r\n\r\n// 甘特图导出配置项接口\r\nexport interface ExportOptions {\r\n fileName?: string;\r\n type?: 'png' | 'jpeg';\r\n quality?: number;\r\n backgroundColor?: string;\r\n scale?: number;\r\n}\r\n\r\n\r\n/**\r\n * 甘特图导出插件\r\n * @description 提供完整的甘特图导出功能,支持高分辨率输出和精准布局保留\r\n */\r\nexport class ExportGanttPlugin implements VTableGantt.plugins.IGanttPlugin {\r\n id = 'gantt-export-helper';\r\n name = 'Gantt Export Helper';\r\n private _gantt: VTableGantt.Gantt | null = null;\r\n\r\n // run 方法,在插件初始化时由 PluginManager调用\r\n run(...args: any[]): void {\r\n const ganttInstance = args[0] as VTableGantt.Gantt;\r\n if (!ganttInstance) {\r\n console.error('ExportGanttPlugin: Gantt instance not provided to run method.');\r\n return;\r\n }\r\n this._gantt = ganttInstance;\r\n }\r\n\r\n /**\r\n * 执行甘特图导出操作\r\n * @async\r\n * @param {ExportOptions} [options={}] 导出配置选项\r\n * @returns {Promise<string | undefined>} 返回Base64格式的图片数据,或在未初始化时返回 undefined\r\n * @throws {Error} 导出过程中发生错误时抛出异常\r\n */\r\n public async exportToImage(options: ExportOptions = {}): Promise<string | undefined> {\r\n if (!this._gantt) {\r\n // 保留这个 error\r\n console.error('ExportGanttPlugin: Gantt instance not available.');\r\n return undefined;\r\n }\r\n\r\n const {\r\n fileName = 'gantt-export',\r\n type = 'png',\r\n quality = 1,\r\n backgroundColor = '#ffffff',\r\n scale = window.devicePixelRatio || 1\r\n } = options;\r\n\r\n try {\r\n const { tempContainer, clonedGantt } = this.createFullSizeContainer(scale);\r\n\r\n try {\r\n await new Promise(resolve => requestAnimationFrame(resolve));\r\n\r\n const totalWidth = (clonedGantt.taskListTableInstance.getAllColsWidth() + clonedGantt.getAllDateColsWidth()) * scale;\r\n const totalHeight = clonedGantt.getAllRowsHeight() * scale;\r\n\r\n const exportCanvas = document.createElement('canvas');\r\n exportCanvas.width = totalWidth;\r\n exportCanvas.height = totalHeight;\r\n const ctx = exportCanvas.getContext('2d')!;\r\n\r\n ctx.fillStyle = backgroundColor;\r\n ctx.fillRect(0, 0, totalWidth, totalHeight);\r\n\r\n if (clonedGantt.taskListTableInstance?.canvas) {\r\n ctx.drawImage(\r\n clonedGantt.taskListTableInstance.canvas,\r\n 0, 0,\r\n clonedGantt.taskListTableInstance.getAllColsWidth() * scale,\r\n totalHeight\r\n );\r\n }\r\n\r\n const splitLineWidth = 3 * scale;\r\n const splitLineX = clonedGantt.taskListTableInstance.getAllColsWidth() * scale;\r\n ctx.fillStyle = 'rgb(225, 228, 232)';\r\n ctx.fillRect(\r\n splitLineX - splitLineWidth / 2,\r\n 0,\r\n splitLineWidth,\r\n totalHeight\r\n );\r\n\r\n const sourceX = 4 * scale;\r\n const sourceWidth = clonedGantt.canvas.width - sourceX;\r\n\r\n if (clonedGantt.canvas) {\r\n ctx.drawImage(\r\n clonedGantt.canvas,\r\n sourceX, 0,\r\n sourceWidth, clonedGantt.canvas.height,\r\n (clonedGantt.taskListTableInstance.getAllColsWidth() + 1.5) * scale, 0,\r\n (clonedGantt.getAllDateColsWidth() - 1.5) * scale,\r\n totalHeight\r\n );\r\n }\r\n\r\n return this.finalizeExport(exportCanvas, fileName, type, quality);\r\n } finally {\r\n tempContainer.remove();\r\n // 确保克隆的甘特图实例被释放\r\n clonedGantt.release();\r\n }\r\n } catch (error) {\r\n console.error('[Gantt Export Plugin] Export failed:', error);\r\n throw new Error(`甘特图导出失败: ${error instanceof Error ? error.message : '未知错误'}`);\r\n }\r\n }\r\n\r\n private createFullSizeContainer(scale: number) {\r\n if (!this._gantt) {\r\n // 保留这个 error\r\n throw new Error('ExportGanttPlugin: Gantt instance not available to create container.');\r\n }\r\n\r\n const tempContainer = document.createElement('div');\r\n tempContainer.style.position = 'fixed';\r\n tempContainer.style.left = '-9999px';\r\n tempContainer.style.overflow = 'hidden';\r\n tempContainer.style.width = `${window.innerWidth + 100}px`;\r\n tempContainer.style.height = `${window.innerHeight + 100}px`;\r\n document.body.appendChild(tempContainer);\r\n\r\n const clonedContainer = document.createElement('div');\r\n\r\n const totalWidth = this._gantt.taskListTableInstance.getAllColsWidth() + this._gantt.getAllDateColsWidth();\r\n const totalHeight = this._gantt.getAllRowsHeight();\r\n\r\n clonedContainer.style.width = `${totalWidth}px`;\r\n clonedContainer.style.height = `${totalHeight}px`;\r\n tempContainer.appendChild(clonedContainer);\r\n\r\n const clonedGantt = new VTableGantt.Gantt(clonedContainer, {\r\n ...this._gantt.options,\r\n records: JSON.parse(JSON.stringify(this._gantt.records)),\r\n taskListTable: {\r\n ...this._gantt.options.taskListTable,\r\n tableWidth: undefined as unknown as number,\r\n minTableWidth: undefined as unknown as number,\r\n maxTableWidth: undefined as unknown as number,\r\n },\r\n });\r\n\r\n clonedGantt.setPixelRatio(scale);\r\n\r\n // 禁用裁剪\r\n if ((clonedGantt as any).scenegraph?.ganttGroup) {\r\n (clonedGantt as any).scenegraph.ganttGroup.setAttribute('clip', false);\r\n }\r\n if ((clonedGantt.taskListTableInstance as any)?.scenegraph?.tableGroup) {\r\n (clonedGantt.taskListTableInstance as any).scenegraph.tableGroup.setAttribute('clip', false);\r\n }\r\n\r\n clonedGantt.scenegraph.stage.render();\r\n\r\n return { tempContainer, clonedGantt };\r\n }\r\n\r\n private finalizeExport(canvas: HTMLCanvasElement, fileName: string, type: string, quality: number): string {\r\n const base64 = canvas.toDataURL(`image/${type}`, quality);\r\n const link = document.createElement('a');\r\n link.download = `${fileName}.${type}`;\r\n link.href = base64;\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n return base64;\r\n }\r\n \r\n release(): void {\r\n this._gantt = null;\r\n }\r\n}"]}
1
+ {"version":3,"sources":["gantt-export-image.ts"],"names":[],"mappings":"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","file":"gantt-export-image.js","sourcesContent":["import * as VTableGantt from '@visactor/vtable-gantt';\r\n\r\n// 甘特图导出配置项接口\r\nexport interface ExportOptions {\r\n fileName?: string;\r\n type?: 'png' | 'jpeg';\r\n quality?: number;\r\n backgroundColor?: string;\r\n scale?: number;\r\n download?: boolean;\r\n}\r\n\r\n\r\n/**\r\n * 甘特图导出插件\r\n * @description 提供完整的甘特图导出功能,支持高分辨率输出和精准布局保留\r\n */\r\nexport class ExportGanttPlugin implements VTableGantt.plugins.IGanttPlugin {\r\n id = 'gantt-export-helper';\r\n name = 'Gantt Export Helper';\r\n private _gantt: VTableGantt.Gantt | null = null;\r\n\r\n // run 方法,在插件初始化时由 PluginManager调用\r\n run(...args: any[]): void {\r\n const ganttInstance = args[0] as VTableGantt.Gantt;\r\n if (!ganttInstance) {\r\n console.error('ExportGanttPlugin: Gantt instance not provided to run method.');\r\n return;\r\n }\r\n this._gantt = ganttInstance;\r\n } \r\n /**\r\n * 执行甘特图导出操作\r\n * @async\r\n * @param {ExportOptions} [options={}] 导出配置选项\r\n * @returns {Promise<string | undefined>} 返回Base64格式的图片数据,或在未初始化时返回 undefined\r\n * @throws {Error} 导出过程中发生错误时抛出异常\r\n */\r\n public async exportToImage(options: ExportOptions = {}): Promise<string | undefined> {\r\n if (!this._gantt) {\r\n // 保留这个 error\r\n console.error('ExportGanttPlugin: Gantt instance not available.');\r\n return undefined;\r\n }\r\n\r\n const {\r\n fileName = 'gantt-export',\r\n type = 'png',\r\n quality = 1,\r\n backgroundColor = '#ffffff',\r\n scale = window.devicePixelRatio || 1,\r\n download = true // 默认执行下载\r\n } = options;\r\n\r\n try {\r\n const { tempContainer, clonedGantt } = this.createFullSizeContainer(scale);\r\n\r\n try {\r\n await new Promise(resolve => requestAnimationFrame(resolve));\r\n\r\n const totalWidth = (clonedGantt.taskListTableInstance.getAllColsWidth() + clonedGantt.getAllDateColsWidth()) * scale;\r\n const totalHeight = clonedGantt.getAllRowsHeight() * scale;\r\n\r\n const exportCanvas = document.createElement('canvas');\r\n exportCanvas.width = totalWidth;\r\n exportCanvas.height = totalHeight;\r\n const ctx = exportCanvas.getContext('2d')!;\r\n\r\n ctx.fillStyle = backgroundColor;\r\n ctx.fillRect(0, 0, totalWidth, totalHeight);\r\n\r\n if (clonedGantt.taskListTableInstance?.canvas) {\r\n ctx.drawImage(\r\n clonedGantt.taskListTableInstance.canvas,\r\n 0, 0,\r\n clonedGantt.taskListTableInstance.getAllColsWidth() * scale,\r\n totalHeight\r\n );\r\n }\r\n\r\n const splitLineWidth = 3 * scale;\r\n const splitLineX = clonedGantt.taskListTableInstance.getAllColsWidth() * scale;\r\n ctx.fillStyle = 'rgb(225, 228, 232)';\r\n ctx.fillRect(\r\n splitLineX - splitLineWidth / 2,\r\n 0,\r\n splitLineWidth,\r\n totalHeight\r\n );\r\n\r\n const sourceX = 4 * scale;\r\n const sourceWidth = clonedGantt.canvas.width - sourceX;\r\n\r\n if (clonedGantt.canvas) {\r\n ctx.drawImage(\r\n clonedGantt.canvas,\r\n sourceX, 0,\r\n sourceWidth, clonedGantt.canvas.height,\r\n (clonedGantt.taskListTableInstance.getAllColsWidth() + 1.5) * scale, 0,\r\n (clonedGantt.getAllDateColsWidth() - 1.5) * scale,\r\n totalHeight );\r\n }\r\n\r\n return this.finalizeExport(exportCanvas, fileName, type, quality, download);\r\n } finally {\r\n tempContainer.remove();\r\n // 确保克隆的甘特图实例被释放\r\n clonedGantt.release();\r\n }\r\n } catch (error) {\r\n console.error('[Gantt Export Plugin] Export failed:', error);\r\n throw new Error(`甘特图导出失败: ${error instanceof Error ? error.message : '未知错误'}`);\r\n }\r\n }\r\n\r\n /**\r\n * 获取甘特图的 Base64 图片数据,不触发下载\r\n * @async\r\n * @param {Omit<ExportOptions, 'download'>} [options={}] 导出配置选项(不包含 download 参数)\r\n * @returns {Promise<string | undefined>} 返回 Base64 格式的图片数据,或在未初始化时返回 undefined\r\n * @throws {Error} 导出过程中发生错误时抛出异常\r\n */\r\n public async exportToBase64(options: Omit<ExportOptions, 'download'> = {}): Promise<string | undefined> {\r\n // 调用 exportToImage 方法,但设置 download 为 false\r\n return this.exportToImage({\r\n ...options,\r\n download: false\r\n });\r\n }\r\n\r\n private createFullSizeContainer(scale: number) {\r\n if (!this._gantt) {\r\n // 保留这个 error\r\n throw new Error('ExportGanttPlugin: Gantt instance not available to create container.');\r\n }\r\n\r\n const tempContainer = document.createElement('div');\r\n tempContainer.style.position = 'fixed';\r\n tempContainer.style.left = '-9999px';\r\n tempContainer.style.overflow = 'hidden';\r\n tempContainer.style.width = `${window.innerWidth + 100}px`;\r\n tempContainer.style.height = `${window.innerHeight + 100}px`;\r\n document.body.appendChild(tempContainer);\r\n\r\n const clonedContainer = document.createElement('div');\r\n\r\n const totalWidth = this._gantt.taskListTableInstance.getAllColsWidth() + this._gantt.getAllDateColsWidth();\r\n const totalHeight = this._gantt.getAllRowsHeight();\r\n\r\n clonedContainer.style.width = `${totalWidth}px`;\r\n clonedContainer.style.height = `${totalHeight}px`;\r\n tempContainer.appendChild(clonedContainer);\r\n\r\n const clonedGantt = new VTableGantt.Gantt(clonedContainer, {\r\n ...this._gantt.options,\r\n records: JSON.parse(JSON.stringify(this._gantt.records)),\r\n taskListTable: {\r\n ...this._gantt.options.taskListTable,\r\n tableWidth: undefined as unknown as number,\r\n minTableWidth: undefined as unknown as number,\r\n maxTableWidth: undefined as unknown as number,\r\n },\r\n plugins: [] \r\n });\r\n\r\n clonedGantt.setPixelRatio(scale);\r\n\r\n // 禁用裁剪\r\n if ((clonedGantt as any).scenegraph?.ganttGroup) {\r\n (clonedGantt as any).scenegraph.ganttGroup.setAttribute('clip', false);\r\n }\r\n if ((clonedGantt.taskListTableInstance as any)?.scenegraph?.tableGroup) {\r\n (clonedGantt.taskListTableInstance as any).scenegraph.tableGroup.setAttribute('clip', false);\r\n }\r\n\r\n clonedGantt.scenegraph.stage.render();\r\n\r\n return { tempContainer, clonedGantt };\r\n } private finalizeExport(canvas: HTMLCanvasElement, fileName: string, type: string, quality: number, download: boolean = true): string {\r\n const base64 = canvas.toDataURL(`image/${type}`, quality);\r\n \r\n // 如果需要下载,则创建下载链接\r\n if (download) {\r\n const link = document.createElement('a');\r\n link.download = `${fileName}.${type}`;\r\n link.href = base64;\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n }\r\n \r\n return base64;\r\n }\r\n \r\n release(): void {\r\n this._gantt = null;\r\n }\r\n}"]}
@@ -8205,9 +8205,9 @@
8205
8205
  setWidthHeightWithoutTransform(aabbBounds) {
8206
8206
  this.widthWithoutTransform = aabbBounds.x2 - aabbBounds.x1, this.heightWithoutTransform = aabbBounds.y2 - aabbBounds.y1;
8207
8207
  }
8208
- setAttributesAndPreventAnimate(params, forceUpdateTag = !1, context) {
8208
+ setAttributesAndPreventAnimate(params, forceUpdateTag = !1, context, ignorePriority) {
8209
8209
  this.setAttributes(params, forceUpdateTag, context), this.animates && this.animates.forEach(animate => {
8210
- Object.keys(params).forEach(key => {
8210
+ (animate.priority !== 1 / 0 || ignorePriority) && Object.keys(params).forEach(key => {
8211
8211
  animate.preventAttr(key);
8212
8212
  });
8213
8213
  });
@@ -8378,7 +8378,7 @@
8378
8378
  });
8379
8379
  } else this.stopStateAnimates(), this.setAttributesAndPreventAnimate(attrs, !1, {
8380
8380
  type: AttributeUpdateType.STATE
8381
- });
8381
+ }), this.finalAttribute && Object.assign(this.finalAttribute, attrs);
8382
8382
  this._emitCustomEvent("afterStateUpdate", {
8383
8383
  type: AttributeUpdateType.STATE
8384
8384
  });
@@ -21832,7 +21832,7 @@
21832
21832
  if (!this._gantt) {
21833
21833
  return undefined;
21834
21834
  }
21835
- const { fileName = 'gantt-export', type = 'png', quality = 1, backgroundColor = '#ffffff', scale = window.devicePixelRatio || 1 } = options;
21835
+ const { fileName = 'gantt-export', type = 'png', quality = 1, backgroundColor = '#ffffff', scale = window.devicePixelRatio || 1, download = true } = options;
21836
21836
  try {
21837
21837
  const { tempContainer, clonedGantt } = this.createFullSizeContainer(scale);
21838
21838
  try {
@@ -21857,7 +21857,7 @@
21857
21857
  if (clonedGantt.canvas) {
21858
21858
  ctx.drawImage(clonedGantt.canvas, sourceX, 0, sourceWidth, clonedGantt.canvas.height, (clonedGantt.taskListTableInstance.getAllColsWidth() + 1.5) * scale, 0, (clonedGantt.getAllDateColsWidth() - 1.5) * scale, totalHeight);
21859
21859
  }
21860
- return this.finalizeExport(exportCanvas, fileName, type, quality);
21860
+ return this.finalizeExport(exportCanvas, fileName, type, quality, download);
21861
21861
  }
21862
21862
  finally {
21863
21863
  tempContainer.remove();
@@ -21868,6 +21868,12 @@
21868
21868
  throw new Error(`甘特图导出失败: ${error instanceof Error ? error.message : '未知错误'}`);
21869
21869
  }
21870
21870
  }
21871
+ async exportToBase64(options = {}) {
21872
+ return this.exportToImage({
21873
+ ...options,
21874
+ download: false
21875
+ });
21876
+ }
21871
21877
  createFullSizeContainer(scale) {
21872
21878
  if (!this._gantt) {
21873
21879
  throw new Error('ExportGanttPlugin: Gantt instance not available to create container.');
@@ -21894,6 +21900,7 @@
21894
21900
  minTableWidth: undefined,
21895
21901
  maxTableWidth: undefined,
21896
21902
  },
21903
+ plugins: []
21897
21904
  });
21898
21905
  clonedGantt.setPixelRatio(scale);
21899
21906
  if (clonedGantt.scenegraph?.ganttGroup) {
@@ -21905,14 +21912,16 @@
21905
21912
  clonedGantt.scenegraph.stage.render();
21906
21913
  return { tempContainer, clonedGantt };
21907
21914
  }
21908
- finalizeExport(canvas, fileName, type, quality) {
21915
+ finalizeExport(canvas, fileName, type, quality, download = true) {
21909
21916
  const base64 = canvas.toDataURL(`image/${type}`, quality);
21910
- const link = document.createElement('a');
21911
- link.download = `${fileName}.${type}`;
21912
- link.href = base64;
21913
- document.body.appendChild(link);
21914
- link.click();
21915
- document.body.removeChild(link);
21917
+ if (download) {
21918
+ const link = document.createElement('a');
21919
+ link.download = `${fileName}.${type}`;
21920
+ link.href = base64;
21921
+ document.body.appendChild(link);
21922
+ link.click();
21923
+ document.body.removeChild(link);
21924
+ }
21916
21925
  return base64;
21917
21926
  }
21918
21927
  release() {