@worm-vue3-print/core 1.3.6 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.cjs +206 -116
- package/dist/browser/index.d.cts +3 -3
- package/dist/browser/index.d.ts +3 -3
- package/dist/browser/index.js +7 -3
- package/dist/{chunk-JQUJ7AF3.js → chunk-TQJGFV2V.js} +207 -115
- package/dist/{chunk-GLNQXOMO.js → chunk-ZKHVOCU5.js} +2 -2
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.cts +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +1 -1
- package/dist/designer/index.cjs +534 -226
- package/dist/designer/index.d.cts +200 -5
- package/dist/designer/index.d.ts +200 -5
- package/dist/designer/index.js +412 -155
- package/dist/dom-executor.iife.global.js +6 -6
- package/dist/{driver-CFm0C_yX.d.cts → driver-hJxBl2_n.d.cts} +24 -4
- package/dist/{driver-CFm0C_yX.d.ts → driver-hJxBl2_n.d.ts} +24 -4
- package/dist/index.cjs +201 -115
- package/dist/index.d.cts +6 -8
- package/dist/index.d.ts +6 -8
- package/dist/index.js +3 -3
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +2 -2
- package/dist/node/index.d.ts +2 -2
- package/dist/node/index.js +1 -1
- package/dist/{ports-Bdst9MWJ.d.ts → ports-B-Jb2XwT.d.cts} +9 -3
- package/dist/{ports-BXYcHExa.d.cts → ports-CJ0SUYFt.d.ts} +9 -3
- package/package.json +1 -1
package/dist/browser/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @worm-vue3-print/core v1.3.
|
|
2
|
+
* @worm-vue3-print/core v1.3.8
|
|
3
3
|
* Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
|
|
4
4
|
* SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
|
|
5
5
|
* SPDX-License-Identifier: MIT
|
|
@@ -292,6 +292,10 @@ function renderBarcodeSvg(value, opts) {
|
|
|
292
292
|
svg.setAttribute("shape-rendering", "crispEdges");
|
|
293
293
|
return svg.outerHTML;
|
|
294
294
|
}
|
|
295
|
+
var QR_DEFAULT_QUIET_MODULES = 0;
|
|
296
|
+
function qrQuietModules(value) {
|
|
297
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : QR_DEFAULT_QUIET_MODULES;
|
|
298
|
+
}
|
|
295
299
|
function renderQrSvg(value, opts) {
|
|
296
300
|
const level = (opts.qrCodeLevel ?? "M").toUpperCase();
|
|
297
301
|
const qr = import_qrcode.default.create(value, {
|
|
@@ -300,7 +304,7 @@ function renderQrSvg(value, opts) {
|
|
|
300
304
|
const modules = qr.modules;
|
|
301
305
|
const size = modules.size;
|
|
302
306
|
const dot = 4;
|
|
303
|
-
const quiet =
|
|
307
|
+
const quiet = qrQuietModules(opts.qrQuietZone) * dot;
|
|
304
308
|
const dim = size * dot + quiet * 2;
|
|
305
309
|
let rects = "";
|
|
306
310
|
for (let y = 0; y < size; y++) {
|
|
@@ -370,6 +374,9 @@ function parseCellFitKey(key) {
|
|
|
370
374
|
if (!Number.isFinite(rowIndex) || !Number.isFinite(colIndex)) return void 0;
|
|
371
375
|
return { elementId: key.slice(0, first), kind, rowIndex, colIndex };
|
|
372
376
|
}
|
|
377
|
+
function cellImageBoxMm(fit, capMm) {
|
|
378
|
+
return (fit || "contain") === "cover" ? capMm : void 0;
|
|
379
|
+
}
|
|
373
380
|
function cellFitWidthMm(colWidths, colIndex, cell, defaultPadding = 1) {
|
|
374
381
|
const span = Math.max(cell?.colspan ?? 1, 1);
|
|
375
382
|
let width = 0;
|
|
@@ -1299,55 +1306,55 @@ function formatDate(value, fmt) {
|
|
|
1299
1306
|
const pad3 = (n) => String(n).padStart(2, "0");
|
|
1300
1307
|
return fmt.replace("YYYY", String(date.getFullYear())).replace("MM", pad3(date.getMonth() + 1)).replace("DD", pad3(date.getDate())).replace("HH", pad3(date.getHours())).replace("mm", pad3(date.getMinutes())).replace("ss", pad3(date.getSeconds()));
|
|
1301
1308
|
}
|
|
1309
|
+
var CN_DIGITS = ["\u96F6", "\u58F9", "\u8D30", "\u53C1", "\u8086", "\u4F0D", "\u9646", "\u67D2", "\u634C", "\u7396"];
|
|
1310
|
+
var CN_UNITS = ["", "\u62FE", "\u4F70", "\u4EDF"];
|
|
1311
|
+
var CN_GROUP_UNITS = ["", "\u4E07", "\u4EBF", "\u4E07\u4EBF", "\u4EBF\u4EBF"];
|
|
1312
|
+
function fourDigitToCapital(n) {
|
|
1313
|
+
let out = "";
|
|
1314
|
+
let zeroPending = false;
|
|
1315
|
+
for (let pos = 3; pos >= 0; pos--) {
|
|
1316
|
+
const d = Math.floor(n / 10 ** pos) % 10;
|
|
1317
|
+
if (d === 0) {
|
|
1318
|
+
if (out) zeroPending = true;
|
|
1319
|
+
continue;
|
|
1320
|
+
}
|
|
1321
|
+
if (zeroPending) {
|
|
1322
|
+
out += "\u96F6";
|
|
1323
|
+
zeroPending = false;
|
|
1324
|
+
}
|
|
1325
|
+
out += CN_DIGITS[d] + CN_UNITS[pos];
|
|
1326
|
+
}
|
|
1327
|
+
return out;
|
|
1328
|
+
}
|
|
1302
1329
|
function toUpperCaseAmount(value) {
|
|
1303
1330
|
const num = Number(value);
|
|
1304
1331
|
if (isNaN(num)) return String(value);
|
|
1305
1332
|
if (num === 0) return "\u96F6\u5143\u6574";
|
|
1306
|
-
const digits = ["\u96F6", "\u58F9", "\u8D30", "\u53C1", "\u8086", "\u4F0D", "\u9646", "\u67D2", "\u634C", "\u7396"];
|
|
1307
|
-
const units = ["", "\u62FE", "\u4F70", "\u4EDF"];
|
|
1308
|
-
const bigUnits = ["", "\u4E07", "\u4EBF"];
|
|
1309
1333
|
const sign = num < 0 ? "\u8D1F" : "";
|
|
1310
|
-
const
|
|
1311
|
-
const
|
|
1312
|
-
const intNum = parseInt(intStr, 10);
|
|
1334
|
+
const [intStr, decStr] = Math.abs(num).toFixed(2).split(".");
|
|
1335
|
+
const groupCount = Math.ceil(intStr.length / 4);
|
|
1313
1336
|
let result = "";
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
const unit = units[groupIdx % 4];
|
|
1322
|
-
const bigUnit = bigUnits[Math.floor(groupIdx / 4)];
|
|
1323
|
-
if (d === 0) {
|
|
1324
|
-
if (lastDigit !== 0) needZero = true;
|
|
1325
|
-
} else {
|
|
1326
|
-
if (needZero) {
|
|
1327
|
-
result = "\u96F6" + result;
|
|
1328
|
-
needZero = false;
|
|
1329
|
-
}
|
|
1330
|
-
result = digits[d] + unit + result;
|
|
1331
|
-
lastDigit = d;
|
|
1332
|
-
}
|
|
1333
|
-
if (groupIdx % 4 === 3 && groupIdx > 0) {
|
|
1334
|
-
result = bigUnit + result;
|
|
1335
|
-
}
|
|
1336
|
-
groupIdx++;
|
|
1337
|
+
let zeroPending = false;
|
|
1338
|
+
for (let groupIdx = groupCount - 1; groupIdx >= 0; groupIdx--) {
|
|
1339
|
+
const end = intStr.length - groupIdx * 4;
|
|
1340
|
+
const group = parseInt(intStr.slice(Math.max(0, end - 4), end), 10);
|
|
1341
|
+
if (group === 0) {
|
|
1342
|
+
if (result) zeroPending = true;
|
|
1343
|
+
continue;
|
|
1337
1344
|
}
|
|
1338
|
-
result += "\
|
|
1345
|
+
if (result && (zeroPending || group < 1e3)) result += "\u96F6";
|
|
1346
|
+
zeroPending = false;
|
|
1347
|
+
result += fourDigitToCapital(group) + (CN_GROUP_UNITS[groupIdx] ?? "");
|
|
1339
1348
|
}
|
|
1349
|
+
result = `${result || "\u96F6"}\u5143`;
|
|
1340
1350
|
const jiao = parseInt(decStr[0], 10);
|
|
1341
1351
|
const fen = parseInt(decStr[1], 10);
|
|
1342
1352
|
if (jiao === 0 && fen === 0) {
|
|
1343
1353
|
result += "\u6574";
|
|
1344
1354
|
} else {
|
|
1345
|
-
if (jiao
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
if (fen > 0) {
|
|
1349
|
-
result += digits[fen] + "\u5206";
|
|
1350
|
-
}
|
|
1355
|
+
if (jiao === 0) result += "\u96F6";
|
|
1356
|
+
else result += CN_DIGITS[jiao] + "\u89D2";
|
|
1357
|
+
if (fen > 0) result += CN_DIGITS[fen] + "\u5206";
|
|
1351
1358
|
}
|
|
1352
1359
|
return sign + result;
|
|
1353
1360
|
}
|
|
@@ -1621,9 +1628,12 @@ function makeRenderRow(row, resolve, keepRaw = false) {
|
|
|
1621
1628
|
cellType: cell.cellType,
|
|
1622
1629
|
barcodeType: cell.barcodeType,
|
|
1623
1630
|
qrCodeLevel: cell.qrCodeLevel,
|
|
1631
|
+
qrQuietZone: cell.qrQuietZone,
|
|
1624
1632
|
showBarcodeText: cell.showBarcodeText,
|
|
1625
1633
|
printerDpi: cell.printerDpi,
|
|
1626
1634
|
fit: cell.fit,
|
|
1635
|
+
objectPosition: cell.objectPosition,
|
|
1636
|
+
fitScale: cell.fitScale,
|
|
1627
1637
|
maxWidth: cell.maxWidth,
|
|
1628
1638
|
maxHeight: cell.maxHeight,
|
|
1629
1639
|
rowspan: cell.rowspan ?? 1,
|
|
@@ -2116,6 +2126,35 @@ function resolveElementBorder(type, opts) {
|
|
|
2116
2126
|
return { all, edges };
|
|
2117
2127
|
}
|
|
2118
2128
|
|
|
2129
|
+
// src/render/crop-style.ts
|
|
2130
|
+
var OBJECT_POSITION_UNSAFE = /[;"'<>\\(){}\[\]@!#]/;
|
|
2131
|
+
var OBJECT_POSITION_MAX_LEN = 64;
|
|
2132
|
+
var CROP_SCALE_MIN = 100;
|
|
2133
|
+
var CROP_SCALE_MAX = 400;
|
|
2134
|
+
function sanitizeObjectPosition(value) {
|
|
2135
|
+
const v = (value ?? "").trim();
|
|
2136
|
+
if (!v || v.length > OBJECT_POSITION_MAX_LEN || OBJECT_POSITION_UNSAFE.test(v)) return "";
|
|
2137
|
+
return v;
|
|
2138
|
+
}
|
|
2139
|
+
function cropScalePct(fit, scale) {
|
|
2140
|
+
if ((fit || "contain") !== "cover") return void 0;
|
|
2141
|
+
if (typeof scale !== "number" || !Number.isFinite(scale)) return void 0;
|
|
2142
|
+
const pct = Math.round(scale);
|
|
2143
|
+
if (pct <= CROP_SCALE_MIN) return void 0;
|
|
2144
|
+
return Math.min(pct, CROP_SCALE_MAX);
|
|
2145
|
+
}
|
|
2146
|
+
function cropStyleDeclarations(fit, scale, objectPosition) {
|
|
2147
|
+
const pos = sanitizeObjectPosition(objectPosition);
|
|
2148
|
+
const out = {};
|
|
2149
|
+
if (pos) out.objectPosition = pos;
|
|
2150
|
+
const pct = cropScalePct(fit, scale);
|
|
2151
|
+
if (pct !== void 0) {
|
|
2152
|
+
out.transform = `scale(${Number((pct / 100).toFixed(2))})`;
|
|
2153
|
+
out.transformOrigin = pos || "50% 50%";
|
|
2154
|
+
}
|
|
2155
|
+
return out;
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2119
2158
|
// src/render/watermark.ts
|
|
2120
2159
|
var PX_PER_MM = 96 / 25.4;
|
|
2121
2160
|
var MM_PER_PX = 25.4 / 96;
|
|
@@ -2312,6 +2351,17 @@ function followGroupHeight(el, members, template, _measuredElements) {
|
|
|
2312
2351
|
function effectiveHeight(el, measured) {
|
|
2313
2352
|
return Math.max(el.options?.height ?? 0, measured.get(el.id)?.measuredHeight ?? 0);
|
|
2314
2353
|
}
|
|
2354
|
+
function xRange(el) {
|
|
2355
|
+
const o = el.options ?? {};
|
|
2356
|
+
const x0 = o.left ?? 0;
|
|
2357
|
+
return [x0, x0 + (o.width ?? 100)];
|
|
2358
|
+
}
|
|
2359
|
+
function xIntersects(a, b) {
|
|
2360
|
+
return a[0] < b[1] && b[0] < a[1];
|
|
2361
|
+
}
|
|
2362
|
+
function xUnion(a, b) {
|
|
2363
|
+
return [Math.min(a[0], b[0]), Math.max(a[1], b[1])];
|
|
2364
|
+
}
|
|
2315
2365
|
function buildPaginationUnits(sorted, measured, groupMap) {
|
|
2316
2366
|
const unitOf = /* @__PURE__ */ new Map();
|
|
2317
2367
|
for (const members of groupMap.values()) {
|
|
@@ -2319,7 +2369,8 @@ function buildPaginationUnits(sorted, measured, groupMap) {
|
|
|
2319
2369
|
const unit = {
|
|
2320
2370
|
anchorId: members[0].id,
|
|
2321
2371
|
ids: members.map((m) => m.id),
|
|
2322
|
-
forceFirstPage: members.some((m) => paginationOf(m)?.pageable === false)
|
|
2372
|
+
forceFirstPage: members.some((m) => paginationOf(m)?.pageable === false),
|
|
2373
|
+
band: members.map(xRange).reduce(xUnion)
|
|
2323
2374
|
};
|
|
2324
2375
|
for (const m of members) unitOf.set(m.id, unit);
|
|
2325
2376
|
}
|
|
@@ -2351,11 +2402,13 @@ function buildPaginationUnits(sorted, measured, groupMap) {
|
|
|
2351
2402
|
if (active[i].bottom <= top) active.splice(i, 1);
|
|
2352
2403
|
}
|
|
2353
2404
|
const bottom = top + effectiveHeight(el, measured);
|
|
2405
|
+
const x = xRange(el);
|
|
2354
2406
|
for (const a of active) {
|
|
2355
|
-
if (a.bottom > top) union(el.id, a.id);
|
|
2407
|
+
if (a.bottom > top && xIntersects(a.x, x)) union(el.id, a.id);
|
|
2356
2408
|
}
|
|
2357
|
-
active.push({ id: el.id, top, bottom });
|
|
2409
|
+
active.push({ id: el.id, top, bottom, x });
|
|
2358
2410
|
}
|
|
2411
|
+
const eligibleById = new Map(eligible.map((e) => [e.id, e]));
|
|
2359
2412
|
const clusters = /* @__PURE__ */ new Map();
|
|
2360
2413
|
for (const el of eligible) {
|
|
2361
2414
|
const root = find(el.id);
|
|
@@ -2365,7 +2418,12 @@ function buildPaginationUnits(sorted, measured, groupMap) {
|
|
|
2365
2418
|
}
|
|
2366
2419
|
for (const ids of clusters.values()) {
|
|
2367
2420
|
if (ids.length < 2) continue;
|
|
2368
|
-
const unit = {
|
|
2421
|
+
const unit = {
|
|
2422
|
+
anchorId: ids[0],
|
|
2423
|
+
ids,
|
|
2424
|
+
forceFirstPage: false,
|
|
2425
|
+
band: ids.map((id) => xRange(eligibleById.get(id))).reduce(xUnion)
|
|
2426
|
+
};
|
|
2369
2427
|
for (const id of ids) unitOf.set(id, unit);
|
|
2370
2428
|
}
|
|
2371
2429
|
return unitOf;
|
|
@@ -2414,17 +2472,30 @@ function paginate(template, measuredElements) {
|
|
|
2414
2472
|
const unitOf = buildPaginationUnits(sorted, measuredElements, groupMap);
|
|
2415
2473
|
const pages = [];
|
|
2416
2474
|
let currentPage = [];
|
|
2417
|
-
let
|
|
2475
|
+
let occupied = [];
|
|
2418
2476
|
let pageBroken = false;
|
|
2419
|
-
function sectionTop(el) {
|
|
2420
|
-
return pageBroken ? pageCursorTop() : el.options?.top ?? 0;
|
|
2421
|
-
}
|
|
2422
|
-
function pageCursorTop() {
|
|
2423
|
-
return Math.max(0, fullPageHeight() - remaining);
|
|
2424
|
-
}
|
|
2425
2477
|
function fullPageHeight() {
|
|
2426
2478
|
return contentHeight - SAFETY_MARGIN;
|
|
2427
2479
|
}
|
|
2480
|
+
function depthIn(x) {
|
|
2481
|
+
let used = 0;
|
|
2482
|
+
for (const r of occupied) {
|
|
2483
|
+
if (xIntersects(x, [r.x0, r.x1])) used += r.height;
|
|
2484
|
+
}
|
|
2485
|
+
return Math.max(0, used);
|
|
2486
|
+
}
|
|
2487
|
+
function remainingIn(x) {
|
|
2488
|
+
return fullPageHeight() - depthIn(x);
|
|
2489
|
+
}
|
|
2490
|
+
function occupy(x, height) {
|
|
2491
|
+
occupied.push({ x0: x[0], x1: x[1], height });
|
|
2492
|
+
}
|
|
2493
|
+
function sectionTop(el, x = xRange(el)) {
|
|
2494
|
+
return pageBroken ? pageCursorTop(x) : el.options?.top ?? 0;
|
|
2495
|
+
}
|
|
2496
|
+
function pageCursorTop(x) {
|
|
2497
|
+
return Math.max(0, fullPageHeight() - remainingIn(x));
|
|
2498
|
+
}
|
|
2428
2499
|
let overflowOnCurrent = false;
|
|
2429
2500
|
function pushPage() {
|
|
2430
2501
|
pages.push(
|
|
@@ -2441,7 +2512,7 @@ function paginate(template, measuredElements) {
|
|
|
2441
2512
|
}
|
|
2442
2513
|
pushPage();
|
|
2443
2514
|
currentPage = [];
|
|
2444
|
-
|
|
2515
|
+
occupied = [];
|
|
2445
2516
|
pageBroken = true;
|
|
2446
2517
|
overflowOnCurrent = false;
|
|
2447
2518
|
}
|
|
@@ -2485,31 +2556,32 @@ function paginate(template, measuredElements) {
|
|
|
2485
2556
|
return pages;
|
|
2486
2557
|
function paginateNonTable(el, measured, sortedList, idx) {
|
|
2487
2558
|
const elHeight = measured.get(el.id)?.measuredHeight ?? el.options?.height ?? 0;
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2559
|
+
const x = xRange(el);
|
|
2560
|
+
const place = () => {
|
|
2561
|
+
const top = sectionTop(el, x);
|
|
2562
|
+
noteOverflow(top + elHeight);
|
|
2563
|
+
currentPage.push({ elementId: el.id, type: "element", renderTop: top });
|
|
2564
|
+
occupy(x, elHeight);
|
|
2565
|
+
};
|
|
2566
|
+
if (elHeight <= remainingIn(x)) {
|
|
2567
|
+
place();
|
|
2493
2568
|
if (paginationOf(el)?.keepWithNext && idx + 1 < sortedList.length) {
|
|
2494
2569
|
const nextEl = sortedList[idx + 1];
|
|
2495
2570
|
const nextHeight = measured.get(nextEl.id)?.measuredHeight ?? nextEl.options?.height ?? 0;
|
|
2496
2571
|
if (elHeight + nextHeight > fullPageHeight()) {
|
|
2497
2572
|
return idx + 1;
|
|
2498
2573
|
}
|
|
2499
|
-
if (nextHeight >
|
|
2574
|
+
if (nextHeight > remainingIn(x)) {
|
|
2500
2575
|
currentPage.pop();
|
|
2576
|
+
occupied.pop();
|
|
2501
2577
|
finishPage();
|
|
2502
|
-
|
|
2503
|
-
remaining -= elHeight;
|
|
2578
|
+
place();
|
|
2504
2579
|
}
|
|
2505
2580
|
}
|
|
2506
2581
|
return idx + 1;
|
|
2507
2582
|
}
|
|
2508
2583
|
finishPage();
|
|
2509
|
-
|
|
2510
|
-
if (top + elHeight > contentHeight) overflowOnCurrent = true;
|
|
2511
|
-
currentPage.push({ elementId: el.id, type: "element", renderTop: sectionTop(el) });
|
|
2512
|
-
remaining -= elHeight;
|
|
2584
|
+
place();
|
|
2513
2585
|
return idx + 1;
|
|
2514
2586
|
}
|
|
2515
2587
|
function paginateUnit(unit, idx) {
|
|
@@ -2522,8 +2594,9 @@ function paginate(template, measuredElements) {
|
|
|
2522
2594
|
maxBottom = Math.max(maxBottom, top2 + effectiveHeight(m, measuredElements));
|
|
2523
2595
|
}
|
|
2524
2596
|
const unitHeight = Math.max(maxBottom - minTop, 0);
|
|
2597
|
+
const band = unit.band;
|
|
2525
2598
|
const place = () => {
|
|
2526
|
-
const offset = pageBroken ? pageCursorTop() - minTop : 0;
|
|
2599
|
+
const offset = pageBroken ? pageCursorTop(band) - minTop : 0;
|
|
2527
2600
|
noteOverflow(minTop + offset + unitHeight);
|
|
2528
2601
|
for (const m of members) {
|
|
2529
2602
|
currentPage.push({
|
|
@@ -2532,9 +2605,9 @@ function paginate(template, measuredElements) {
|
|
|
2532
2605
|
renderTop: (m.options?.top ?? 0) + offset
|
|
2533
2606
|
});
|
|
2534
2607
|
}
|
|
2535
|
-
|
|
2608
|
+
occupy(band, unitHeight);
|
|
2536
2609
|
};
|
|
2537
|
-
if (unitHeight <=
|
|
2610
|
+
if (unitHeight <= remainingIn(band)) {
|
|
2538
2611
|
place();
|
|
2539
2612
|
return idx + 1;
|
|
2540
2613
|
}
|
|
@@ -2558,7 +2631,8 @@ function paginate(template, measuredElements) {
|
|
|
2558
2631
|
const rowCount = Math.min(bodyRows.length, bodyHeights.length);
|
|
2559
2632
|
const repeatCount = opts._repeatHeaderCount ?? 0;
|
|
2560
2633
|
const repeatH = measured.get(el.id)?.repeatHeaderHeight ?? rowHeights.slice(0, repeatCount).reduce((s, h) => s + h, 0);
|
|
2561
|
-
const freshAvail =
|
|
2634
|
+
const freshAvail = fullPageHeight();
|
|
2635
|
+
const tb = xRange(el);
|
|
2562
2636
|
if (repeatH > freshAvail) {
|
|
2563
2637
|
throw new Error(
|
|
2564
2638
|
`\u8868\u683C ${el.id} \u7684\u91CD\u590D\u8868\u5934\u9AD8\u5EA6 (${repeatH.toFixed(1)}mm) \u8D85\u8FC7\u9875\u9762\u53EF\u7528\u9AD8\u5EA6 (${freshAvail.toFixed(1)}mm)\uFF0C\u8BF7\u51CF\u5C11\u91CD\u590D\u8868\u5934\u884C`
|
|
@@ -2571,16 +2645,16 @@ function paginate(template, measuredElements) {
|
|
|
2571
2645
|
startRow: 0,
|
|
2572
2646
|
endRow: 0,
|
|
2573
2647
|
summary: summaryH > 0,
|
|
2574
|
-
renderTop: sectionTop(el)
|
|
2648
|
+
renderTop: sectionTop(el, tb)
|
|
2575
2649
|
});
|
|
2576
|
-
|
|
2577
|
-
applyFollowGroup(el, measured);
|
|
2650
|
+
occupy(tb, summaryH);
|
|
2651
|
+
applyFollowGroup(el, measured, tb);
|
|
2578
2652
|
return idx + 1;
|
|
2579
2653
|
}
|
|
2580
2654
|
const totalH = bodyHeights.slice(0, rowCount).reduce((s, h) => s + h, 0);
|
|
2581
2655
|
const totalNeed = totalH + subtotalH + summaryH;
|
|
2582
2656
|
if (tablePaginationOf(el)?.enabled === false) {
|
|
2583
|
-
if (totalNeed >
|
|
2657
|
+
if (totalNeed > remainingIn(tb) && currentPage.length > 0) finishPage();
|
|
2584
2658
|
currentPage.push({
|
|
2585
2659
|
elementId: el.id,
|
|
2586
2660
|
type: "table-slice",
|
|
@@ -2588,78 +2662,78 @@ function paginate(template, measuredElements) {
|
|
|
2588
2662
|
endRow: rowCount,
|
|
2589
2663
|
subtotal: subtotalH > 0,
|
|
2590
2664
|
summary: summaryH > 0,
|
|
2591
|
-
renderTop: sectionTop(el)
|
|
2665
|
+
renderTop: sectionTop(el, tb)
|
|
2592
2666
|
});
|
|
2593
|
-
|
|
2594
|
-
applyFollowGroup(el, measured);
|
|
2667
|
+
occupy(tb, totalNeed);
|
|
2668
|
+
applyFollowGroup(el, measured, tb);
|
|
2595
2669
|
return idx + 1;
|
|
2596
2670
|
}
|
|
2597
2671
|
const groups = buildRowGroups(bodyRows, rowCount);
|
|
2598
2672
|
let sliceStart = 0;
|
|
2599
2673
|
let firstSlice = true;
|
|
2600
|
-
let sliceTop = sectionTop(el);
|
|
2674
|
+
let sliceTop = sectionTop(el, tb);
|
|
2675
|
+
let sliceUsed = 0;
|
|
2676
|
+
const avail = () => remainingIn(tb) - sliceUsed;
|
|
2677
|
+
const pushSlice = (endRow, repeatHeader) => {
|
|
2678
|
+
currentPage.push({
|
|
2679
|
+
elementId: el.id,
|
|
2680
|
+
type: "table-slice",
|
|
2681
|
+
startRow: sliceStart,
|
|
2682
|
+
endRow,
|
|
2683
|
+
subtotal: subtotalH > 0,
|
|
2684
|
+
...!firstSlice && repeatHeader ? { repeatHeader: true } : {},
|
|
2685
|
+
renderTop: sliceTop
|
|
2686
|
+
});
|
|
2687
|
+
occupy(tb, sliceUsed);
|
|
2688
|
+
sliceUsed = 0;
|
|
2689
|
+
};
|
|
2601
2690
|
for (const g of groups) {
|
|
2602
2691
|
const gh = bodyHeights.slice(g.start, g.end).reduce((s, h) => s + h, 0);
|
|
2603
|
-
if (gh + subtotalH <=
|
|
2604
|
-
|
|
2692
|
+
if (gh + subtotalH <= avail()) {
|
|
2693
|
+
sliceUsed += gh;
|
|
2605
2694
|
continue;
|
|
2606
2695
|
}
|
|
2607
2696
|
if (g.start > sliceStart) {
|
|
2608
|
-
|
|
2609
|
-
elementId: el.id,
|
|
2610
|
-
type: "table-slice",
|
|
2611
|
-
startRow: sliceStart,
|
|
2612
|
-
endRow: g.start,
|
|
2613
|
-
subtotal: subtotalH > 0,
|
|
2614
|
-
...!firstSlice && repeatCount > 0 ? { repeatHeader: true } : {},
|
|
2615
|
-
renderTop: sliceTop
|
|
2616
|
-
});
|
|
2697
|
+
pushSlice(g.start, repeatCount > 0);
|
|
2617
2698
|
firstSlice = false;
|
|
2618
2699
|
sliceStart = g.start;
|
|
2619
2700
|
}
|
|
2620
2701
|
finishPage();
|
|
2621
|
-
sliceTop = sectionTop(el);
|
|
2622
|
-
|
|
2623
|
-
|
|
2702
|
+
sliceTop = sectionTop(el, tb);
|
|
2703
|
+
sliceUsed = 0;
|
|
2704
|
+
if (!firstSlice) sliceUsed += repeatH;
|
|
2705
|
+
sliceUsed += gh;
|
|
2624
2706
|
}
|
|
2625
2707
|
if (sliceStart < rowCount) {
|
|
2626
|
-
|
|
2627
|
-
elementId: el.id,
|
|
2628
|
-
type: "table-slice",
|
|
2629
|
-
startRow: sliceStart,
|
|
2630
|
-
endRow: rowCount,
|
|
2631
|
-
subtotal: subtotalH > 0,
|
|
2632
|
-
...!firstSlice && repeatCount > 0 ? { repeatHeader: true } : {},
|
|
2633
|
-
renderTop: sliceTop
|
|
2634
|
-
});
|
|
2708
|
+
pushSlice(rowCount, repeatCount > 0);
|
|
2635
2709
|
}
|
|
2636
2710
|
if (summaryH > 0) {
|
|
2637
|
-
if (summaryH <=
|
|
2711
|
+
if (summaryH <= avail()) {
|
|
2638
2712
|
const lastIdx = currentPage.length - 1;
|
|
2639
2713
|
const last = currentPage[lastIdx];
|
|
2640
2714
|
if (last && last.type === "table-slice" && last.elementId === el.id) {
|
|
2641
2715
|
currentPage[lastIdx] = { ...last, summary: true };
|
|
2642
|
-
|
|
2716
|
+
occupy(tb, summaryH);
|
|
2643
2717
|
} else {
|
|
2644
2718
|
finishPage();
|
|
2645
2719
|
currentPage.push({ elementId: el.id, type: "table-slice", startRow: rowCount, endRow: rowCount, summary: true, renderTop: 0 });
|
|
2646
|
-
|
|
2720
|
+
occupy(tb, summaryH);
|
|
2647
2721
|
}
|
|
2648
2722
|
} else {
|
|
2649
2723
|
finishPage();
|
|
2650
2724
|
currentPage.push({ elementId: el.id, type: "table-slice", startRow: rowCount, endRow: rowCount, summary: true, renderTop: 0 });
|
|
2651
|
-
|
|
2725
|
+
occupy(tb, summaryH);
|
|
2652
2726
|
}
|
|
2653
2727
|
}
|
|
2654
|
-
applyFollowGroup(el, measured);
|
|
2728
|
+
applyFollowGroup(el, measured, tb);
|
|
2655
2729
|
return idx + 1;
|
|
2656
2730
|
}
|
|
2657
|
-
function applyFollowGroup(el, measured) {
|
|
2731
|
+
function applyFollowGroup(el, measured, band) {
|
|
2658
2732
|
const members = followMap.get(el.id) ?? [];
|
|
2659
2733
|
if (members.length === 0) return;
|
|
2660
2734
|
const followH = followGroupHeight(el, members, template, measured);
|
|
2661
2735
|
const opts = el.options ?? {};
|
|
2662
|
-
if (followH <=
|
|
2736
|
+
if (followH <= remainingIn(band)) {
|
|
2663
2737
|
const lastIdx = currentPage.length - 1;
|
|
2664
2738
|
const last = currentPage[lastIdx];
|
|
2665
2739
|
if (last && last.type === "table-slice" && last.elementId === el.id) {
|
|
@@ -2670,7 +2744,7 @@ function paginate(template, measuredElements) {
|
|
|
2670
2744
|
// 沿用该切片在本页的定位 top(续片已 stamp 为 0)
|
|
2671
2745
|
groupTop: last.renderTop ?? opts.top ?? 0
|
|
2672
2746
|
};
|
|
2673
|
-
|
|
2747
|
+
occupy(band, followH);
|
|
2674
2748
|
return;
|
|
2675
2749
|
}
|
|
2676
2750
|
}
|
|
@@ -2683,7 +2757,7 @@ function paginate(template, measuredElements) {
|
|
|
2683
2757
|
followElementIds: members,
|
|
2684
2758
|
groupTop: 0
|
|
2685
2759
|
});
|
|
2686
|
-
|
|
2760
|
+
occupy(band, followH);
|
|
2687
2761
|
}
|
|
2688
2762
|
}
|
|
2689
2763
|
function buildRowGroups(renderRows, rowCount) {
|
|
@@ -2890,12 +2964,23 @@ function textStyle(opts) {
|
|
|
2890
2964
|
if (opts.lineHeight) parts.push(`line-height:${opts.lineHeight}pt`);
|
|
2891
2965
|
if (opts.letterSpacing) parts.push(`letter-spacing:${opts.letterSpacing}pt`);
|
|
2892
2966
|
if (opts.verticalAlign) {
|
|
2893
|
-
|
|
2894
|
-
|
|
2967
|
+
if (opts.textAlign === "justify") {
|
|
2968
|
+
parts.push(`display:flex;flex-direction:column;justify-content:${V_ALIGN_FLEX[opts.verticalAlign] ?? "flex-start"}`);
|
|
2969
|
+
} else {
|
|
2970
|
+
parts.push(`display:flex;align-items:${V_ALIGN_FLEX[opts.verticalAlign] ?? "flex-start"}`);
|
|
2971
|
+
parts.push(`justify-content:${H_ALIGN_FLEX[opts.textAlign ?? "left"] ?? "flex-start"}`);
|
|
2972
|
+
}
|
|
2895
2973
|
}
|
|
2896
2974
|
if (opts.textAlign) parts.push(`text-align:${opts.textAlign}`);
|
|
2975
|
+
if (opts.textAlign === "justify") parts.push("text-align-last:justify");
|
|
2897
2976
|
return parts.length ? parts.join(";") + ";" : "";
|
|
2898
2977
|
}
|
|
2978
|
+
function indentStyle(opts) {
|
|
2979
|
+
return opts.longTextIndent ? `text-indent:${opts.longTextIndent}em;` : "";
|
|
2980
|
+
}
|
|
2981
|
+
function cropStyle(fit, fitScale, objectPosition) {
|
|
2982
|
+
return Object.entries(cropStyleDeclarations(fit, fitScale, objectPosition)).map(([key, value]) => `${key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)}:${escapeInlineStyleValue(value)};`).join("");
|
|
2983
|
+
}
|
|
2899
2984
|
function elementFitStyle(fit, opts) {
|
|
2900
2985
|
if (fit === "autoHeight") return "overflow:visible;";
|
|
2901
2986
|
if (opts.wordWrap === false) return "white-space:nowrap;text-overflow:ellipsis;";
|
|
@@ -2934,7 +3019,7 @@ function renderElement(el, isMeasure, containerStyle, overrideTop, ctx) {
|
|
|
2934
3019
|
return renderTableElement(el, isMeasure, measureAttr, ctx);
|
|
2935
3020
|
case "image":
|
|
2936
3021
|
return `<div class="print-element" style="${style}"${measureAttr}>
|
|
2937
|
-
<img src="${esc(opts.src ?? "")}" style="width:100%;height:100%;object-fit
|
|
3022
|
+
<img src="${esc(opts.src ?? "")}" style="width:100%;height:100%;object-fit:${opts.fit || "contain"};${cropStyle(opts.fit, opts.fitScale, opts.objectPosition)}" />
|
|
2938
3023
|
</div>`;
|
|
2939
3024
|
case "barcode":
|
|
2940
3025
|
case "qrcode": {
|
|
@@ -2961,7 +3046,7 @@ function renderElement(el, isMeasure, containerStyle, overrideTop, ctx) {
|
|
|
2961
3046
|
case "oval":
|
|
2962
3047
|
return `<div class="print-element" style="${style};border:${opts.borderWidth || 1}pt ${opts.borderStyle || "solid"} ${opts.borderColor || "#333"};border-radius:50%;"${measureAttr}></div>`;
|
|
2963
3048
|
case "longText":
|
|
2964
|
-
return `<div class="print-element" style="${style}${textStyle(opts)}${elementFitStyle(fit, opts)}"${measureAttr}${fitAttr}>${esc(opts.formatter ?? opts.testData ?? "")}</div>`;
|
|
3049
|
+
return `<div class="print-element" style="${style}${textStyle(opts)}${indentStyle(opts)}${elementFitStyle(fit, opts)}"${measureAttr}${fitAttr}>${esc(opts.formatter ?? opts.testData ?? "")}</div>`;
|
|
2965
3050
|
case "html":
|
|
2966
3051
|
return `<div class="print-element" style="${style}"${measureAttr}>${opts.testData ?? opts.title ?? ""}</div>`;
|
|
2967
3052
|
default:
|
|
@@ -2976,6 +3061,8 @@ function codeImgHtml(value, cellType, opts, io) {
|
|
|
2976
3061
|
const svg = codeRenderer.render(value, cellType, {
|
|
2977
3062
|
barcodeType: opts.barcodeType,
|
|
2978
3063
|
qrCodeLevel: opts.qrCodeLevel != null ? String(opts.qrCodeLevel) : void 0,
|
|
3064
|
+
// 0 是合法档(无白边),必须用 typeof 判定而非 or/?? 之类假值判断
|
|
3065
|
+
qrQuietZone: typeof opts.qrQuietZone === "number" ? opts.qrQuietZone : void 0,
|
|
2979
3066
|
showText: opts.hideTitle !== void 0 ? !opts.hideTitle : opts.showBarcodeText,
|
|
2980
3067
|
barWidth: typeof opts.barWidth === "number" ? opts.barWidth : void 0,
|
|
2981
3068
|
fontSize: typeof opts.fontSize === "number" ? opts.fontSize : void 0,
|
|
@@ -2986,10 +3073,8 @@ function codeImgHtml(value, cellType, opts, io) {
|
|
|
2986
3073
|
if (isBarcode && /^<svg[\s>]/i.test(svg)) return inlineCodeSvgHtml(svg);
|
|
2987
3074
|
const src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
2988
3075
|
const styleParts = [];
|
|
2989
|
-
styleParts.push("max-width:100%", "max-height:100%", "display:block", "margin:auto");
|
|
2990
|
-
|
|
2991
|
-
styleParts.push(`object-fit:${fit}`);
|
|
2992
|
-
}
|
|
3076
|
+
styleParts.push("width:100%", "height:100%", "max-width:100%", "max-height:100%", "display:block", "margin:auto");
|
|
3077
|
+
styleParts.push(`object-fit:${fit || "contain"}`);
|
|
2993
3078
|
if (maxWidth) {
|
|
2994
3079
|
styleParts.push(`max-width:${maxWidth}mm`);
|
|
2995
3080
|
}
|
|
@@ -3017,6 +3102,7 @@ function matrixCellStyle(cell, opts) {
|
|
|
3017
3102
|
if (color) parts.push(`color:${color}`);
|
|
3018
3103
|
if (cell.backgroundColor) parts.push(`background-color:${cell.backgroundColor}`);
|
|
3019
3104
|
parts.push(`text-align:${cell.align ?? "left"}`);
|
|
3105
|
+
if (cell.align === "justify") parts.push("text-align-last:justify");
|
|
3020
3106
|
parts.push(`vertical-align:${cell.valign ?? "middle"}`);
|
|
3021
3107
|
parts.push(`padding:${padding}mm`);
|
|
3022
3108
|
parts.push(cell.wordWrap === false ? "white-space:nowrap;overflow:hidden" : "word-break:break-all");
|
|
@@ -3056,7 +3142,10 @@ function renderMatrixRows(renderRows, start, end, opts, withRowIndex, ctx, fitOw
|
|
|
3056
3142
|
const fit = cell.fit || "contain";
|
|
3057
3143
|
const maxWidth = cell.maxWidth ? `max-width:${cell.maxWidth}mm;` : "max-width:100%;";
|
|
3058
3144
|
const maxHeight = cell.maxHeight ? `max-height:${cell.maxHeight}mm;` : "max-height:100%;";
|
|
3059
|
-
|
|
3145
|
+
const boxMm = cellImageBoxMm(fit, cellFitCapMm(renderRows, r, cell, defaultPadding));
|
|
3146
|
+
const boxHeight = boxMm === void 0 ? "height:100%" : `height:${boxMm}mm`;
|
|
3147
|
+
const imgBox = boxMm === void 0 ? "" : "width:100%;height:100%;";
|
|
3148
|
+
inner = `<div style="width:100%;${boxHeight};display:flex;align-items:center;justify-content:center;overflow:hidden;"><img src="${esc(resolveCellContent(cell, ctx))}" style="${imgBox}object-fit:${fit};${cropStyle(fit, cell.fitScale, cell.objectPosition)}${maxWidth}${maxHeight}display:block;" /></div>`;
|
|
3060
3149
|
} else {
|
|
3061
3150
|
inner = renderTextCellInner(renderRows, r, colIndex, cell, opts, fitOwner, defaultPadding, ctx);
|
|
3062
3151
|
}
|
|
@@ -3245,7 +3334,8 @@ function codeSpecKey(value, cellType, opts = {}) {
|
|
|
3245
3334
|
opts.qrCodeLevel ?? null,
|
|
3246
3335
|
opts.showText ?? null,
|
|
3247
3336
|
opts.barWidth ?? null,
|
|
3248
|
-
opts.fontSize ?? null
|
|
3337
|
+
opts.fontSize ?? null,
|
|
3338
|
+
opts.qrQuietZone ?? null
|
|
3249
3339
|
]);
|
|
3250
3340
|
}
|
|
3251
3341
|
function createMapCodeRenderer(map) {
|
package/dist/browser/index.d.cts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @worm-vue3-print/core v1.3.
|
|
2
|
+
* @worm-vue3-print/core v1.3.8
|
|
3
3
|
* Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
|
|
4
4
|
* SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
|
|
5
5
|
* SPDX-License-Identifier: MIT
|
|
6
6
|
*/
|
|
7
|
-
import { P as PageLayout, T as TemplateData, M as MultiPageTemplateData, C as CodeRenderer, D as DriverFactory, R as RawMeasurement, a as CodeSpec } from '../driver-
|
|
8
|
-
import { P as PrintRuntime, F as FitFontSize } from '../ports-
|
|
7
|
+
import { P as PageLayout, T as TemplateData, M as MultiPageTemplateData, C as CodeRenderer, D as DriverFactory, R as RawMeasurement, a as CodeSpec } from '../driver-hJxBl2_n.cjs';
|
|
8
|
+
import { P as PrintRuntime, F as FitFontSize } from '../ports-B-Jb2XwT.cjs';
|
|
9
9
|
|
|
10
10
|
interface BrowserRenderResult {
|
|
11
11
|
/** 最终多页 HTML 字符串 */
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @worm-vue3-print/core v1.3.
|
|
2
|
+
* @worm-vue3-print/core v1.3.8
|
|
3
3
|
* Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
|
|
4
4
|
* SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
|
|
5
5
|
* SPDX-License-Identifier: MIT
|
|
6
6
|
*/
|
|
7
|
-
import { P as PageLayout, T as TemplateData, M as MultiPageTemplateData, C as CodeRenderer, D as DriverFactory, R as RawMeasurement, a as CodeSpec } from '../driver-
|
|
8
|
-
import { P as PrintRuntime, F as FitFontSize } from '../ports-
|
|
7
|
+
import { P as PageLayout, T as TemplateData, M as MultiPageTemplateData, C as CodeRenderer, D as DriverFactory, R as RawMeasurement, a as CodeSpec } from '../driver-hJxBl2_n.js';
|
|
8
|
+
import { P as PrintRuntime, F as FitFontSize } from '../ports-CJ0SUYFt.js';
|
|
9
9
|
|
|
10
10
|
interface BrowserRenderResult {
|
|
11
11
|
/** 最终多页 HTML 字符串 */
|
package/dist/browser/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @worm-vue3-print/core v1.3.
|
|
2
|
+
* @worm-vue3-print/core v1.3.8
|
|
3
3
|
* Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
|
|
4
4
|
* SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
|
|
5
5
|
* SPDX-License-Identifier: MIT
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
prepareDocument,
|
|
18
18
|
resolveBarcodeSize,
|
|
19
19
|
resolveShrinkMinFontSize
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-TQJGFV2V.js";
|
|
21
21
|
|
|
22
22
|
// src/browser/browser-code-renderer.ts
|
|
23
23
|
import JsBarcode from "jsbarcode";
|
|
@@ -62,6 +62,10 @@ function renderBarcodeSvg(value, opts) {
|
|
|
62
62
|
svg.setAttribute("shape-rendering", "crispEdges");
|
|
63
63
|
return svg.outerHTML;
|
|
64
64
|
}
|
|
65
|
+
var QR_DEFAULT_QUIET_MODULES = 0;
|
|
66
|
+
function qrQuietModules(value) {
|
|
67
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : QR_DEFAULT_QUIET_MODULES;
|
|
68
|
+
}
|
|
65
69
|
function renderQrSvg(value, opts) {
|
|
66
70
|
const level = (opts.qrCodeLevel ?? "M").toUpperCase();
|
|
67
71
|
const qr = QRCode.create(value, {
|
|
@@ -70,7 +74,7 @@ function renderQrSvg(value, opts) {
|
|
|
70
74
|
const modules = qr.modules;
|
|
71
75
|
const size = modules.size;
|
|
72
76
|
const dot = 4;
|
|
73
|
-
const quiet =
|
|
77
|
+
const quiet = qrQuietModules(opts.qrQuietZone) * dot;
|
|
74
78
|
const dim = size * dot + quiet * 2;
|
|
75
79
|
let rects = "";
|
|
76
80
|
for (let y = 0; y < size; y++) {
|