styled-exceljs 0.21.0 → 0.21.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +19 -2
- package/bower.json +1 -1
- package/dist/xlsx.core.min.js +18 -18
- package/dist/xlsx.core.min.map +1 -1
- package/dist/xlsx.extendscript.js +249 -23
- package/dist/xlsx.full.min.js +17 -17
- package/dist/xlsx.full.min.map +1 -1
- package/dist/xlsx.mini.min.js +10 -10
- package/dist/xlsx.mini.min.map +1 -1
- package/docs/visual-fidelity.md +42 -2
- package/docs/visual-fidelity.zh-CN.md +38 -1
- package/package.json +2 -2
- package/types/index.d.ts +53 -0
- package/xlsx.js +249 -23
- package/xlsx.mjs +249 -23
package/docs/visual-fidelity.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# XLSX / XLS Visual Fidelity Extensions
|
|
2
2
|
|
|
3
|
+
`styled-exceljs` is built from a fork of the original SheetJS Community Edition
|
|
4
|
+
source code. The fork keeps SheetJS-compatible APIs and extends the original
|
|
5
|
+
reader / writer foundation with visual parsing and browser rendering features.
|
|
6
|
+
|
|
3
7
|
This document describes the browser rendering metadata exposed by this build.
|
|
4
8
|
The public model extends the existing SheetJS worksheet object and keeps default
|
|
5
9
|
read behavior compatible. Expensive visual parsing is enabled with explicit
|
|
@@ -26,6 +30,7 @@ const wb = XLSX.read(data, {
|
|
|
26
30
|
const html = XLSX.utils.sheet_to_html(ws, {
|
|
27
31
|
cellStyles: true,
|
|
28
32
|
browserPixels: true,
|
|
33
|
+
autoFit: true,
|
|
29
34
|
charts: true,
|
|
30
35
|
drawings: true
|
|
31
36
|
});
|
|
@@ -35,6 +40,8 @@ const html = XLSX.utils.sheet_to_html(ws, {
|
|
|
35
40
|
| --- | --- | --- |
|
|
36
41
|
| `cellStyles` | read / HTML | Resolves full styles into `cell.s`, row styles, and column styles. |
|
|
37
42
|
| `browserPixels` | read / HTML | Converts XLSX/XLS column widths and row heights to CSS pixels. |
|
|
43
|
+
| `autoFit` | HTML / utilities | Measures formatted cell text and computes best-fit column widths. |
|
|
44
|
+
| `overflow` | HTML | Controls unwrapped text overflow (`excel` / `visible` / `clip` / `hidden`). |
|
|
38
45
|
| `charts` | read / HTML | Parses chart models and renders supported chart types as inline SVG. |
|
|
39
46
|
| `drawings` | read / HTML | Parses image/drawing anchors and renders supported images as `<img>`. |
|
|
40
47
|
| `validateMerges` | read | Throws on invalid, duplicate, overlapping, or out-of-bounds merge ranges. |
|
|
@@ -116,6 +123,34 @@ XLSX.utils.row_height_to_px(points);
|
|
|
116
123
|
XLSX.utils.px_to_row_height(px);
|
|
117
124
|
```
|
|
118
125
|
|
|
126
|
+
Best-fit widths can be computed with browser text measurement:
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
XLSX.utils.auto_fit_columns(ws, {
|
|
130
|
+
set: true,
|
|
131
|
+
measureText(text, font, style) {
|
|
132
|
+
ctx.font = font;
|
|
133
|
+
return ctx.measureText(text).width;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`auto_fit_columns` scans formatted display text (`cell.w` after formatting),
|
|
139
|
+
composes column, row, and cell styles, and applies Excel-like layout rules:
|
|
140
|
+
|
|
141
|
+
- `alignment.wrapText` measures the longest explicit line or word segment
|
|
142
|
+
instead of expanding to the full paragraph width.
|
|
143
|
+
- `alignment.shrinkToFit` does not force a wider column when an existing width
|
|
144
|
+
is available.
|
|
145
|
+
- merged cells distribute additional width across the merged column span.
|
|
146
|
+
- widths are clamped to the Excel column width range and converted through MDW.
|
|
147
|
+
|
|
148
|
+
`XLSX.utils.measure_text_width(text, style, opts)` is also public. In browsers
|
|
149
|
+
it uses `opts.measureText` or Canvas `measureText`; in Node or headless
|
|
150
|
+
environments it uses a deterministic font-aware approximation. For pixel-close
|
|
151
|
+
Excel rendering, pass a browser Canvas callback using the same font stack as the
|
|
152
|
+
rendered table.
|
|
153
|
+
|
|
119
154
|
### Drawings
|
|
120
155
|
|
|
121
156
|
When `drawings:true` is set, worksheets may expose `ws["!drawings"]`:
|
|
@@ -210,11 +245,11 @@ Tolerant reads attach non-fatal errors to `ws["!mergeErrors"]`. Reads with
|
|
|
210
245
|
## HTML Output
|
|
211
246
|
|
|
212
247
|
`XLSX.utils.sheet_to_html(ws, {cellStyles:true, browserPixels:true,
|
|
213
|
-
charts:true, drawings:true})` emits:
|
|
248
|
+
autoFit:true, charts:true, drawings:true})` emits:
|
|
214
249
|
|
|
215
250
|
- `<colgroup>` entries with browser pixel widths
|
|
216
251
|
- inline row heights
|
|
217
|
-
- font, fill, border, alignment, wrap, shrink, and rotation CSS
|
|
252
|
+
- font, fill, border, alignment, wrap, shrink-to-fit, overflow, and rotation CSS
|
|
218
253
|
- hidden row/column behavior
|
|
219
254
|
- `rowspan` / `colspan` for merged cells
|
|
220
255
|
- an absolutely positioned drawing layer with images and chart SVG
|
|
@@ -222,6 +257,11 @@ charts:true, drawings:true})` emits:
|
|
|
222
257
|
The renderer does not materialize empty grid cells for row/column styles. Row
|
|
223
258
|
and column styles are composed with real cell styles at render time.
|
|
224
259
|
|
|
260
|
+
When `autoFit` is enabled, the generated table uses fixed layout and a computed
|
|
261
|
+
`<colgroup>`. Unwrapped text defaults to Excel-like visible overflow. Use
|
|
262
|
+
`overflow:"clip"` or `overflow:"hidden"` when the host page must constrain cell
|
|
263
|
+
content to the calculated column width.
|
|
264
|
+
|
|
225
265
|
## Completeness Report
|
|
226
266
|
|
|
227
267
|
The release includes a local report helper:
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# XLSX / XLS 视觉保真扩展
|
|
2
2
|
|
|
3
|
+
`styled-exceljs` 基于 SheetJS Community Edition 原始代码 fork 并继续增强。
|
|
4
|
+
本 fork 保持 SheetJS 兼容 API 和读写基础,在此之上扩展视觉解析和浏览器渲染能力。
|
|
5
|
+
|
|
3
6
|
本文档说明本版本在 SheetJS 兼容工作表模型上新增的浏览器渲染元数据。
|
|
4
7
|
默认读取行为保持轻量和兼容;完整视觉信息需要通过显式选项启用。
|
|
5
8
|
|
|
@@ -25,6 +28,7 @@ const ws = wb.Sheets[wb.SheetNames[0]];
|
|
|
25
28
|
const html = XLSX.utils.sheet_to_html(ws, {
|
|
26
29
|
cellStyles: true,
|
|
27
30
|
browserPixels: true,
|
|
31
|
+
autoFit: true,
|
|
28
32
|
charts: true,
|
|
29
33
|
drawings: true
|
|
30
34
|
});
|
|
@@ -39,6 +43,8 @@ const html = XLSX.utils.sheet_to_html(ws, {
|
|
|
39
43
|
| --- | --- | --- |
|
|
40
44
|
| `cellStyles` | 读取 / HTML | 将完整样式解析到 `cell.s`,并读取行样式和列样式。 |
|
|
41
45
|
| `browserPixels` | 读取 / HTML | 按 XLSX / XLS 规范将列宽、行高换算为浏览器 CSS 像素。 |
|
|
46
|
+
| `autoFit` | HTML / 工具函数 | 按格式化后的文字宽度计算最优列宽。 |
|
|
47
|
+
| `overflow` | HTML | 控制非换行文字溢出方式:`excel` / `visible` / `clip` / `hidden`。 |
|
|
42
48
|
| `charts` | 读取 / HTML | 解析图表模型,并将支持的图表类型以内联 SVG 渲染。 |
|
|
43
49
|
| `drawings` | 读取 / HTML | 解析图片、绘图锚点,支持的内嵌图片渲染为 `<img>`。 |
|
|
44
50
|
| `validateMerges` | 读取 | 读取时校验合并单元格,发现非法、重复、重叠或越界范围时抛错。 |
|
|
@@ -207,6 +213,32 @@ XLSX.utils.row_height_to_px(points);
|
|
|
207
213
|
XLSX.utils.px_to_row_height(px);
|
|
208
214
|
```
|
|
209
215
|
|
|
216
|
+
自动列宽可以接入浏览器真实文字测量:
|
|
217
|
+
|
|
218
|
+
```js
|
|
219
|
+
XLSX.utils.auto_fit_columns(ws, {
|
|
220
|
+
set: true,
|
|
221
|
+
measureText(text, font, style) {
|
|
222
|
+
ctx.font = font;
|
|
223
|
+
return ctx.measureText(text).width;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
`auto_fit_columns` 会扫描格式化后的显示文字(`cell.w`),合成列、行、
|
|
229
|
+
单元格样式,并尽量遵循 Excel 的布局行为:
|
|
230
|
+
|
|
231
|
+
- `alignment.wrapText` 开启时,按最长显式行或最长词段计算,而不是按整段
|
|
232
|
+
文本强行拉宽列。
|
|
233
|
+
- `alignment.shrinkToFit` 开启且已有列宽时,不再强制扩大列宽。
|
|
234
|
+
- 合并单元格会把额外宽度分摊到覆盖的列。
|
|
235
|
+
- 最终列宽会限制在 Excel 允许范围内,并通过 MDW 公式转换。
|
|
236
|
+
|
|
237
|
+
`XLSX.utils.measure_text_width(text, style, opts)` 也可单独使用。在浏览器中
|
|
238
|
+
会优先使用 `opts.measureText` 或 Canvas `measureText`;在 Node / 无 DOM
|
|
239
|
+
环境中使用稳定的字体近似算法。若需要尽量贴近 Excel,请传入与页面实际
|
|
240
|
+
字体一致的 Canvas 测量回调。
|
|
241
|
+
|
|
210
242
|
## 图片和绘图
|
|
211
243
|
|
|
212
244
|
开启 `drawings:true` 后,工作表可能暴露 `ws["!drawings"]`:
|
|
@@ -329,6 +361,7 @@ interface MergeError {
|
|
|
329
361
|
XLSX.utils.sheet_to_html(ws, {
|
|
330
362
|
cellStyles: true,
|
|
331
363
|
browserPixels: true,
|
|
364
|
+
autoFit: true,
|
|
332
365
|
charts: true,
|
|
333
366
|
drawings: true
|
|
334
367
|
});
|
|
@@ -339,7 +372,7 @@ XLSX.utils.sheet_to_html(ws, {
|
|
|
339
372
|
- `<colgroup>` 列宽
|
|
340
373
|
- 行高 CSS
|
|
341
374
|
- 字体、字号、颜色、填充、边框
|
|
342
|
-
- 水平 /
|
|
375
|
+
- 水平 / 垂直对齐、换行、缩进、旋转、收缩适应、溢出控制
|
|
343
376
|
- 隐藏行列
|
|
344
377
|
- 合并单元格的 `rowspan` / `colspan`
|
|
345
378
|
- 绝对定位图片层
|
|
@@ -348,6 +381,10 @@ XLSX.utils.sheet_to_html(ws, {
|
|
|
348
381
|
渲染器不会为了行样式或列样式物化整张空白网格。真实单元格渲染时会按
|
|
349
382
|
cell XF > row XF > column XF > default XF 的思路合成最终样式。
|
|
350
383
|
|
|
384
|
+
开启 `autoFit` 后,HTML 表格会使用固定布局和计算后的 `<colgroup>`。
|
|
385
|
+
未换行文本默认使用接近 Excel 的可见溢出效果;如果宿主页面必须把内容
|
|
386
|
+
限制在列宽内,可以设置 `overflow:"clip"` 或 `overflow:"hidden"`。
|
|
387
|
+
|
|
351
388
|
## 完整度报告
|
|
352
389
|
|
|
353
390
|
仓库提供本地完整度报告脚本:
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "styled-exceljs",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.2",
|
|
4
4
|
"author": "sheetjs",
|
|
5
|
-
"description": "SheetJS
|
|
5
|
+
"description": "SheetJS CE fork with enhanced XLS/XLSX styling and browser rendering",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"excel",
|
|
8
8
|
"xls",
|
package/types/index.d.ts
CHANGED
|
@@ -629,6 +629,38 @@ export interface CellStyle extends FillStyle {
|
|
|
629
629
|
bgColor?: StyleColor;
|
|
630
630
|
}
|
|
631
631
|
|
|
632
|
+
export interface TextMeasureOpts {
|
|
633
|
+
/** Browser-compatible text measurement callback. Receives text, CSS font string, and resolved style. */
|
|
634
|
+
measureText?: (text: string, font: string, style: CellStyle) => number;
|
|
635
|
+
/** Optional canvas-like object used for browser measureText fallback */
|
|
636
|
+
canvas?: any;
|
|
637
|
+
/** Maximum digit width in CSS pixels for Excel width conversion */
|
|
638
|
+
MDW?: number;
|
|
639
|
+
/** Additional pixel padding used when measuring cell text */
|
|
640
|
+
padding?: number;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
export interface AutoFitColumnOpts extends TextMeasureOpts {
|
|
644
|
+
/** Range to scan. Defaults to worksheet !ref */
|
|
645
|
+
range?: string | Range;
|
|
646
|
+
/** Minimum column width in Excel characters */
|
|
647
|
+
min?: number;
|
|
648
|
+
/** Maximum column width in Excel characters */
|
|
649
|
+
max?: number;
|
|
650
|
+
/** Minimum column width in browser pixels */
|
|
651
|
+
minPx?: number;
|
|
652
|
+
/** Maximum column width in browser pixels */
|
|
653
|
+
maxPx?: number;
|
|
654
|
+
/** Include merged cells when measuring width. Defaults to true */
|
|
655
|
+
includeMerged?: boolean;
|
|
656
|
+
/** Skip hidden rows and columns */
|
|
657
|
+
skipHidden?: boolean;
|
|
658
|
+
/** If false, return computed columns without mutating worksheet !cols */
|
|
659
|
+
set?: boolean;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
export type HTMLOverflowMode = "excel" | "visible" | "clip" | "hidden";
|
|
663
|
+
|
|
632
664
|
/** Drawing relationship entry */
|
|
633
665
|
export interface DrawingRelationship {
|
|
634
666
|
Type?: string;
|
|
@@ -1119,6 +1151,18 @@ export interface Sheet2HTMLOpts {
|
|
|
1119
1151
|
|
|
1120
1152
|
/** If true, render parsed drawing images */
|
|
1121
1153
|
drawings?: boolean;
|
|
1154
|
+
|
|
1155
|
+
/** If true or an options object, auto-fit columns using measured text widths */
|
|
1156
|
+
autoFit?: boolean | AutoFitColumnOpts;
|
|
1157
|
+
|
|
1158
|
+
/** Unwrapped text overflow behavior for browser rendering */
|
|
1159
|
+
overflow?: HTMLOverflowMode;
|
|
1160
|
+
|
|
1161
|
+
/** Browser-compatible text measurement callback used by autoFit and shrink-to-fit */
|
|
1162
|
+
measureText?: (text: string, font: string, style: CellStyle) => number;
|
|
1163
|
+
|
|
1164
|
+
/** Optional canvas-like object used for text measurement */
|
|
1165
|
+
canvas?: any;
|
|
1122
1166
|
}
|
|
1123
1167
|
|
|
1124
1168
|
export interface Sheet2JSONOpts extends DateNFOption {
|
|
@@ -1260,6 +1304,15 @@ export interface XLSX$Utils {
|
|
|
1260
1304
|
/** Validate worksheet merge ranges */
|
|
1261
1305
|
validate_merges(worksheet: WorkSheet, opts?: CommonOptions): MergeError[];
|
|
1262
1306
|
|
|
1307
|
+
/** Measure text width in browser pixels using Canvas when available */
|
|
1308
|
+
measure_text_width(text: string, style?: CellStyle, opts?: TextMeasureOpts): number;
|
|
1309
|
+
|
|
1310
|
+
/** Auto-fit worksheet columns based on formatted cell text */
|
|
1311
|
+
auto_fit_columns(worksheet: WorkSheet, opts?: AutoFitColumnOpts): ColInfo[];
|
|
1312
|
+
|
|
1313
|
+
/** Alias for auto_fit_columns */
|
|
1314
|
+
autofit_columns(worksheet: WorkSheet, opts?: AutoFitColumnOpts): ColInfo[];
|
|
1315
|
+
|
|
1263
1316
|
/** Convert XLSX column width to browser pixels */
|
|
1264
1317
|
col_width_to_px(width: number): number;
|
|
1265
1318
|
|
package/xlsx.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false */
|
|
5
5
|
var XLSX = {};
|
|
6
6
|
function make_xlsx_lib(XLSX){
|
|
7
|
-
XLSX.version = '0.21.
|
|
7
|
+
XLSX.version = '0.21.2';
|
|
8
8
|
var current_codepage = 1200, current_ansi = 1252;
|
|
9
9
|
/*global cptable:true, window */
|
|
10
10
|
var $cptable;
|
|
@@ -11110,7 +11110,7 @@ function resolve_style_obj_color(obj, themes) {
|
|
|
11110
11110
|
|
|
11111
11111
|
/* 18.3.1.13 width calculations */
|
|
11112
11112
|
/* [MS-OI29500] 2.1.595 Column Width & Formatting */
|
|
11113
|
-
var DEF_MDW =
|
|
11113
|
+
var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
|
|
11114
11114
|
function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); }
|
|
11115
11115
|
function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; }
|
|
11116
11116
|
function char2width(chr) { return (Math.round((chr * MDW + 5)/MDW*256))/256; }
|
|
@@ -11152,6 +11152,188 @@ function process_col(coll) {
|
|
|
11152
11152
|
if(coll.customWidth) delete coll.customWidth;
|
|
11153
11153
|
}
|
|
11154
11154
|
|
|
11155
|
+
var XLSX_COL_WIDTH_MAX = 255, XLSX_COL_WIDTH_PADDING = 5;
|
|
11156
|
+
function clamp_col_width(width) {
|
|
11157
|
+
return width > XLSX_COL_WIDTH_MAX ? XLSX_COL_WIDTH_MAX : width < 0 ? 0 : width;
|
|
11158
|
+
}
|
|
11159
|
+
function px2col(px) {
|
|
11160
|
+
var width = char2width(px2char(Math.max(0, px)));
|
|
11161
|
+
return clamp_col_width(width);
|
|
11162
|
+
}
|
|
11163
|
+
function col2px(col) {
|
|
11164
|
+
if(!col) return 64;
|
|
11165
|
+
if(col.wpx != null) return col.wpx;
|
|
11166
|
+
if(col.width != null) return width2px(col.width);
|
|
11167
|
+
if(col.wch != null) return width2px(char2width(col.wch));
|
|
11168
|
+
return 64;
|
|
11169
|
+
}
|
|
11170
|
+
function set_col_width_from_px(col, px) {
|
|
11171
|
+
if(!col) col = ({});
|
|
11172
|
+
col.wpx = Math.max(0, Math.ceil(px));
|
|
11173
|
+
col.wch = px2char(col.wpx);
|
|
11174
|
+
col.width = px2col(col.wpx);
|
|
11175
|
+
col.MDW = MDW;
|
|
11176
|
+
col.bestFit = true;
|
|
11177
|
+
col.customWidth = true;
|
|
11178
|
+
return col;
|
|
11179
|
+
}
|
|
11180
|
+
function style_font_size_pt(style) {
|
|
11181
|
+
var font = style && style.font || {};
|
|
11182
|
+
var sz = +font.sz;
|
|
11183
|
+
return sz > 0 ? sz : 11;
|
|
11184
|
+
}
|
|
11185
|
+
function style_font_family(style) {
|
|
11186
|
+
var font = style && style.font || {};
|
|
11187
|
+
return font.name || "Calibri";
|
|
11188
|
+
}
|
|
11189
|
+
function css_font_from_style(style) {
|
|
11190
|
+
var font = style && style.font || {};
|
|
11191
|
+
var parts = [];
|
|
11192
|
+
if(font.italic) parts.push("italic");
|
|
11193
|
+
if(font.bold) parts.push("bold");
|
|
11194
|
+
parts.push(style_font_size_pt(style) + "pt");
|
|
11195
|
+
var name = style_font_family(style);
|
|
11196
|
+
if(/[,\s'"]/.test(name)) name = '"' + String(name).replace(/"/g, '\\"') + '"';
|
|
11197
|
+
parts.push(name);
|
|
11198
|
+
return parts.join(" ");
|
|
11199
|
+
}
|
|
11200
|
+
function fallback_char_width(ch, fpx) {
|
|
11201
|
+
var cc = ch.charCodeAt(0);
|
|
11202
|
+
if(cc == 9 || cc == 32) return fpx * 0.33;
|
|
11203
|
+
if(cc >= 48 && cc <= 57) return fpx * 0.52;
|
|
11204
|
+
if(cc >= 65 && cc <= 90) return fpx * 0.62;
|
|
11205
|
+
if(cc >= 97 && cc <= 122) {
|
|
11206
|
+
if("iljtfr".indexOf(ch) > -1) return fpx * 0.28;
|
|
11207
|
+
if("mw".indexOf(ch) > -1) return fpx * 0.82;
|
|
11208
|
+
return fpx * 0.50;
|
|
11209
|
+
}
|
|
11210
|
+
if(cc >= 0x2E80) return fpx;
|
|
11211
|
+
return fpx * 0.52;
|
|
11212
|
+
}
|
|
11213
|
+
function fallback_text_width(text, style) {
|
|
11214
|
+
var fpx = pt2px_browser(style_font_size_pt(style)), width = 0;
|
|
11215
|
+
for(var i = 0; i < text.length; ++i) width += fallback_char_width(text.charAt(i), fpx);
|
|
11216
|
+
return width;
|
|
11217
|
+
}
|
|
11218
|
+
function measure_text_width(text, style, opts) {
|
|
11219
|
+
var o = opts || {};
|
|
11220
|
+
var str = text == null ? "" : String(text);
|
|
11221
|
+
var lines = str.split(/\r\n|\n|\r/g), max = 0, i = 0, w = 0;
|
|
11222
|
+
if(o.measureText) for(i = 0; i < lines.length; ++i) {
|
|
11223
|
+
w = +o.measureText(lines[i], css_font_from_style(style), style || {});
|
|
11224
|
+
if(isFinite(w) && w > max) max = w;
|
|
11225
|
+
}
|
|
11226
|
+
else {
|
|
11227
|
+
var canvas = o.canvas, ctx = null;
|
|
11228
|
+
if(!canvas && typeof document !== "undefined" && document.createElement) try { canvas = document.createElement("canvas"); } catch(e) {}
|
|
11229
|
+
try { ctx = canvas && canvas.getContext && canvas.getContext("2d"); } catch(e) { ctx = null; }
|
|
11230
|
+
if(ctx && ctx.measureText) {
|
|
11231
|
+
ctx.font = css_font_from_style(style);
|
|
11232
|
+
for(i = 0; i < lines.length; ++i) {
|
|
11233
|
+
w = ctx.measureText(lines[i]).width;
|
|
11234
|
+
if(isFinite(w) && w > max) max = w;
|
|
11235
|
+
}
|
|
11236
|
+
} else for(i = 0; i < lines.length; ++i) {
|
|
11237
|
+
w = fallback_text_width(lines[i], style || {});
|
|
11238
|
+
if(isFinite(w) && w > max) max = w;
|
|
11239
|
+
}
|
|
11240
|
+
}
|
|
11241
|
+
return max;
|
|
11242
|
+
}
|
|
11243
|
+
function auto_fit_cell_text(cell, opts) {
|
|
11244
|
+
if(!cell || cell.v == null) return "";
|
|
11245
|
+
if(cell.w == null && cell.t != 'z') format_cell(cell);
|
|
11246
|
+
return String(cell.w != null ? cell.w : cell.v);
|
|
11247
|
+
}
|
|
11248
|
+
function text_width_segments(text, wrap) {
|
|
11249
|
+
var lines = String(text == null ? "" : text).split(/\r\n|\n|\r/g), out = [], i = 0, j = 0, parts = null;
|
|
11250
|
+
if(!wrap) return lines;
|
|
11251
|
+
for(i = 0; i < lines.length; ++i) {
|
|
11252
|
+
parts = lines[i].split(/[\t \u00A0\-\/]+/);
|
|
11253
|
+
for(j = 0; j < parts.length; ++j) if(parts[j]) out.push(parts[j]);
|
|
11254
|
+
if(!parts.length || (parts.length == 1 && !parts[0])) out.push(lines[i]);
|
|
11255
|
+
}
|
|
11256
|
+
return out.length ? out : [""];
|
|
11257
|
+
}
|
|
11258
|
+
function effective_cell_style(ws, cell, R, C) {
|
|
11259
|
+
var out = ({}), cols = ws["!cols"] || [], rows = ws["!rows"] || [];
|
|
11260
|
+
if(cols[C] && cols[C].s) extend_style_obj(out, cols[C].s);
|
|
11261
|
+
if(rows[R] && rows[R].s) extend_style_obj(out, rows[R].s);
|
|
11262
|
+
if(cell && cell.s) extend_style_obj(out, cell.s);
|
|
11263
|
+
return out;
|
|
11264
|
+
}
|
|
11265
|
+
function measure_cell_text_width(cell, style, opts) {
|
|
11266
|
+
var o = opts || {}, text = auto_fit_cell_text(cell, o), align = style && style.alignment || {};
|
|
11267
|
+
var wrap = !!align.wrapText, segments = text_width_segments(text, wrap), max = 0, w = 0;
|
|
11268
|
+
for(var i = 0; i < segments.length; ++i) {
|
|
11269
|
+
w = measure_text_width(segments[i], style, o);
|
|
11270
|
+
if(w > max) max = w;
|
|
11271
|
+
}
|
|
11272
|
+
var indent = +align.indent || 0;
|
|
11273
|
+
if(indent > 0) max += indent * 3 * Math.max(1, MDW);
|
|
11274
|
+
var rotation = +align.textRotation || 0;
|
|
11275
|
+
if(rotation == 255) rotation = 90;
|
|
11276
|
+
if(rotation > 90) rotation = 90 - rotation;
|
|
11277
|
+
if(rotation < 0) rotation = -rotation;
|
|
11278
|
+
if(rotation > 0 && rotation < 90) {
|
|
11279
|
+
var rad = rotation * Math.PI / 180, fpx = pt2px_browser(style_font_size_pt(style));
|
|
11280
|
+
max = Math.abs(max * Math.cos(rad)) + Math.abs(fpx * Math.sin(rad));
|
|
11281
|
+
} else if(rotation >= 90) max = Math.max(MDW + XLSX_COL_WIDTH_PADDING, pt2px_browser(style_font_size_pt(style)) + 2);
|
|
11282
|
+
return max + (o.padding != null ? +o.padding : XLSX_COL_WIDTH_PADDING);
|
|
11283
|
+
}
|
|
11284
|
+
function merge_start_map(merges) {
|
|
11285
|
+
var out = {};
|
|
11286
|
+
for(var i = 0; i < merges.length; ++i) out[merges[i].s.r + ":" + merges[i].s.c] = merges[i];
|
|
11287
|
+
return out;
|
|
11288
|
+
}
|
|
11289
|
+
function is_covered_merge(merges, R, C) {
|
|
11290
|
+
for(var i = 0; i < merges.length; ++i) {
|
|
11291
|
+
var m = merges[i];
|
|
11292
|
+
if(m.s.r <= R && R <= m.e.r && m.s.c <= C && C <= m.e.c) return !(m.s.r == R && m.s.c == C);
|
|
11293
|
+
}
|
|
11294
|
+
return false;
|
|
11295
|
+
}
|
|
11296
|
+
function auto_fit_columns(ws, opts) {
|
|
11297
|
+
var o = opts || {}, oldMDW = MDW;
|
|
11298
|
+
if(o.MDW) MDW = +o.MDW || MDW;
|
|
11299
|
+
var r = o.range ? (typeof o.range == "string" ? decode_range(o.range) : o.range) : decode_range(ws["!ref"] || "A1");
|
|
11300
|
+
var base = ws["!cols"] || [], rows = ws["!rows"] || [], cols = [], widths = [];
|
|
11301
|
+
var minpx = o.minPx != null ? +o.minPx : o.min != null ? width2px(char2width(+o.min)) : 0;
|
|
11302
|
+
var maxpx = o.maxPx != null ? +o.maxPx : width2px(XLSX_COL_WIDTH_MAX);
|
|
11303
|
+
var merges = o.includeMerged === false ? [] : (ws["!merges"] || []);
|
|
11304
|
+
var starts = merge_start_map(merges), dense = ws["!data"] != null;
|
|
11305
|
+
var C = 0, R = 0, span = 0, m = null, j = 0, cell = null, style = null, need = 0, have = 0;
|
|
11306
|
+
for(C = r.s.c; C <= r.e.c; ++C) {
|
|
11307
|
+
cols[C] = dup(base[C] || {});
|
|
11308
|
+
if(cols[C] && cols[C].hidden && o.skipHidden) continue;
|
|
11309
|
+
widths[C] = cols[C] && (cols[C].wpx != null || cols[C].width != null || cols[C].wch != null) ? col2px(cols[C]) : minpx;
|
|
11310
|
+
}
|
|
11311
|
+
for(R = r.s.r; R <= r.e.r; ++R) {
|
|
11312
|
+
if(rows[R] && rows[R].hidden && o.skipHidden) continue;
|
|
11313
|
+
for(C = r.s.c; C <= r.e.c; ++C) {
|
|
11314
|
+
if(cols[C] && cols[C].hidden && o.skipHidden) continue;
|
|
11315
|
+
if(is_covered_merge(merges, R, C)) continue;
|
|
11316
|
+
cell = dense ? (ws["!data"][R]||[])[C] : ws[encode_cell({r:R,c:C})];
|
|
11317
|
+
if(!cell || cell.v == null) continue;
|
|
11318
|
+
style = effective_cell_style(ws, cell, R, C);
|
|
11319
|
+
need = measure_cell_text_width(cell, style, o);
|
|
11320
|
+
if(style && style.alignment && style.alignment.shrinkToFit && widths[C]) need = Math.min(need, widths[C]);
|
|
11321
|
+
m = starts[R + ":" + C];
|
|
11322
|
+
span = m ? m.e.c - m.s.c + 1 : 1;
|
|
11323
|
+
if(span > 1) {
|
|
11324
|
+
have = 0;
|
|
11325
|
+
for(j = 0; j < span; ++j) have += widths[C+j] || minpx;
|
|
11326
|
+
if(need > have) for(j = 0; j < span; ++j) widths[C+j] = Math.min(maxpx, Math.max(widths[C+j] || minpx, (widths[C+j] || minpx) + (need - have) / span));
|
|
11327
|
+
} else widths[C] = Math.min(maxpx, Math.max(widths[C] || minpx, need));
|
|
11328
|
+
}
|
|
11329
|
+
}
|
|
11330
|
+
for(C = r.s.c; C <= r.e.c; ++C) if(widths[C] != null) cols[C] = set_col_width_from_px(cols[C] || {}, Math.min(maxpx, Math.max(minpx, widths[C])));
|
|
11331
|
+
if(o.set === false) { MDW = oldMDW; return cols; }
|
|
11332
|
+
ws["!cols"] = cols;
|
|
11333
|
+
MDW = oldMDW;
|
|
11334
|
+
return cols;
|
|
11335
|
+
}
|
|
11336
|
+
|
|
11155
11337
|
var DEF_PPI = 96, PPI = DEF_PPI;
|
|
11156
11338
|
function px2pt(px) { return px * 96 / PPI; }
|
|
11157
11339
|
function pt2px(pt) { return pt * PPI / 96; }
|
|
@@ -16208,8 +16390,11 @@ function col_obj_w(C, col) {
|
|
|
16208
16390
|
else if(col.wch != null) wch = col.wch;
|
|
16209
16391
|
if(wch > -1) { p.width = char2width(wch); p.customWidth = 1; }
|
|
16210
16392
|
else if(col.width != null) p.width = col.width;
|
|
16393
|
+
if(p.width != null) p.width = clamp_col_width(p.width);
|
|
16211
16394
|
if(col.hidden) p.hidden = true;
|
|
16212
16395
|
if(col.level != null) { p.outlineLevel = p.level = col.level; }
|
|
16396
|
+
if(col.bestFit || col.bestfit) p.bestFit = true;
|
|
16397
|
+
if(col.customWidth || col.customwidth) p.customWidth = 1;
|
|
16213
16398
|
return p;
|
|
16214
16399
|
}
|
|
16215
16400
|
|
|
@@ -16567,10 +16752,13 @@ function parse_ws_xml_cols(columns, cols) {
|
|
|
16567
16752
|
for(var coli = 0; coli != cols.length; ++coli) {
|
|
16568
16753
|
var coll = parsexmltag(cols[coli], true);
|
|
16569
16754
|
if(coll.hidden) coll.hidden = parsexmlbool(coll.hidden);
|
|
16755
|
+
if(coll.bestFit) coll.bestFit = parsexmlbool(coll.bestFit);
|
|
16756
|
+
if(coll.customWidth) coll.customWidth = parsexmlbool(coll.customWidth);
|
|
16570
16757
|
var colm=parseInt(coll.min, 10)-1, colM=parseInt(coll.max,10)-1;
|
|
16571
16758
|
if(coll.outlineLevel) coll.level = (+coll.outlineLevel || 0);
|
|
16572
16759
|
delete coll.min; delete coll.max; coll.width = +coll.width;
|
|
16573
|
-
|
|
16760
|
+
/* OOXML widths share the workbook Normal-font MDW; do not infer a different scale per sheet. */
|
|
16761
|
+
if(!seencol && coll.width) { seencol = true; MDW = DEF_MDW; }
|
|
16574
16762
|
process_col(coll);
|
|
16575
16763
|
while(colm <= colM) columns[colm++] = dup(coll);
|
|
16576
16764
|
}
|
|
@@ -17740,7 +17928,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|
|
17740
17928
|
if(!opts.cellStyles) break;
|
|
17741
17929
|
while(val.e >= val.s) {
|
|
17742
17930
|
colinfo[val.e--] = { width: val.w/256, hidden: !!(val.flags & 0x01), level: val.level };
|
|
17743
|
-
if(!seencol) { seencol = true;
|
|
17931
|
+
if(!seencol) { seencol = true; MDW = DEF_MDW; }
|
|
17744
17932
|
process_col(colinfo[val.e+1]);
|
|
17745
17933
|
}
|
|
17746
17934
|
break;
|
|
@@ -21280,7 +21468,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
|
|
21280
21468
|
while(val.e >= val.s) {
|
|
21281
21469
|
colinfo[val.e--] = { width: val.w/256, level: (val.level || 0), hidden: !!(val.flags & 1) };
|
|
21282
21470
|
if(val.ixfe != null && XFs[val.ixfe]) colinfo[val.e+1].s = resolve_xls_style(XFs[val.ixfe], val.ixfe);
|
|
21283
|
-
if(!seencol) { seencol = true;
|
|
21471
|
+
if(!seencol) { seencol = true; MDW = DEF_MDW; }
|
|
21284
21472
|
process_col(colinfo[val.e+1]);
|
|
21285
21473
|
}
|
|
21286
21474
|
} break;
|
|
@@ -23708,8 +23896,6 @@ function html_cell_style(cell, opts) {
|
|
|
23708
23896
|
var alignment = s.alignment || {};
|
|
23709
23897
|
if(alignment.horizontal) css.push("text-align:" + alignment.horizontal);
|
|
23710
23898
|
if(alignment.vertical) css.push("vertical-align:" + alignment.vertical);
|
|
23711
|
-
if(alignment.wrapText) css.push("white-space:normal");
|
|
23712
|
-
if(alignment.shrinkToFit) css.push("font-size:smaller");
|
|
23713
23899
|
if(alignment.textRotation != null && alignment.textRotation !== 0) {
|
|
23714
23900
|
var deg = alignment.textRotation == 255 ? 90 : alignment.textRotation > 90 ? 90 - alignment.textRotation : alignment.textRotation;
|
|
23715
23901
|
css.push("transform:rotate(" + deg + "deg)");
|
|
@@ -23722,12 +23908,29 @@ function html_cell_style(cell, opts) {
|
|
|
23722
23908
|
add_html_border(css, "bottom", border.bottom);
|
|
23723
23909
|
return css.join(";");
|
|
23724
23910
|
}
|
|
23911
|
+
function html_cell_layout_style(cell, opts, C, CS, cols) {
|
|
23912
|
+
if(!opts || !cell) return "";
|
|
23913
|
+
var s = cell.s || {}, alignment = s.alignment || {}, css = [];
|
|
23914
|
+
if(opts.browserPixels || opts.autoFit) css.push("box-sizing:border-box;padding:0 2px;min-width:0");
|
|
23915
|
+
if(alignment.wrapText) css.push("white-space:pre-wrap;overflow-wrap:normal;word-break:normal");
|
|
23916
|
+
else {
|
|
23917
|
+
css.push("white-space:pre");
|
|
23918
|
+
if(alignment.shrinkToFit || opts.overflow == "clip" || opts.overflow == "hidden") css.push("overflow:hidden;text-overflow:clip");
|
|
23919
|
+
else css.push("overflow:visible");
|
|
23920
|
+
}
|
|
23921
|
+
if(alignment.shrinkToFit && cols && C != null) {
|
|
23922
|
+
var have = 0, span = CS || 1;
|
|
23923
|
+
for(var j = 0; j < span; ++j) have += html_col_width(cols[C+j]);
|
|
23924
|
+
var need = measure_cell_text_width(cell, s, opts);
|
|
23925
|
+
if(have > 0 && need > have) {
|
|
23926
|
+
var scale = Math.max(0.25, Math.min(1, have / need));
|
|
23927
|
+
css.push("font-size:" + Math.max(1, style_font_size_pt(s) * scale) + "pt");
|
|
23928
|
+
}
|
|
23929
|
+
}
|
|
23930
|
+
return css.join(";");
|
|
23931
|
+
}
|
|
23725
23932
|
function html_col_width(col) {
|
|
23726
|
-
|
|
23727
|
-
if(col.wpx != null) return col.wpx;
|
|
23728
|
-
if(col.width != null) return width2px(col.width);
|
|
23729
|
-
if(col.wch != null) return width2px(char2width(col.wch));
|
|
23730
|
-
return 64;
|
|
23933
|
+
return col2px(col);
|
|
23731
23934
|
}
|
|
23732
23935
|
function html_row_height(row) {
|
|
23733
23936
|
if(!row) return 20;
|
|
@@ -23742,7 +23945,7 @@ function make_html_row(ws, r, R, o) {
|
|
|
23742
23945
|
var sp = ({});
|
|
23743
23946
|
var dense = ws["!data"] != null;
|
|
23744
23947
|
var row = (ws["!rows"]||[])[R];
|
|
23745
|
-
var cols = ws["!cols"] || [];
|
|
23948
|
+
var cols = o && o._htmlCols || ws["!cols"] || [];
|
|
23746
23949
|
for(var C = r.s.c; C <= r.e.c; ++C) {
|
|
23747
23950
|
var RS = 0, CS = 0;
|
|
23748
23951
|
for(var j = 0; j < M.length; ++j) {
|
|
@@ -23785,6 +23988,8 @@ function make_html_row(ws, r, R, o) {
|
|
|
23785
23988
|
if(cell.l && (cell.l.Target || "#").charAt(0) != "#" && (!o.sanitizeLinks || (cell.l.Target || "").slice(0, 11).toLowerCase() != 'javascript:')) w = '<a href="' + escapehtml(cell.l.Target) +'">' + w + '</a>';
|
|
23786
23989
|
}
|
|
23787
23990
|
var cstyle = html_cell_style(stylecell, o);
|
|
23991
|
+
var lstyle = html_cell_layout_style(stylecell, o, C, CS, cols);
|
|
23992
|
+
if(lstyle) cstyle = cstyle ? cstyle + ";" + lstyle : lstyle;
|
|
23788
23993
|
if(cstyle) sp.style = cstyle;
|
|
23789
23994
|
sp.id = (o.id || "sjs") + "-" + coord;
|
|
23790
23995
|
oo.push(writextag('td', w, sp));
|
|
@@ -23816,9 +24021,9 @@ function html_to_workbook(str, opts) {
|
|
|
23816
24021
|
}
|
|
23817
24022
|
|
|
23818
24023
|
var HTML_EMU_PER_PIXEL = 9525;
|
|
23819
|
-
function html_anchor_pos(ws, anchor) {
|
|
24024
|
+
function html_anchor_pos(ws, anchor, opts) {
|
|
23820
24025
|
var out = {left:0, top:0, width:480, height:288};
|
|
23821
|
-
var cols = ws["!cols"] || [], rows = ws["!rows"] || [];
|
|
24026
|
+
var cols = opts && opts._htmlCols || ws["!cols"] || [], rows = ws["!rows"] || [];
|
|
23822
24027
|
var from = anchor && anchor.from || {col:0,row:0,colOff:0,rowOff:0};
|
|
23823
24028
|
var to = anchor && anchor.to;
|
|
23824
24029
|
for(var C = 0; C < (from.col||0); ++C) out.left += html_col_width(cols[C]);
|
|
@@ -23931,11 +24136,11 @@ function render_html_drawings(ws, opts) {
|
|
|
23931
24136
|
var out = [], drawings = ws["!drawings"] || {}, charts = ws["!charts"] || [];
|
|
23932
24137
|
if(opts && opts.drawings && drawings.images) drawings.images.forEach(function(img) {
|
|
23933
24138
|
if(!img || !img.dataURI) return;
|
|
23934
|
-
var pos = html_anchor_pos(ws, img.anchor);
|
|
24139
|
+
var pos = html_anchor_pos(ws, img.anchor, opts);
|
|
23935
24140
|
out.push('<img class="sjs-drawing-image" src="' + img.dataURI + '" style="' + html_abs_style(pos) + '"/>');
|
|
23936
24141
|
});
|
|
23937
24142
|
if(opts && opts.charts) charts.forEach(function(chart) {
|
|
23938
|
-
var pos = html_anchor_pos(ws, chart.anchor);
|
|
24143
|
+
var pos = html_anchor_pos(ws, chart.anchor, opts);
|
|
23939
24144
|
out.push('<div class="sjs-chart" style="' + html_abs_style(pos) + '">' + render_chart_svg(chart, pos.width, pos.height) + '</div>');
|
|
23940
24145
|
});
|
|
23941
24146
|
if(!out.length) return "";
|
|
@@ -23943,11 +24148,16 @@ function render_html_drawings(ws, opts) {
|
|
|
23943
24148
|
}
|
|
23944
24149
|
function make_html_preamble(ws, R, o) {
|
|
23945
24150
|
var out = [];
|
|
23946
|
-
var
|
|
23947
|
-
if(o && o.
|
|
24151
|
+
var tattr = ({}), tstyle = [];
|
|
24152
|
+
if(o && o.id) tattr.id = o.id;
|
|
24153
|
+
if(o && (o.browserPixels || o.autoFit)) tstyle.push("border-collapse:collapse;table-layout:fixed");
|
|
24154
|
+
if(tstyle.length) tattr.style = tstyle.join(";");
|
|
24155
|
+
var table = writextag("table", "", tattr).replace(/<\/table>$/, "");
|
|
24156
|
+
var cols = o && o._htmlCols || ws["!cols"];
|
|
24157
|
+
if(o && (o.browserPixels || o.autoFit) && cols) {
|
|
23948
24158
|
out.push("<colgroup>");
|
|
23949
24159
|
for(var C = R.s.c; C <= R.e.c; ++C) {
|
|
23950
|
-
var col =
|
|
24160
|
+
var col = cols[C], style = [];
|
|
23951
24161
|
style.push("width:" + html_col_width(col) + "px");
|
|
23952
24162
|
if(col && col.hidden) style.push("display:none");
|
|
23953
24163
|
out.push(writextag("col", null, {style:style.join(";")}));
|
|
@@ -23958,7 +24168,16 @@ function make_html_preamble(ws, R, o) {
|
|
|
23958
24168
|
}
|
|
23959
24169
|
|
|
23960
24170
|
function sheet_to_html(ws, opts/*, wb:?Workbook*/) {
|
|
23961
|
-
var o =
|
|
24171
|
+
var o = {};
|
|
24172
|
+
if(opts) for(var k in opts) if(Object.prototype.hasOwnProperty.call(opts, k)) o[k] = opts[k];
|
|
24173
|
+
if(o.autoFit) {
|
|
24174
|
+
var af = {set:false};
|
|
24175
|
+
if(typeof o.autoFit == "object") for(k in o.autoFit) if(Object.prototype.hasOwnProperty.call(o.autoFit, k)) af[k] = o.autoFit[k];
|
|
24176
|
+
if(o.measureText && af.measureText == null) af.measureText = o.measureText;
|
|
24177
|
+
if(o.canvas && af.canvas == null) af.canvas = o.canvas;
|
|
24178
|
+
o._htmlCols = auto_fit_columns(ws, af);
|
|
24179
|
+
if(o.browserPixels == null) o.browserPixels = true;
|
|
24180
|
+
}
|
|
23962
24181
|
var header = o.header != null ? o.header : HTML_BEGIN;
|
|
23963
24182
|
var footer = o.footer != null ? o.footer : HTML_END;
|
|
23964
24183
|
var out = [header];
|
|
@@ -25893,7 +26112,8 @@ var numbers_lut_new = function() {
|
|
|
25893
26112
|
function numbers_format_cell(cell, t, flags, ofmt, nfmt) {
|
|
25894
26113
|
var _a, _b, _c, _d;
|
|
25895
26114
|
var ctype = t & 255, ver = t >> 8;
|
|
25896
|
-
|
|
26115
|
+
/* Missing legacy/new format tables mean the default format. */
|
|
26116
|
+
var fmt = (ver >= 5 ? nfmt : ofmt) || [];
|
|
25897
26117
|
dur:
|
|
25898
26118
|
if (flags & (ver > 4 ? 8 : 4) && cell.t == "n" && ctype == 7) {
|
|
25899
26119
|
var dstyle = ((_a = fmt[7]) == null ? void 0 : _a[0]) ? varint_to_i32(fmt[7][0].data) : -1;
|
|
@@ -27808,6 +28028,7 @@ function drawing_mime(path) {
|
|
|
27808
28028
|
case "bmp": return "image/bmp";
|
|
27809
28029
|
case "svg": return "image/svg+xml";
|
|
27810
28030
|
case "jpg": case "jpeg": return "image/jpeg";
|
|
28031
|
+
case "tif": case "tiff": return "image/tiff";
|
|
27811
28032
|
default: return "application/octet-stream";
|
|
27812
28033
|
}
|
|
27813
28034
|
}
|
|
@@ -27823,7 +28044,9 @@ function parse_sheet_drawing(sheet, type, zip, path, idx, opts, wb) {
|
|
|
27823
28044
|
if(!img || !img.target) return;
|
|
27824
28045
|
var ipath = resolve_path(img.target, dfile);
|
|
27825
28046
|
var ibin = getzipbin(zip, ipath, true);
|
|
27826
|
-
|
|
28047
|
+
var contentType = drawing_mime(ipath);
|
|
28048
|
+
if(ibin) img.dataURI = "data:" + contentType + ";base64," + Base64_encode_arr(ibin);
|
|
28049
|
+
img.contentType = contentType;
|
|
27827
28050
|
img.path = ipath;
|
|
27828
28051
|
});
|
|
27829
28052
|
if(opts.charts && draw.charts && draw.charts.length) {
|
|
@@ -29186,6 +29409,9 @@ var utils = {
|
|
|
29186
29409
|
sheet_to_formulae: sheet_to_formulae,
|
|
29187
29410
|
sheet_to_row_object_array: sheet_to_json,
|
|
29188
29411
|
validate_merges: validate_merges,
|
|
29412
|
+
measure_text_width: measure_text_width,
|
|
29413
|
+
auto_fit_columns: auto_fit_columns,
|
|
29414
|
+
autofit_columns: auto_fit_columns,
|
|
29189
29415
|
col_width_to_px: width2px,
|
|
29190
29416
|
px_to_col_width: function(px) { return char2width(px2char(px)); },
|
|
29191
29417
|
row_height_to_px: pt2px_browser,
|