feat(打印能力): 优化打印文案、选项与底栏布局
build.yaml / build (push) Successful in 43s

This commit is contained in:
xiaoqidun committed 2026-10-24 21:50:22 +08:00
1 parent 615f94bcac
commit a022c3e636
3 files changed
+29 -35

No files matched your search

+8 -8
View File
@@ -674,18 +674,18 @@
</dialog>
<dialog id="printPanel" class="form-dialog print-dialog">
<form id="printForm">
<h2 id="printTitle" class="form-title">打印</h2>
<h2 id="printTitle" class="form-title">打印设置</h2>
<div class="print-content">
<fieldset id="printSettings" class="print-settings">
<div class="form-row"><label for="printPrinter">打印设备</label><div class="print-field"><select id="printPrinter"><option value="browser">浏览器打印</option><option value="pdf">保存为PDF</option></select><button id="printProperties" class="small-button" type="button" hidden>设备属性</button></div></div>
<div class="form-row"><label for="printPrinter">打印设备</label><div class="print-field"><select id="printPrinter"><option value="browser">系统打印</option><option value="pdf">另存输出</option></select><button id="printProperties" class="small-button" type="button" hidden>设备属性</button></div></div>
<div class="form-row" data-print-row="device" hidden><label for="printCopies">打印份数</label><div class="print-field"><input id="printCopies" type="number" min="1" max="999" value="1"><label class="print-check"><input id="printCollation" type="checkbox" checked>逐份打印</label></div></div>
<div class="form-row"><label for="printScope">打印范围</label><select id="printScope"><option value="all">全部页面</option><option value="current">当前页面</option><option value="selected">所选页面</option><option value="range">指定页码</option></select></div>
<div class="form-row" data-print-row="range" hidden><label for="printRange">指定页码</label><input id="printRange" type="text" placeholder="1-3,5" autocomplete="off" spellcheck="false"></div>
<div class="form-row"><label for="printParity">奇偶筛选</label><div class="print-field"><select id="printParity"><option value="all">全部页面</option><option value="odd">奇数页面</option><option value="even">偶数页面</option></select><label class="print-check"><input id="printReverse" type="checkbox">逆序打印</label></div></div>
<div class="form-row"><label for="printMode">页面排版</label><select id="printMode"><option value="single">单页打印</option><option value="multiple">多页合印</option><option value="booklet">小册打印</option><option value="poster">海报拼接</option></select></div>
<div class="form-row"><label for="printPaper">纸张大小</label><select id="printPaper"><option value="210,297">A4</option><option value="297,420">A3</option><option value="148,210">A5</option><option value="176,250">B5</option><option value="215.9,279.4">Letter</option><option value="215.9,355.6">Legal</option><option value="source">原页面尺寸</option><option value="custom">自定义</option></select></div>
<div class="form-row"><label for="printPaper">纸张大小</label><select id="printPaper"><option value="210,297">A4</option><option value="297,420">A3</option><option value="148,210">A5</option><option value="176,250">B5</option><option value="215.9,279.4">Letter</option><option value="215.9,355.6">Legal</option><option value="source">原页尺寸</option><option value="custom">自定尺寸</option></select></div>
<div class="form-row" data-print-row="paper" hidden><label for="printWidth">纸张尺寸</label><div class="print-field"><input id="printWidth" type="number" value="210" min="1" max="5000" step="any" title="纸张宽度"><span>×</span><input id="printHeight" type="number" value="297" min="1" max="5000" step="any" title="纸张高度"><span>mm</span></div></div>
<div class="form-row"><label for="printOrientation">纸张方向</label><select id="printOrientation"><option value="portrait">纵向</option><option value="landscape">横向</option></select></div>
<div class="form-row"><label for="printOrientation">纸张方向</label><select id="printOrientation"><option value="portrait">纵向纸张</option><option value="landscape">横向纸张</option></select></div>
<div class="form-row"><label for="printScaling">页面缩放</label><select id="printScaling"><option value="shrink">缩小大页</option><option value="fit">适合纸张</option><option value="actual">实际大小</option><option value="custom">自定比例</option></select></div>
<div class="form-row" data-print-row="scale" hidden><label for="printScale">缩放比例</label><div class="print-field"><input id="printScale" type="number" min="1" max="10000" value="100" step="1"><span>%</span></div></div>
<div class="form-row"><span>额外边距</span><div class="print-field print-margins"><input id="printMarginTop" type="number" min="0" value="0" step="0.1" title="上边距"><input id="printMarginRight" type="number" min="0" value="0" step="0.1" title="右边距"><input id="printMarginBottom" type="number" min="0" value="0" step="0.1" title="下边距"><input id="printMarginLeft" type="number" min="0" value="0" step="0.1" title="左边距"><span>mm</span></div></div>
@@ -696,16 +696,16 @@
<div class="form-row" data-print-row="booklet" hidden><label for="printBookletSheets">每册纸数</label><input id="printBookletSheets" type="number" min="0" max="2500" placeholder="不分册" title="0表示不分册"></div>
<div class="form-row" data-print-row="booklet" hidden><label for="printSheetFrom">纸张范围</label><div class="print-field"><input id="printSheetFrom" type="number" min="1" placeholder="起始" title="起始纸张编号"><span>至</span><input id="printSheetTo" type="number" min="1" placeholder="结束" title="结束纸张编号"></div></div>
<div class="form-row" data-print-row="poster" hidden><label for="printOverlap">重叠宽度</label><div class="print-field"><input id="printOverlap" type="number" min="0" value="5" step="0.1"><span>mm</span></div></div>
<div class="form-row"><label for="printDuplex">双面方式</label><select id="printDuplex"><option value="simplex">单面打印</option><option value="longEdge">自动双面(长边)</option><option value="shortEdge">自动双面(短边)</option><option value="manualLongEdge">手动双面(长边)</option><option value="manualShortEdge">手动双面(短边)</option></select></div>
<div class="form-row"><label for="printDuplex">双面方式</label><select id="printDuplex"><option value="simplex">单面打印</option><option value="longEdge">自动长边</option><option value="shortEdge">自动短边</option><option value="manualLongEdge">手动长边</option><option value="manualShortEdge">手动短边</option></select></div>
<div class="form-row" data-print-row="sides" hidden><label for="printSides">打印纸面</label><select id="printSides"><option value="all">正反两面</option><option value="front">只印正面</option><option value="back">只印背面</option></select></div>
<div class="form-row" data-print-row="manual" hidden><span>背面处理</span><div class="print-field"><label class="print-check"><input id="printBackReverse" type="checkbox">倒序送纸</label><label class="print-check" title="背面旋转180°"><input id="printBackRotate" type="checkbox">背面旋转</label></div></div>
<div class="form-row"><label for="printContents">打印内容</label><select id="printContents"><option value="documentAndAnnotations">文档与注解</option><option value="document">文档与表单</option><option value="annotations">仅打印注解</option><option value="forms">仅打印表单</option></select></div>
<div class="form-row"><label for="printContents">打印内容</label><select id="printContents"><option value="documentAndAnnotations">文档注解</option><option value="document">文档表单</option><option value="annotations">仅限注解</option><option value="forms">仅限表单</option></select></div>
<div class="print-options"><label><input id="printRotate" type="checkbox" checked>自动旋转</label><label><input id="printGrayscale" type="checkbox">灰度打印</label><label><input id="printBorders" type="checkbox">页面边框</label><label><input id="printCropMarks" type="checkbox">裁切标记</label><label><input id="printRaster" type="checkbox">图像打印</label><select id="printDPI" title="图像精度"><option value="150">150 DPI</option><option value="300" selected>300 DPI</option><option value="600">600 DPI</option><option value="1200">1200 DPI</option></select></div>
<div class="print-options" data-print-row="poster" hidden><label title="仅拼接超出纸面的页面"><input id="printTileOnlyLarge" type="checkbox" checked>仅拼大页</label><label><input id="printLabels" type="checkbox" checked>拼接标签</label></div>
</fieldset>
<div class="print-preview"><div id="printPreview" class="print-preview-page"></div><div class="print-preview-tools"><button id="printPrevious" class="small-button" type="button">上一面</button><input id="printPreviewNumber" type="number" min="1" value="1" title="预览纸面"><span id="printPageCount">/ 0</span><button id="printNext" class="small-button" type="button">下一面</button><select id="printZoom" title="预览缩放"><option value="fit">适合</option><option value="0.5">50%</option><option value="1">100%</option><option value="2">200%</option></select></div></div>
<div id="printPreview" class="print-preview-page"></div>
</div>
<div class="form-actions"><div id="printStatus" class="form-status"></div><button id="printCancel" class="button" type="button">关闭</button><button id="printSubmit" class="button" type="submit" disabled>打印</button></div>
<div class="print-footer"><div id="printStatus" class="form-status"></div><div class="print-preview-tools"><button id="printPrevious" class="small-button" type="button">上页</button><input id="printPreviewNumber" type="number" min="1" value="1" title="预览纸面"><span id="printPageCount">/ 0</span><button id="printNext" class="small-button" type="button">下页</button><select id="printZoom" title="预览缩放"><option value="fit">适合</option><option value="0.5">50%</option><option value="1">100%</option><option value="2">200%</option></select></div><div class="form-actions"><button id="printCancel" class="button" type="button">关闭</button><button id="printSubmit" class="button" type="submit" disabled>打印</button></div></div>
</form>
</dialog>
<dialog id="exportPanel" class="form-dialog">
+17 -22
View File
@@ -33,12 +33,14 @@
.print-content {
display: grid;
grid-template-columns: 310px minmax(0, 1fr);
height: min(62dvh, 660px);
min-height: 240px;
gap: 14px;
}
.print-settings {
min-width: 0;
max-height: calc(100dvh - 230px);
max-height: 100%;
margin: 0;
padding: 0 8px 0 0;
overflow: auto;
@@ -64,28 +66,20 @@
.print-field > span { flex: none; color: var(--text-muted); white-space: nowrap; }
.print-dialog .print-settings .print-margins input { padding: 0 3px; text-align: center; }
.print-check { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.print-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: var(--control-height); align-items: center; gap: 8px; margin: 12px 0 0 calc(4em + 8px); }
.print-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)) minmax(90px, 1fr); grid-auto-rows: var(--control-height); align-items: center; gap: 8px; margin-top: 12px; }
.print-options label { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.print-check input, .print-options input { margin: 0; accent-color: var(--accent); }
.print-dialog .form-actions { grid-template-columns: minmax(0, 1fr) 80px 80px; margin-top: 12px; }
.print-dialog .form-actions > .form-status { overflow-wrap: anywhere; }
.print-dialog .form-actions > .form-status:empty { display: none; }
.print-dialog .form-actions > button:first-of-type { grid-column: 2; }
.print-preview {
display: flex;
min-width: 0;
min-height: 300px;
flex-direction: column;
gap: 8px;
}
.print-footer { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 14px; margin-top: 12px; }
.print-footer > .form-status { min-width: 0; margin: 0; overflow-wrap: anywhere; }
.print-dialog .form-actions { grid-template-columns: 80px 80px; margin: 0; }
.print-preview-page {
display: grid;
height: min(62dvh, 660px);
min-height: 240px;
justify-items: center;
align-items: start;
min-width: 0;
height: 100%;
min-height: 0;
justify-items: safe center;
align-items: safe center;
padding: 12px;
overflow: auto;
background: #e1e6e9;
@@ -99,13 +93,14 @@
#ofdgoPrintDocument { display: none; }
@media (max-width: 680px) {
.print-content { grid-template-columns: minmax(0, 1fr); }
.print-content { grid-template-columns: minmax(0, 1fr); height: auto; min-height: 0; }
.print-settings { max-height: 34dvh; }
.print-preview-page { height: 32dvh; min-height: 160px; }
.print-preview { min-height: 210px; }
.print-footer { grid-template-columns: minmax(0, 1fr); gap: 8px; }
.print-footer > .form-status:empty { display: none; }
.print-preview-tools { gap: 5px; }
.print-dialog .print-preview-tools input { width: 42px; }
.print-dialog .form-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.print-dialog .form-actions > .form-status { grid-column: 1 / -1; }
.print-dialog .form-actions > button:first-of-type { grid-column: 1; }
}
@media print {
+4 -5
View File
@@ -72,7 +72,6 @@ export class PrintDialog {
if (browser.disabled) this.el.Printer.value = "pdf";
try {
if (this.nativeHost) {
browser.textContent = "系统打印";
const capabilities = await this.nativeHost.call("print.capabilities", {});
if (!this.current(sequence)) return;
this.capabilities = capabilities;
@@ -233,7 +232,7 @@ export class PrintDialog {
if (!this.current(sequence)) return;
this.profile = profile;
const options = this.options(profile);
this.el.Status.textContent = "正在准备打印";
this.el.Status.textContent = "准备打印…";
const layout = await context.call(this.prepared ? "ofdgoLayoutPrint" : "ofdgoPreparePrint", options);
if (!this.current(sequence)) return;
this.prepared = true;
@@ -331,7 +330,7 @@ export class PrintDialog {
this.root.append(style);
for (let i = 0; i < this.layout.sides.length; i++) {
if (!this.current(sequence)) throw new DOMException("打印已取消", "AbortError");
this.el.Status.textContent = `正在准备纸面 ${i + 1}/${this.layout.sides.length}`;
this.el.Status.textContent = `准备纸面 ${i + 1}/${this.layout.sides.length}`;
const {svg} = await context.call("ofdgoPrintSide", i);
if (!this.current(sequence)) throw new DOMException("打印已取消", "AbortError");
const url = URL.createObjectURL(new Blob([svg], {type:"image/svg+xml"}));
@@ -350,7 +349,7 @@ export class PrintDialog {
document.title = context.name;
this.waiting = this.nativeHost ? "native" : "browser";
this.controls();
this.el.Status.textContent = job.deviceOptions ? "正在提交打印作业" : "正在打开打印窗口";
this.el.Status.textContent = job.deviceOptions ? "提交打印…" : "打开打印…";
if (job.deviceOptions) {
const result = await this.nativeHost.call("print", {...job.deviceOptions, fingerprint:job.fingerprint});
if (this.current(sequence)) {
@@ -398,7 +397,7 @@ export class PrintDialog {
const sequence = this.sequence, context = this.context;
this.running = true;
this.controls();
this.el.Status.textContent = "正在生成打印PDF";
this.el.Status.textContent = "生成文件…";
try {
const result = await context.call("ofdgoPrintPDF");
if (this.current(sequence)) {