documonster 0.18.0 → 0.18.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.
- package/README.md +1 -1
- package/README_zh.md +1 -1
- package/dist/esm/modules/excel/core/workbook-model.js +1 -0
- package/dist/esm/modules/excel/core/workbook.browser.js +1 -0
- package/dist/esm/modules/excel/xlsb/conditional-format.js +54 -10
- package/dist/esm/modules/excel/xlsb/dxf.js +928 -0
- package/dist/esm/modules/excel/xlsb/fill.js +12 -2
- package/dist/esm/modules/excel/xlsb/filter-criteria.js +15 -8
- package/dist/esm/modules/excel/xlsb/font.js +5 -4
- package/dist/esm/modules/excel/xlsb/read/package.js +6 -0
- package/dist/esm/modules/excel/xlsb/styles.js +30 -359
- package/dist/esm/modules/excel/xlsb/write/package.js +13 -1
- package/dist/esm/modules/excel/xlsb/write/worksheet.js +16 -1
- package/dist/esm/modules/excel/xlsx/xform/simple/boolean-xform.js +12 -1
- package/dist/esm/modules/excel/xlsx/xform/style/alignment-xform.js +52 -16
- package/dist/esm/modules/excel/xlsx/xform/style/border-xform.js +24 -2
- package/dist/esm/modules/excel/xlsx/xform/style/dxf-extensions.js +55 -0
- package/dist/esm/modules/excel/xlsx/xform/style/dxf-xform.js +121 -6
- package/dist/esm/modules/excel/xlsx/xform/style/fill-xform.js +17 -10
- package/dist/esm/modules/excel/xlsx/xform/style/font-xform.js +32 -8
- package/dist/esm/modules/excel/xlsx/xform/style/styles-xform.js +83 -8
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +10 -0
- package/dist/esm/utils/text-measure.js +1 -1
- package/dist/iife/documonster.archive.iife.min.js +1 -1
- package/dist/iife/documonster.csv.iife.min.js +1 -1
- package/dist/iife/documonster.draw.iife.min.js +2 -2
- package/dist/iife/documonster.excel.iife.min.js +53 -53
- package/dist/iife/documonster.formula.iife.min.js +1 -1
- package/dist/iife/documonster.markdown.iife.min.js +1 -1
- package/dist/iife/documonster.mermaid.iife.min.js +2 -2
- package/dist/iife/documonster.pdf.iife.min.js +2 -2
- package/dist/iife/documonster.stream.iife.min.js +1 -1
- package/dist/iife/documonster.word.iife.min.js +60 -60
- package/dist/iife/documonster.xml.iife.min.js +1 -1
- package/dist/types/modules/excel/core/workbook-core.d.ts +10 -1
- package/dist/types/modules/excel/core/workbook-model.d.ts +3 -1
- package/dist/types/modules/excel/types.d.ts +33 -4
- package/dist/types/modules/excel/xlsb/conditional-format.d.ts +20 -2
- package/dist/types/modules/excel/xlsb/dxf.d.ts +56 -0
- package/dist/types/modules/excel/xlsb/fill.d.ts +5 -1
- package/dist/types/modules/excel/xlsb/filter-criteria.d.ts +9 -1
- package/dist/types/modules/excel/xlsb/font.d.ts +22 -0
- package/dist/types/modules/excel/xlsb/styles.d.ts +2 -13
- package/dist/types/modules/excel/xlsb/write/worksheet.d.ts +2 -0
- package/dist/types/modules/excel/xlsx/xform/simple/boolean-xform.d.ts +15 -0
- package/dist/types/modules/excel/xlsx/xform/style/alignment-xform.d.ts +13 -1
- package/dist/types/modules/excel/xlsx/xform/style/border-xform.d.ts +11 -0
- package/dist/types/modules/excel/xlsx/xform/style/dxf-extensions.d.ts +29 -0
- package/dist/types/modules/excel/xlsx/xform/style/dxf-xform.d.ts +34 -1
- package/dist/types/modules/excel/xlsx/xform/style/fill-xform.d.ts +15 -3
- package/dist/types/modules/excel/xlsx/xform/style/font-xform.d.ts +6 -0
- package/dist/types/modules/excel/xlsx/xform/style/styles-xform.d.ts +23 -0
- package/dist/types/utils/text-measure.d.ts +2 -1
- package/package.json +17 -18
package/README.md
CHANGED
|
@@ -211,7 +211,7 @@ const buffer = await Workbook.toBuffer(wb);
|
|
|
211
211
|
|
|
212
212
|
```html
|
|
213
213
|
<!-- Script tag (no bundler) — one IIFE per module, each under the shared `Documonster` global -->
|
|
214
|
-
<script src="https://unpkg.com/documonster@0.18.
|
|
214
|
+
<script src="https://unpkg.com/documonster@0.18.1/dist/iife/documonster.excel.iife.min.js"></script>
|
|
215
215
|
<script>
|
|
216
216
|
const { Workbook, Cell } = Documonster.Excel;
|
|
217
217
|
const wb = Workbook.create();
|
package/README_zh.md
CHANGED
|
@@ -198,7 +198,7 @@ const buffer = await Workbook.toBuffer(wb);
|
|
|
198
198
|
|
|
199
199
|
```html
|
|
200
200
|
<!-- Script 标签(无需打包工具)— 每个模块一个 IIFE,共享同一个 `Documonster` 全局 -->
|
|
201
|
-
<script src="https://unpkg.com/documonster@0.18.
|
|
201
|
+
<script src="https://unpkg.com/documonster@0.18.1/dist/iife/documonster.excel.iife.min.js"></script>
|
|
202
202
|
<script>
|
|
203
203
|
const { Workbook, Cell } = Documonster.Excel;
|
|
204
204
|
const wb = Workbook.create();
|
|
@@ -73,6 +73,7 @@ export function getWorkbookModel(wb) {
|
|
|
73
73
|
calcProperties: wb.calcProperties,
|
|
74
74
|
defaultFont: wb._defaultFont,
|
|
75
75
|
cellStyles: wb._cellStyles ? [...wb._cellStyles.values()] : undefined,
|
|
76
|
+
dxfs: wb._dxfs,
|
|
76
77
|
externalLinks: wb.externalLinks,
|
|
77
78
|
chartEntries: wb._chartEntries,
|
|
78
79
|
chartRels: wb._chartRels,
|
|
@@ -830,6 +830,7 @@ export function setWorkbookModel(wb, value) {
|
|
|
830
830
|
wb._cellStyles = value.cellStyles
|
|
831
831
|
? new Map(value.cellStyles.map(cs => [cs.name, cs]))
|
|
832
832
|
: undefined;
|
|
833
|
+
wb._dxfs = value.dxfs;
|
|
833
834
|
// Restore chart entries
|
|
834
835
|
wb._chartEntries = value.chartEntries || {};
|
|
835
836
|
wb._chartRels = value.chartRels || {};
|
|
@@ -62,30 +62,69 @@ const CF_OPER = {
|
|
|
62
62
|
/** `DXFId` meaning "no differential formatting". */
|
|
63
63
|
const NO_DXF = 0xffffffff;
|
|
64
64
|
/**
|
|
65
|
-
* The `BrtBeginDXFs` collection
|
|
65
|
+
* The `BrtBeginDXFs` collection, and where each format lands in it.
|
|
66
66
|
*
|
|
67
67
|
* A `dxfId` is an index into this, so it has to be built across every sheet before any of them is written
|
|
68
68
|
* — which is why this is a separate pass rather than something the sheet writer does. Deduplicated by
|
|
69
69
|
* serialised form, because two rules with the same fill share one entry in Excel's own output.
|
|
70
|
+
*
|
|
71
|
+
* **The table the workbook was read with comes first** (`options.source`). Not every holder of a `dxfId` is
|
|
72
|
+
* modelled: a `<colorFilter>` is preserved as XML with the number it was read with, and `fromSource` is how
|
|
73
|
+
* that number is translated. A modelled rule read from the same file holds the very object its `dxfId`
|
|
74
|
+
* resolved to, so it is matched by identity before its serialised form is ever computed.
|
|
75
|
+
*
|
|
76
|
+
* **A format this writer cannot encode gets no index at all** (`options.describe`), rather than an index the
|
|
77
|
+
* styles writer then leaves out. Handing it an index and dropping it later moved every format after it down by
|
|
78
|
+
* one, so each later rule — and every preserved reference — pointed at its neighbour's formatting. A format that
|
|
79
|
+
* encodes only *in part* is kept, and what it lost is returned in `lost`, once per distinct format.
|
|
70
80
|
*/
|
|
71
|
-
export function collectDxfs(blocks) {
|
|
81
|
+
export function collectDxfs(blocks, options = {}) {
|
|
82
|
+
const { source = [], describe = () => ({ writable: true, dropped: [] }) } = options;
|
|
72
83
|
const styles = [];
|
|
84
|
+
const lost = [];
|
|
73
85
|
const indexByKey = new Map();
|
|
86
|
+
const indexByIdentity = new Map();
|
|
87
|
+
const add = (style) => {
|
|
88
|
+
const known = indexByIdentity.get(style);
|
|
89
|
+
if (known !== undefined) {
|
|
90
|
+
return known;
|
|
91
|
+
}
|
|
92
|
+
const key = JSON.stringify(style);
|
|
93
|
+
let index = indexByKey.get(key);
|
|
94
|
+
if (index === undefined) {
|
|
95
|
+
const { writable, dropped } = describe(style);
|
|
96
|
+
index = writable ? styles.push(style) - 1 : NO_DXF;
|
|
97
|
+
if (writable && dropped.length > 0) {
|
|
98
|
+
lost.push(`differential format ${index}: ${dropped.join(", ")}`);
|
|
99
|
+
}
|
|
100
|
+
indexByKey.set(key, index);
|
|
101
|
+
}
|
|
102
|
+
indexByIdentity.set(style, index);
|
|
103
|
+
return index;
|
|
104
|
+
};
|
|
105
|
+
const sourceIndex = source.map(style => (style === undefined ? NO_DXF : add(style)));
|
|
74
106
|
for (const block of blocks) {
|
|
75
107
|
for (const rule of block.rules ?? []) {
|
|
76
|
-
if (rule.style
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
const key = JSON.stringify(rule.style);
|
|
80
|
-
if (!indexByKey.has(key)) {
|
|
81
|
-
indexByKey.set(key, styles.length);
|
|
82
|
-
styles.push(rule.style);
|
|
108
|
+
if (rule.style !== undefined) {
|
|
109
|
+
add(rule.style);
|
|
83
110
|
}
|
|
84
111
|
}
|
|
85
112
|
}
|
|
86
113
|
return {
|
|
87
114
|
styles,
|
|
88
|
-
indexOf: style => style === undefined
|
|
115
|
+
indexOf: style => style === undefined
|
|
116
|
+
? NO_DXF
|
|
117
|
+
: (indexByIdentity.get(style) ?? indexByKey.get(JSON.stringify(style)) ?? NO_DXF),
|
|
118
|
+
fromSource: sourceId => {
|
|
119
|
+
// With no table read from a file there is nothing to translate from: a stated id can only mean the table
|
|
120
|
+
// being written, which is how the XLSX writer treats the same XML — it writes the number as it is.
|
|
121
|
+
if (source.length === 0) {
|
|
122
|
+
return sourceId < styles.length ? sourceId : undefined;
|
|
123
|
+
}
|
|
124
|
+
const index = sourceIndex[sourceId];
|
|
125
|
+
return index === undefined || index === NO_DXF ? undefined : index;
|
|
126
|
+
},
|
|
127
|
+
lost
|
|
89
128
|
};
|
|
90
129
|
}
|
|
91
130
|
/**
|
|
@@ -112,6 +151,11 @@ export function conditionalFormattingRecords(blocks, dxf, context, resolvePriori
|
|
|
112
151
|
}
|
|
113
152
|
const encoded = (block.rules ?? [])
|
|
114
153
|
.map(rule => {
|
|
154
|
+
// A style `BrtDXF` cannot express gets no `dxfId` (see `collectDxfs`): the rule is still written and
|
|
155
|
+
// still applies, but without its formatting — which is a loss, and was silent.
|
|
156
|
+
if (rule.style !== undefined && dxf.indexOf(rule.style) === NO_DXF) {
|
|
157
|
+
lost.push(`conditional formatting format on ${block.ref ?? "an unnamed range"}`);
|
|
158
|
+
}
|
|
115
159
|
// The block's range travels with the rule, because a derived formula is written relative to the
|
|
116
160
|
// range's top-left cell and a single rule does not carry the range itself.
|
|
117
161
|
const payload = encodeRule({
|