@worm-vue3-print/core 1.0.1 → 1.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/index.cjs +65 -25
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +65 -25
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -931,6 +931,9 @@ function makeRenderRow(row, resolve, keepRaw = false) {
|
|
|
931
931
|
barcodeType: cell.barcodeType,
|
|
932
932
|
qrCodeLevel: cell.qrCodeLevel,
|
|
933
933
|
showBarcodeText: cell.showBarcodeText,
|
|
934
|
+
fit: cell.fit,
|
|
935
|
+
maxWidth: cell.maxWidth,
|
|
936
|
+
maxHeight: cell.maxHeight,
|
|
934
937
|
rowspan: cell.rowspan ?? 1,
|
|
935
938
|
colspan: cell.colspan ?? 1,
|
|
936
939
|
merged: cell.merged === true,
|
|
@@ -997,6 +1000,10 @@ function buildPageCss(template) {
|
|
|
997
1000
|
|
|
998
1001
|
/* \u2500\u2500 \u5168\u5C40\u91CD\u7F6E \u2500\u2500 */
|
|
999
1002
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
1003
|
+
|
|
1004
|
+
/* \u6253\u5370\u5FC5\u987B\u4FDD\u7559\u5143\u7D20\u80CC\u666F\u8272\uFF08Chromium \u9ED8\u8BA4\u5254\u9664\u80CC\u666F\uFF0C\u9700\u663E\u5F0F\u58F0\u660E\uFF09 */
|
|
1005
|
+
* { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
|
1006
|
+
|
|
1000
1007
|
body { font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif; }
|
|
1001
1008
|
|
|
1002
1009
|
/* \u2500\u2500 \u5C4F\u5E55\u9884\u89C8\uFF1A\u7070\u5E95 + \u7EB8\u5F20\u9634\u5F71/\u9875\u95F4\u8DDD\uFF1B\u6253\u5370\u65F6\u53BB\u9664 \u2500\u2500 */
|
|
@@ -1013,6 +1020,7 @@ body { font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, s
|
|
|
1013
1020
|
.print-page {
|
|
1014
1021
|
width: ${mm(paper.width)};
|
|
1015
1022
|
min-height: ${mm(paper.height)};
|
|
1023
|
+
background: ${template.pageBackground ?? "#fff"};
|
|
1016
1024
|
padding: ${mm(mt)} ${mm(mr)} ${mm(mb)} ${mm(ml)};
|
|
1017
1025
|
position: relative;
|
|
1018
1026
|
page-break-after: always;
|
|
@@ -1029,12 +1037,14 @@ body { font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, s
|
|
|
1029
1037
|
position: relative;
|
|
1030
1038
|
}
|
|
1031
1039
|
|
|
1032
|
-
/* \u2500\u2500 \u9875\u811A\uFF1A\u7EDD\u5BF9\u5B9A\u4F4D\u56FA\u5B9A\u5728\u9875\u9762\u5E95\u90E8\uFF08\u5185\u5BB9\u4E0D\u8DB3\u65F6\u4E0D\u968F\u6587\u6863\u6D41\u4E0A\u6D6E\uFF09 \u2500\u2500
|
|
1040
|
+
/* \u2500\u2500 \u9875\u811A\uFF1A\u7EDD\u5BF9\u5B9A\u4F4D\u56FA\u5B9A\u5728\u9875\u9762\u5E95\u90E8\uFF08\u5185\u5BB9\u4E0D\u8DB3\u65F6\u4E0D\u968F\u6587\u6863\u6D41\u4E0A\u6D6E\uFF09 \u2500\u2500
|
|
1041
|
+
\u7528\u663E\u5F0F top \u5B9A\u4F4D\u5230\u300C\u7EB8\u9AD8 - \u4E0B\u8FB9\u8DDD - \u9875\u811A\u9AD8\u300D\uFF0C\u4FDD\u8BC1\u4E0B\u8FB9\u8DDD\u751F\u6548\u3001
|
|
1042
|
+
\u4E0E\u8BBE\u8BA1\u5668 CanvasPaper \u7684\u4E09\u533A\u51E0\u4F55\u4E00\u81F4\u3002 */
|
|
1033
1043
|
.page-footer {
|
|
1034
1044
|
width: ${mm(contentWidth)};
|
|
1035
1045
|
height: ${mm(footerH)};
|
|
1036
1046
|
position: absolute;
|
|
1037
|
-
|
|
1047
|
+
top: ${mm(paper.height - mb - footerH)};
|
|
1038
1048
|
left: 0;
|
|
1039
1049
|
}
|
|
1040
1050
|
|
|
@@ -1088,7 +1098,7 @@ body { font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, s
|
|
|
1088
1098
|
}
|
|
1089
1099
|
`.trim();
|
|
1090
1100
|
}
|
|
1091
|
-
function elementPositionStyle(left, top, width, height) {
|
|
1101
|
+
function elementPositionStyle(left, top, width, height, zIndex) {
|
|
1092
1102
|
const parts = [
|
|
1093
1103
|
`position:absolute`,
|
|
1094
1104
|
`left:${mm(left)}`,
|
|
@@ -1098,6 +1108,9 @@ function elementPositionStyle(left, top, width, height) {
|
|
|
1098
1108
|
if (height !== void 0 && height > 0) {
|
|
1099
1109
|
parts.push(`height:${mm(height)}`);
|
|
1100
1110
|
}
|
|
1111
|
+
if (zIndex !== void 0) {
|
|
1112
|
+
parts.push(`z-index:${zIndex}`);
|
|
1113
|
+
}
|
|
1101
1114
|
return parts.join(";") + ";";
|
|
1102
1115
|
}
|
|
1103
1116
|
|
|
@@ -1139,18 +1152,15 @@ function buildFollowMap(sorted) {
|
|
|
1139
1152
|
}
|
|
1140
1153
|
return map;
|
|
1141
1154
|
}
|
|
1142
|
-
function followGroupHeight(el, members, template,
|
|
1143
|
-
|
|
1144
|
-
let
|
|
1155
|
+
function followGroupHeight(el, members, template, _measuredElements) {
|
|
1156
|
+
const tableBottom = tableDesignBottom(el);
|
|
1157
|
+
let maxBottom = tableBottom;
|
|
1145
1158
|
for (const id of members) {
|
|
1146
1159
|
const m = template.elements.find((e) => e.id === id);
|
|
1147
1160
|
if (!m) continue;
|
|
1148
|
-
|
|
1149
|
-
total += Math.max(mTop - cursorBottom, 0);
|
|
1150
|
-
total += measuredElements.get(id)?.measuredHeight ?? m.options?.height ?? 0;
|
|
1151
|
-
cursorBottom = mTop + (m.options?.height ?? 0);
|
|
1161
|
+
maxBottom = Math.max(maxBottom, (m.options?.top ?? 0) + (m.options?.height ?? 0));
|
|
1152
1162
|
}
|
|
1153
|
-
return
|
|
1163
|
+
return Math.max(maxBottom - tableBottom, 0);
|
|
1154
1164
|
}
|
|
1155
1165
|
function paginate(template, measuredElements) {
|
|
1156
1166
|
const paper = getPaperDimensions(template);
|
|
@@ -1536,7 +1546,7 @@ function renderElement(el, isMeasure, containerStyle, overrideTop, ctx) {
|
|
|
1536
1546
|
const top = overrideTop ?? opts.top ?? 0;
|
|
1537
1547
|
const width = opts.width ?? 100;
|
|
1538
1548
|
const height = opts.height ?? void 0;
|
|
1539
|
-
const style = containerStyle ?? elementPositionStyle(left, top, width, height);
|
|
1549
|
+
const style = containerStyle ?? elementPositionStyle(left, top, width, height, opts.zIndex);
|
|
1540
1550
|
const measureAttr = isMeasure ? ` data-measure-id="${el.id}"` : "";
|
|
1541
1551
|
const type = el.type || el.printElementType?.type || "text";
|
|
1542
1552
|
switch (type) {
|
|
@@ -1570,7 +1580,7 @@ function renderElement(el, isMeasure, containerStyle, overrideTop, ctx) {
|
|
|
1570
1580
|
return `<div class="print-element" style="${style}${textStyle(opts)}"${measureAttr}>${esc(opts.formatter ?? opts.testData ?? "")}</div>`;
|
|
1571
1581
|
}
|
|
1572
1582
|
}
|
|
1573
|
-
function codeImgHtml(value, cellType, opts, fallbackHtml, fill = false, codeRenderer) {
|
|
1583
|
+
function codeImgHtml(value, cellType, opts, fallbackHtml, fill = false, codeRenderer, fit, maxWidth, maxHeight) {
|
|
1574
1584
|
if (!value || !codeRenderer) return fallbackHtml;
|
|
1575
1585
|
try {
|
|
1576
1586
|
const svg = codeRenderer.render(value, cellType, {
|
|
@@ -1581,7 +1591,22 @@ function codeImgHtml(value, cellType, opts, fallbackHtml, fill = false, codeRend
|
|
|
1581
1591
|
fontSize: typeof opts.fontSize === "number" ? opts.fontSize : void 0
|
|
1582
1592
|
});
|
|
1583
1593
|
const src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
1584
|
-
const
|
|
1594
|
+
const styleParts = [];
|
|
1595
|
+
if (fill) {
|
|
1596
|
+
styleParts.push("width:100%", "height:100%", "object-fit:contain", "display:block", "margin:auto");
|
|
1597
|
+
} else {
|
|
1598
|
+
styleParts.push("max-width:100%", "max-height:100%", "display:block", "margin:auto");
|
|
1599
|
+
}
|
|
1600
|
+
if (fit) {
|
|
1601
|
+
styleParts.push(`object-fit:${fit}`);
|
|
1602
|
+
}
|
|
1603
|
+
if (maxWidth) {
|
|
1604
|
+
styleParts.push(`max-width:${maxWidth}mm`);
|
|
1605
|
+
}
|
|
1606
|
+
if (maxHeight) {
|
|
1607
|
+
styleParts.push(`max-height:${maxHeight}mm`);
|
|
1608
|
+
}
|
|
1609
|
+
const style = styleParts.join(";");
|
|
1585
1610
|
return `<img src="${src}" style="${style}" />`;
|
|
1586
1611
|
} catch {
|
|
1587
1612
|
return fallbackHtml;
|
|
@@ -1618,7 +1643,12 @@ function renderMatrixRows(renderRows, start, end, opts, withRowIndex, ctx) {
|
|
|
1618
1643
|
let inner;
|
|
1619
1644
|
if (cell.cellType === "barcode" || cell.cellType === "qrcode") {
|
|
1620
1645
|
const cellFill = cell.cellType === "barcode";
|
|
1621
|
-
inner = `<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;">${codeImgHtml(cell.content, cell.cellType, cell, esc(cell.content), cellFill, ctx?.codeRenderer)}</div>`;
|
|
1646
|
+
inner = `<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;">${codeImgHtml(cell.content, cell.cellType, cell, esc(cell.content), cellFill, ctx?.codeRenderer, cell.fit, cell.maxWidth, cell.maxHeight)}</div>`;
|
|
1647
|
+
} else if (cell.cellType === "image") {
|
|
1648
|
+
const fit = cell.fit || "contain";
|
|
1649
|
+
const maxWidth = cell.maxWidth ? `max-width:${cell.maxWidth}mm;` : "max-width:100%;";
|
|
1650
|
+
const maxHeight = cell.maxHeight ? `max-height:${cell.maxHeight}mm;` : "max-height:100%;";
|
|
1651
|
+
inner = `<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;"><img src="${esc(cell.content)}" style="object-fit:${fit};${maxWidth}${maxHeight}display:block;" /></div>`;
|
|
1622
1652
|
} else {
|
|
1623
1653
|
inner = esc(cell.content);
|
|
1624
1654
|
}
|
|
@@ -1640,7 +1670,7 @@ function matrixTableHtml(el, bodyHtml) {
|
|
|
1640
1670
|
}
|
|
1641
1671
|
function renderTableElement(el, isMeasure, measureAttr, ctx) {
|
|
1642
1672
|
const opts = el.options;
|
|
1643
|
-
const style = elementPositionStyle(opts.left ?? 0, opts.top ?? 0, opts.width ?? 100);
|
|
1673
|
+
const style = elementPositionStyle(opts.left ?? 0, opts.top ?? 0, opts.width ?? 100, void 0, opts.zIndex);
|
|
1644
1674
|
const renderRows = opts._renderRows ?? [];
|
|
1645
1675
|
const bodyHtml = renderMatrixRows(renderRows, 0, renderRows.length, opts, isMeasure, ctx);
|
|
1646
1676
|
return `<div class="print-element" style="${style};overflow:visible;"${measureAttr}>
|
|
@@ -1649,7 +1679,7 @@ function renderTableElement(el, isMeasure, measureAttr, ctx) {
|
|
|
1649
1679
|
}
|
|
1650
1680
|
function renderTableSlice(el, section, ctx) {
|
|
1651
1681
|
const opts = el.options;
|
|
1652
|
-
const style = elementPositionStyle(opts.left ?? 0, section.renderTop ?? opts.top ?? 0, opts.width ?? 100);
|
|
1682
|
+
const style = elementPositionStyle(opts.left ?? 0, section.renderTop ?? opts.top ?? 0, opts.width ?? 100, void 0, opts.zIndex);
|
|
1653
1683
|
const renderRows = opts._renderRows ?? [];
|
|
1654
1684
|
const startRow = section.startRow ?? 0;
|
|
1655
1685
|
const endRow = section.endRow ?? renderRows.length;
|
|
@@ -1691,7 +1721,9 @@ function renderFlowGroup(el, section, template, ctx) {
|
|
|
1691
1721
|
const tableLeft = opts.left ?? 0;
|
|
1692
1722
|
const tableWidth = opts.width ?? 100;
|
|
1693
1723
|
const groupTop = section.groupTop ?? opts.top ?? 0;
|
|
1694
|
-
const
|
|
1724
|
+
const tableBottom = tableDesignBottom(el);
|
|
1725
|
+
const zStyle = typeof opts.zIndex === "number" ? `z-index:${opts.zIndex};` : "";
|
|
1726
|
+
const style = `position:absolute;left:${mm(tableLeft)};top:${mm(groupTop)};width:${mm(tableWidth)};overflow:visible;${zStyle}`;
|
|
1695
1727
|
const startRow = section.startRow ?? 0;
|
|
1696
1728
|
const endRow = section.endRow ?? 0;
|
|
1697
1729
|
let sliceHtml = "";
|
|
@@ -1707,31 +1739,39 @@ function renderFlowGroup(el, section, template, ctx) {
|
|
|
1707
1739
|
${bodyHtml}${subtotalHtml}${summaryHtml}`)}
|
|
1708
1740
|
</div>`;
|
|
1709
1741
|
}
|
|
1710
|
-
|
|
1711
|
-
const
|
|
1742
|
+
const followIds = section.followElementIds ?? [];
|
|
1743
|
+
const followExtent = followIds.reduce((maxBottom, id) => {
|
|
1744
|
+
const m = findElement(template, id);
|
|
1745
|
+
if (!m) return maxBottom;
|
|
1746
|
+
return Math.max(maxBottom, (m.options?.top ?? 0) + (m.options?.height ?? 0));
|
|
1747
|
+
}, tableBottom);
|
|
1748
|
+
const followHtml = followIds.map((id) => {
|
|
1712
1749
|
const m = findElement(template, id);
|
|
1713
1750
|
if (!m) return "";
|
|
1714
1751
|
const mTop = m.options?.top ?? 0;
|
|
1715
1752
|
const mLeft = m.options?.left ?? 0;
|
|
1716
1753
|
const mWidth = m.options?.width ?? tableWidth;
|
|
1717
1754
|
const mHeight = m.options?.height ?? 0;
|
|
1718
|
-
const
|
|
1719
|
-
cursorBottom = mTop + mHeight;
|
|
1755
|
+
const mZ = m.options?.zIndex;
|
|
1720
1756
|
const type = m.type || m.printElementType?.type || "text";
|
|
1721
1757
|
const needsHeight = type === "rect" || type === "oval" || type === "image";
|
|
1722
1758
|
const flowStyle = [
|
|
1723
|
-
"position:
|
|
1759
|
+
"position:absolute",
|
|
1724
1760
|
`left:${mm(mLeft - tableLeft)}`,
|
|
1761
|
+
`top:${mm(mTop - tableBottom)}`,
|
|
1725
1762
|
`width:${mm(mWidth)}`,
|
|
1726
1763
|
...needsHeight && mHeight > 0 ? [`height:${mm(mHeight)}`] : [],
|
|
1727
|
-
`
|
|
1764
|
+
...typeof mZ === "number" ? [`z-index:${mZ}`] : [],
|
|
1728
1765
|
"overflow:visible"
|
|
1729
1766
|
].join(";") + ";";
|
|
1730
1767
|
return renderElement(m, false, flowStyle, void 0, ctx);
|
|
1731
1768
|
}).join("\n");
|
|
1769
|
+
const followWrap = followIds.length > 0 ? `<div class="flow-follow" style="position:relative;width:${mm(tableWidth)};height:${mm(Math.max(followExtent - tableBottom, 0))};overflow:visible;">
|
|
1770
|
+
${followHtml}
|
|
1771
|
+
</div>` : "";
|
|
1732
1772
|
return `<div class="flow-group" style="${style}">
|
|
1733
1773
|
${sliceHtml}
|
|
1734
|
-
${
|
|
1774
|
+
${followWrap}
|
|
1735
1775
|
</div>`;
|
|
1736
1776
|
}
|
|
1737
1777
|
function renderAreaElements(elements, _contentWidth, pageIndex, totalPages, ctx) {
|
package/dist/index.d.cts
CHANGED
|
@@ -139,6 +139,8 @@ interface TemplateData {
|
|
|
139
139
|
customWidth?: number;
|
|
140
140
|
/** 自定义纸张高度(mm),仅 paperSize='CUSTOM' 时生效 */
|
|
141
141
|
customHeight?: number;
|
|
142
|
+
/** 页面(纸张)背景色;未设置时默认白色 */
|
|
143
|
+
pageBackground?: string;
|
|
142
144
|
margins: {
|
|
143
145
|
top: number;
|
|
144
146
|
right: number;
|
|
@@ -206,7 +208,7 @@ interface RenderCell {
|
|
|
206
208
|
content: string;
|
|
207
209
|
/** 小计行专用:单元格原始 formatter 表达式,渲染阶段以当前页数据行上下文求值 */
|
|
208
210
|
rawFormatter?: string;
|
|
209
|
-
/** 内容类型:text(默认)/ barcode / qrcode,非 text 时 content
|
|
211
|
+
/** 内容类型:text(默认)/ barcode / qrcode / image,非 text 时 content 为码值或图片 URL */
|
|
210
212
|
cellType?: string;
|
|
211
213
|
/** 条形码码制(jsbarcode 格式名),仅 cellType='barcode' 时生效 */
|
|
212
214
|
barcodeType?: string;
|
|
@@ -214,6 +216,12 @@ interface RenderCell {
|
|
|
214
216
|
qrCodeLevel?: string;
|
|
215
217
|
/** 条形码下方是否显示文本,仅 cellType='barcode' 时生效 */
|
|
216
218
|
showBarcodeText?: boolean;
|
|
219
|
+
/** 图片缩放模式,仅 cellType='image' 时生效 */
|
|
220
|
+
fit?: string;
|
|
221
|
+
/** 图片最大宽度(mm),仅 cellType='image' 时生效 */
|
|
222
|
+
maxWidth?: number;
|
|
223
|
+
/** 图片最大高度(mm),仅 cellType='image' 时生效 */
|
|
224
|
+
maxHeight?: number;
|
|
217
225
|
rowspan: number;
|
|
218
226
|
colspan: number;
|
|
219
227
|
merged: boolean;
|
|
@@ -330,9 +338,10 @@ declare function mm(value: number): string;
|
|
|
330
338
|
*/
|
|
331
339
|
declare function buildPageCss(template: TemplateData): string;
|
|
332
340
|
/**
|
|
333
|
-
* 生成内联样式:元素绝对定位(mm
|
|
341
|
+
* 生成内联样式:元素绝对定位(mm 单位)。
|
|
342
|
+
* 可选 z-index:与设计器「层级」一致,未设置(undefined)时不输出(层叠回退 DOM 顺序)。
|
|
334
343
|
*/
|
|
335
|
-
declare function elementPositionStyle(left: number, top: number, width: number, height?: number): string;
|
|
344
|
+
declare function elementPositionStyle(left: number, top: number, width: number, height?: number, zIndex?: number): string;
|
|
336
345
|
|
|
337
346
|
/**
|
|
338
347
|
* 表格设计底部(mm)= 设计 top + 设计高度。
|
package/dist/index.d.ts
CHANGED
|
@@ -139,6 +139,8 @@ interface TemplateData {
|
|
|
139
139
|
customWidth?: number;
|
|
140
140
|
/** 自定义纸张高度(mm),仅 paperSize='CUSTOM' 时生效 */
|
|
141
141
|
customHeight?: number;
|
|
142
|
+
/** 页面(纸张)背景色;未设置时默认白色 */
|
|
143
|
+
pageBackground?: string;
|
|
142
144
|
margins: {
|
|
143
145
|
top: number;
|
|
144
146
|
right: number;
|
|
@@ -206,7 +208,7 @@ interface RenderCell {
|
|
|
206
208
|
content: string;
|
|
207
209
|
/** 小计行专用:单元格原始 formatter 表达式,渲染阶段以当前页数据行上下文求值 */
|
|
208
210
|
rawFormatter?: string;
|
|
209
|
-
/** 内容类型:text(默认)/ barcode / qrcode,非 text 时 content
|
|
211
|
+
/** 内容类型:text(默认)/ barcode / qrcode / image,非 text 时 content 为码值或图片 URL */
|
|
210
212
|
cellType?: string;
|
|
211
213
|
/** 条形码码制(jsbarcode 格式名),仅 cellType='barcode' 时生效 */
|
|
212
214
|
barcodeType?: string;
|
|
@@ -214,6 +216,12 @@ interface RenderCell {
|
|
|
214
216
|
qrCodeLevel?: string;
|
|
215
217
|
/** 条形码下方是否显示文本,仅 cellType='barcode' 时生效 */
|
|
216
218
|
showBarcodeText?: boolean;
|
|
219
|
+
/** 图片缩放模式,仅 cellType='image' 时生效 */
|
|
220
|
+
fit?: string;
|
|
221
|
+
/** 图片最大宽度(mm),仅 cellType='image' 时生效 */
|
|
222
|
+
maxWidth?: number;
|
|
223
|
+
/** 图片最大高度(mm),仅 cellType='image' 时生效 */
|
|
224
|
+
maxHeight?: number;
|
|
217
225
|
rowspan: number;
|
|
218
226
|
colspan: number;
|
|
219
227
|
merged: boolean;
|
|
@@ -330,9 +338,10 @@ declare function mm(value: number): string;
|
|
|
330
338
|
*/
|
|
331
339
|
declare function buildPageCss(template: TemplateData): string;
|
|
332
340
|
/**
|
|
333
|
-
* 生成内联样式:元素绝对定位(mm
|
|
341
|
+
* 生成内联样式:元素绝对定位(mm 单位)。
|
|
342
|
+
* 可选 z-index:与设计器「层级」一致,未设置(undefined)时不输出(层叠回退 DOM 顺序)。
|
|
334
343
|
*/
|
|
335
|
-
declare function elementPositionStyle(left: number, top: number, width: number, height?: number): string;
|
|
344
|
+
declare function elementPositionStyle(left: number, top: number, width: number, height?: number, zIndex?: number): string;
|
|
336
345
|
|
|
337
346
|
/**
|
|
338
347
|
* 表格设计底部(mm)= 设计 top + 设计高度。
|
package/dist/index.js
CHANGED
|
@@ -874,6 +874,9 @@ function makeRenderRow(row, resolve, keepRaw = false) {
|
|
|
874
874
|
barcodeType: cell.barcodeType,
|
|
875
875
|
qrCodeLevel: cell.qrCodeLevel,
|
|
876
876
|
showBarcodeText: cell.showBarcodeText,
|
|
877
|
+
fit: cell.fit,
|
|
878
|
+
maxWidth: cell.maxWidth,
|
|
879
|
+
maxHeight: cell.maxHeight,
|
|
877
880
|
rowspan: cell.rowspan ?? 1,
|
|
878
881
|
colspan: cell.colspan ?? 1,
|
|
879
882
|
merged: cell.merged === true,
|
|
@@ -940,6 +943,10 @@ function buildPageCss(template) {
|
|
|
940
943
|
|
|
941
944
|
/* \u2500\u2500 \u5168\u5C40\u91CD\u7F6E \u2500\u2500 */
|
|
942
945
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
946
|
+
|
|
947
|
+
/* \u6253\u5370\u5FC5\u987B\u4FDD\u7559\u5143\u7D20\u80CC\u666F\u8272\uFF08Chromium \u9ED8\u8BA4\u5254\u9664\u80CC\u666F\uFF0C\u9700\u663E\u5F0F\u58F0\u660E\uFF09 */
|
|
948
|
+
* { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
|
949
|
+
|
|
943
950
|
body { font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif; }
|
|
944
951
|
|
|
945
952
|
/* \u2500\u2500 \u5C4F\u5E55\u9884\u89C8\uFF1A\u7070\u5E95 + \u7EB8\u5F20\u9634\u5F71/\u9875\u95F4\u8DDD\uFF1B\u6253\u5370\u65F6\u53BB\u9664 \u2500\u2500 */
|
|
@@ -956,6 +963,7 @@ body { font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, s
|
|
|
956
963
|
.print-page {
|
|
957
964
|
width: ${mm(paper.width)};
|
|
958
965
|
min-height: ${mm(paper.height)};
|
|
966
|
+
background: ${template.pageBackground ?? "#fff"};
|
|
959
967
|
padding: ${mm(mt)} ${mm(mr)} ${mm(mb)} ${mm(ml)};
|
|
960
968
|
position: relative;
|
|
961
969
|
page-break-after: always;
|
|
@@ -972,12 +980,14 @@ body { font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, s
|
|
|
972
980
|
position: relative;
|
|
973
981
|
}
|
|
974
982
|
|
|
975
|
-
/* \u2500\u2500 \u9875\u811A\uFF1A\u7EDD\u5BF9\u5B9A\u4F4D\u56FA\u5B9A\u5728\u9875\u9762\u5E95\u90E8\uFF08\u5185\u5BB9\u4E0D\u8DB3\u65F6\u4E0D\u968F\u6587\u6863\u6D41\u4E0A\u6D6E\uFF09 \u2500\u2500
|
|
983
|
+
/* \u2500\u2500 \u9875\u811A\uFF1A\u7EDD\u5BF9\u5B9A\u4F4D\u56FA\u5B9A\u5728\u9875\u9762\u5E95\u90E8\uFF08\u5185\u5BB9\u4E0D\u8DB3\u65F6\u4E0D\u968F\u6587\u6863\u6D41\u4E0A\u6D6E\uFF09 \u2500\u2500
|
|
984
|
+
\u7528\u663E\u5F0F top \u5B9A\u4F4D\u5230\u300C\u7EB8\u9AD8 - \u4E0B\u8FB9\u8DDD - \u9875\u811A\u9AD8\u300D\uFF0C\u4FDD\u8BC1\u4E0B\u8FB9\u8DDD\u751F\u6548\u3001
|
|
985
|
+
\u4E0E\u8BBE\u8BA1\u5668 CanvasPaper \u7684\u4E09\u533A\u51E0\u4F55\u4E00\u81F4\u3002 */
|
|
976
986
|
.page-footer {
|
|
977
987
|
width: ${mm(contentWidth)};
|
|
978
988
|
height: ${mm(footerH)};
|
|
979
989
|
position: absolute;
|
|
980
|
-
|
|
990
|
+
top: ${mm(paper.height - mb - footerH)};
|
|
981
991
|
left: 0;
|
|
982
992
|
}
|
|
983
993
|
|
|
@@ -1031,7 +1041,7 @@ body { font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, s
|
|
|
1031
1041
|
}
|
|
1032
1042
|
`.trim();
|
|
1033
1043
|
}
|
|
1034
|
-
function elementPositionStyle(left, top, width, height) {
|
|
1044
|
+
function elementPositionStyle(left, top, width, height, zIndex) {
|
|
1035
1045
|
const parts = [
|
|
1036
1046
|
`position:absolute`,
|
|
1037
1047
|
`left:${mm(left)}`,
|
|
@@ -1041,6 +1051,9 @@ function elementPositionStyle(left, top, width, height) {
|
|
|
1041
1051
|
if (height !== void 0 && height > 0) {
|
|
1042
1052
|
parts.push(`height:${mm(height)}`);
|
|
1043
1053
|
}
|
|
1054
|
+
if (zIndex !== void 0) {
|
|
1055
|
+
parts.push(`z-index:${zIndex}`);
|
|
1056
|
+
}
|
|
1044
1057
|
return parts.join(";") + ";";
|
|
1045
1058
|
}
|
|
1046
1059
|
|
|
@@ -1082,18 +1095,15 @@ function buildFollowMap(sorted) {
|
|
|
1082
1095
|
}
|
|
1083
1096
|
return map;
|
|
1084
1097
|
}
|
|
1085
|
-
function followGroupHeight(el, members, template,
|
|
1086
|
-
|
|
1087
|
-
let
|
|
1098
|
+
function followGroupHeight(el, members, template, _measuredElements) {
|
|
1099
|
+
const tableBottom = tableDesignBottom(el);
|
|
1100
|
+
let maxBottom = tableBottom;
|
|
1088
1101
|
for (const id of members) {
|
|
1089
1102
|
const m = template.elements.find((e) => e.id === id);
|
|
1090
1103
|
if (!m) continue;
|
|
1091
|
-
|
|
1092
|
-
total += Math.max(mTop - cursorBottom, 0);
|
|
1093
|
-
total += measuredElements.get(id)?.measuredHeight ?? m.options?.height ?? 0;
|
|
1094
|
-
cursorBottom = mTop + (m.options?.height ?? 0);
|
|
1104
|
+
maxBottom = Math.max(maxBottom, (m.options?.top ?? 0) + (m.options?.height ?? 0));
|
|
1095
1105
|
}
|
|
1096
|
-
return
|
|
1106
|
+
return Math.max(maxBottom - tableBottom, 0);
|
|
1097
1107
|
}
|
|
1098
1108
|
function paginate(template, measuredElements) {
|
|
1099
1109
|
const paper = getPaperDimensions(template);
|
|
@@ -1479,7 +1489,7 @@ function renderElement(el, isMeasure, containerStyle, overrideTop, ctx) {
|
|
|
1479
1489
|
const top = overrideTop ?? opts.top ?? 0;
|
|
1480
1490
|
const width = opts.width ?? 100;
|
|
1481
1491
|
const height = opts.height ?? void 0;
|
|
1482
|
-
const style = containerStyle ?? elementPositionStyle(left, top, width, height);
|
|
1492
|
+
const style = containerStyle ?? elementPositionStyle(left, top, width, height, opts.zIndex);
|
|
1483
1493
|
const measureAttr = isMeasure ? ` data-measure-id="${el.id}"` : "";
|
|
1484
1494
|
const type = el.type || el.printElementType?.type || "text";
|
|
1485
1495
|
switch (type) {
|
|
@@ -1513,7 +1523,7 @@ function renderElement(el, isMeasure, containerStyle, overrideTop, ctx) {
|
|
|
1513
1523
|
return `<div class="print-element" style="${style}${textStyle(opts)}"${measureAttr}>${esc(opts.formatter ?? opts.testData ?? "")}</div>`;
|
|
1514
1524
|
}
|
|
1515
1525
|
}
|
|
1516
|
-
function codeImgHtml(value, cellType, opts, fallbackHtml, fill = false, codeRenderer) {
|
|
1526
|
+
function codeImgHtml(value, cellType, opts, fallbackHtml, fill = false, codeRenderer, fit, maxWidth, maxHeight) {
|
|
1517
1527
|
if (!value || !codeRenderer) return fallbackHtml;
|
|
1518
1528
|
try {
|
|
1519
1529
|
const svg = codeRenderer.render(value, cellType, {
|
|
@@ -1524,7 +1534,22 @@ function codeImgHtml(value, cellType, opts, fallbackHtml, fill = false, codeRend
|
|
|
1524
1534
|
fontSize: typeof opts.fontSize === "number" ? opts.fontSize : void 0
|
|
1525
1535
|
});
|
|
1526
1536
|
const src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
1527
|
-
const
|
|
1537
|
+
const styleParts = [];
|
|
1538
|
+
if (fill) {
|
|
1539
|
+
styleParts.push("width:100%", "height:100%", "object-fit:contain", "display:block", "margin:auto");
|
|
1540
|
+
} else {
|
|
1541
|
+
styleParts.push("max-width:100%", "max-height:100%", "display:block", "margin:auto");
|
|
1542
|
+
}
|
|
1543
|
+
if (fit) {
|
|
1544
|
+
styleParts.push(`object-fit:${fit}`);
|
|
1545
|
+
}
|
|
1546
|
+
if (maxWidth) {
|
|
1547
|
+
styleParts.push(`max-width:${maxWidth}mm`);
|
|
1548
|
+
}
|
|
1549
|
+
if (maxHeight) {
|
|
1550
|
+
styleParts.push(`max-height:${maxHeight}mm`);
|
|
1551
|
+
}
|
|
1552
|
+
const style = styleParts.join(";");
|
|
1528
1553
|
return `<img src="${src}" style="${style}" />`;
|
|
1529
1554
|
} catch {
|
|
1530
1555
|
return fallbackHtml;
|
|
@@ -1561,7 +1586,12 @@ function renderMatrixRows(renderRows, start, end, opts, withRowIndex, ctx) {
|
|
|
1561
1586
|
let inner;
|
|
1562
1587
|
if (cell.cellType === "barcode" || cell.cellType === "qrcode") {
|
|
1563
1588
|
const cellFill = cell.cellType === "barcode";
|
|
1564
|
-
inner = `<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;">${codeImgHtml(cell.content, cell.cellType, cell, esc(cell.content), cellFill, ctx?.codeRenderer)}</div>`;
|
|
1589
|
+
inner = `<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;">${codeImgHtml(cell.content, cell.cellType, cell, esc(cell.content), cellFill, ctx?.codeRenderer, cell.fit, cell.maxWidth, cell.maxHeight)}</div>`;
|
|
1590
|
+
} else if (cell.cellType === "image") {
|
|
1591
|
+
const fit = cell.fit || "contain";
|
|
1592
|
+
const maxWidth = cell.maxWidth ? `max-width:${cell.maxWidth}mm;` : "max-width:100%;";
|
|
1593
|
+
const maxHeight = cell.maxHeight ? `max-height:${cell.maxHeight}mm;` : "max-height:100%;";
|
|
1594
|
+
inner = `<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;"><img src="${esc(cell.content)}" style="object-fit:${fit};${maxWidth}${maxHeight}display:block;" /></div>`;
|
|
1565
1595
|
} else {
|
|
1566
1596
|
inner = esc(cell.content);
|
|
1567
1597
|
}
|
|
@@ -1583,7 +1613,7 @@ function matrixTableHtml(el, bodyHtml) {
|
|
|
1583
1613
|
}
|
|
1584
1614
|
function renderTableElement(el, isMeasure, measureAttr, ctx) {
|
|
1585
1615
|
const opts = el.options;
|
|
1586
|
-
const style = elementPositionStyle(opts.left ?? 0, opts.top ?? 0, opts.width ?? 100);
|
|
1616
|
+
const style = elementPositionStyle(opts.left ?? 0, opts.top ?? 0, opts.width ?? 100, void 0, opts.zIndex);
|
|
1587
1617
|
const renderRows = opts._renderRows ?? [];
|
|
1588
1618
|
const bodyHtml = renderMatrixRows(renderRows, 0, renderRows.length, opts, isMeasure, ctx);
|
|
1589
1619
|
return `<div class="print-element" style="${style};overflow:visible;"${measureAttr}>
|
|
@@ -1592,7 +1622,7 @@ function renderTableElement(el, isMeasure, measureAttr, ctx) {
|
|
|
1592
1622
|
}
|
|
1593
1623
|
function renderTableSlice(el, section, ctx) {
|
|
1594
1624
|
const opts = el.options;
|
|
1595
|
-
const style = elementPositionStyle(opts.left ?? 0, section.renderTop ?? opts.top ?? 0, opts.width ?? 100);
|
|
1625
|
+
const style = elementPositionStyle(opts.left ?? 0, section.renderTop ?? opts.top ?? 0, opts.width ?? 100, void 0, opts.zIndex);
|
|
1596
1626
|
const renderRows = opts._renderRows ?? [];
|
|
1597
1627
|
const startRow = section.startRow ?? 0;
|
|
1598
1628
|
const endRow = section.endRow ?? renderRows.length;
|
|
@@ -1634,7 +1664,9 @@ function renderFlowGroup(el, section, template, ctx) {
|
|
|
1634
1664
|
const tableLeft = opts.left ?? 0;
|
|
1635
1665
|
const tableWidth = opts.width ?? 100;
|
|
1636
1666
|
const groupTop = section.groupTop ?? opts.top ?? 0;
|
|
1637
|
-
const
|
|
1667
|
+
const tableBottom = tableDesignBottom(el);
|
|
1668
|
+
const zStyle = typeof opts.zIndex === "number" ? `z-index:${opts.zIndex};` : "";
|
|
1669
|
+
const style = `position:absolute;left:${mm(tableLeft)};top:${mm(groupTop)};width:${mm(tableWidth)};overflow:visible;${zStyle}`;
|
|
1638
1670
|
const startRow = section.startRow ?? 0;
|
|
1639
1671
|
const endRow = section.endRow ?? 0;
|
|
1640
1672
|
let sliceHtml = "";
|
|
@@ -1650,31 +1682,39 @@ function renderFlowGroup(el, section, template, ctx) {
|
|
|
1650
1682
|
${bodyHtml}${subtotalHtml}${summaryHtml}`)}
|
|
1651
1683
|
</div>`;
|
|
1652
1684
|
}
|
|
1653
|
-
|
|
1654
|
-
const
|
|
1685
|
+
const followIds = section.followElementIds ?? [];
|
|
1686
|
+
const followExtent = followIds.reduce((maxBottom, id) => {
|
|
1687
|
+
const m = findElement(template, id);
|
|
1688
|
+
if (!m) return maxBottom;
|
|
1689
|
+
return Math.max(maxBottom, (m.options?.top ?? 0) + (m.options?.height ?? 0));
|
|
1690
|
+
}, tableBottom);
|
|
1691
|
+
const followHtml = followIds.map((id) => {
|
|
1655
1692
|
const m = findElement(template, id);
|
|
1656
1693
|
if (!m) return "";
|
|
1657
1694
|
const mTop = m.options?.top ?? 0;
|
|
1658
1695
|
const mLeft = m.options?.left ?? 0;
|
|
1659
1696
|
const mWidth = m.options?.width ?? tableWidth;
|
|
1660
1697
|
const mHeight = m.options?.height ?? 0;
|
|
1661
|
-
const
|
|
1662
|
-
cursorBottom = mTop + mHeight;
|
|
1698
|
+
const mZ = m.options?.zIndex;
|
|
1663
1699
|
const type = m.type || m.printElementType?.type || "text";
|
|
1664
1700
|
const needsHeight = type === "rect" || type === "oval" || type === "image";
|
|
1665
1701
|
const flowStyle = [
|
|
1666
|
-
"position:
|
|
1702
|
+
"position:absolute",
|
|
1667
1703
|
`left:${mm(mLeft - tableLeft)}`,
|
|
1704
|
+
`top:${mm(mTop - tableBottom)}`,
|
|
1668
1705
|
`width:${mm(mWidth)}`,
|
|
1669
1706
|
...needsHeight && mHeight > 0 ? [`height:${mm(mHeight)}`] : [],
|
|
1670
|
-
`
|
|
1707
|
+
...typeof mZ === "number" ? [`z-index:${mZ}`] : [],
|
|
1671
1708
|
"overflow:visible"
|
|
1672
1709
|
].join(";") + ";";
|
|
1673
1710
|
return renderElement(m, false, flowStyle, void 0, ctx);
|
|
1674
1711
|
}).join("\n");
|
|
1712
|
+
const followWrap = followIds.length > 0 ? `<div class="flow-follow" style="position:relative;width:${mm(tableWidth)};height:${mm(Math.max(followExtent - tableBottom, 0))};overflow:visible;">
|
|
1713
|
+
${followHtml}
|
|
1714
|
+
</div>` : "";
|
|
1675
1715
|
return `<div class="flow-group" style="${style}">
|
|
1676
1716
|
${sliceHtml}
|
|
1677
|
-
${
|
|
1717
|
+
${followWrap}
|
|
1678
1718
|
</div>`;
|
|
1679
1719
|
}
|
|
1680
1720
|
function renderAreaElements(elements, _contentWidth, pageIndex, totalPages, ctx) {
|