From 90875d84c725ad29b079921096cdaebd2ffc31a4 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 12 Sep 2025 22:43:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(style-print):=20=E4=BC=98=E5=8C=96PDF?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=A0=B7=E5=BC=8F=E5=92=8C=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=8F=90=E9=AB=98=E5=85=BC=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加PDF专用样式类pdf-generating,确保打印样式一致性 - 调整A4纸张边距并优化html2canvas的参数缩放和定位 - 在生成PDF时动态添加和移除pdf-generating类 - 增加错误处理时清除样式类,避免影响页面展示 - 优化表格布局及文本换行,防止内容溢出 - 调整打印信息容器和二维码区域的样式适配PDF生成 - 增加样式盒模型统一设置,提高打印兼容性 --- .../app/orders/style/style-print.component.ts | 31 ++++++- .../webapp/app/orders/style/style-print.vue | 90 +++++++++++++++++++ 2 files changed, 117 insertions(+), 4 deletions(-) diff --git a/src/main/webapp/app/orders/style/style-print.component.ts b/src/main/webapp/app/orders/style/style-print.component.ts index 4550cbd..aa35caf 100644 --- a/src/main/webapp/app/orders/style/style-print.component.ts +++ b/src/main/webapp/app/orders/style/style-print.component.ts @@ -238,6 +238,9 @@ export default defineComponent({ return; } + // 临时添加PDF专用样式类 + element.classList.add('pdf-generating'); + // 等待图片加载完成 const images = element.querySelectorAll('img'); await Promise.all( @@ -249,16 +252,26 @@ export default defineComponent({ }), ); - // A4纸张配置 + // 等待一帧以确保样式应用 + await new Promise(resolve => requestAnimationFrame(resolve)); + + // A4纸张配置 - 优化PDF生成参数 const opt = { - margin: [15, 15, 15, 15], + margin: [10, 10, 10, 10], // 减少边距 filename: `${$t('jewpmsApp.style.detail.title')}-${style.value.number}.pdf`, - image: { type: 'jpeg', quality: 0.98 }, + image: { type: 'jpeg', quality: 0.95 }, html2canvas: { - scale: 2, + scale: 1.5, // 降低缩放比例避免偏移 useCORS: true, allowTaint: true, letterRendering: true, + scrollX: 0, // 确保从左上角开始 + scrollY: 0, + x: 0, // 明确设置起始位置 + y: 0, + width: element.scrollWidth, // 使用实际内容宽度 + height: element.scrollHeight, // 使用实际内容高度 + backgroundColor: '#ffffff', // 设置背景色 }, jsPDF: { unit: 'mm', @@ -269,6 +282,10 @@ export default defineComponent({ }; const blob = await html2pdf().set(opt).from(element).outputPdf('blob'); + + // 移除临时样式类 + element.classList.remove('pdf-generating'); + const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; @@ -285,6 +302,12 @@ export default defineComponent({ } catch (error) { console.error('PDF下载错误:', error); alertService.showError($t('entity.action.downloadError')); + + // 确保在错误情况下也移除样式类 + const element = document.getElementById('stylePrintContent'); + if (element) { + element.classList.remove('pdf-generating'); + } } }; diff --git a/src/main/webapp/app/orders/style/style-print.vue b/src/main/webapp/app/orders/style/style-print.vue index 01645cd..2487012 100644 --- a/src/main/webapp/app/orders/style/style-print.vue +++ b/src/main/webapp/app/orders/style/style-print.vue @@ -230,6 +230,59 @@ export default StylePrint; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); font-size: 12px; line-height: 1.4; + position: relative; + box-sizing: border-box; +} + +/* PDF生成时的专用样式 */ +.print-preview.pdf-generating { + width: 100% !important; + max-width: 210mm !important; + margin: 0 !important; + padding: 10mm !important; + box-shadow: none !important; + border-radius: 0 !important; + transform: none !important; + position: static !important; + left: 0 !important; + top: 0 !important; + box-sizing: border-box !important; +} + +/* 确保PDF生成时表格不会超出边界 */ +.pdf-generating .print-table { + table-layout: fixed !important; + width: 100% !important; + max-width: 100% !important; + word-wrap: break-word !important; +} + +.pdf-generating .print-table th, +.pdf-generating .print-table td { + word-wrap: break-word !important; + overflow-wrap: break-word !important; + max-width: none !important; +} + +/* PDF生成时信息容器优化 */ +.pdf-generating .print-info-container { + display: flex !important; + flex-wrap: nowrap !important; + width: 100% !important; + max-width: 100% !important; + box-sizing: border-box !important; +} + +.pdf-generating .print-info-left, +.pdf-generating .print-info-right { + box-sizing: border-box !important; + max-width: 100% !important; +} + +.pdf-generating .print-info-qrcode { + flex-shrink: 0 !important; + width: 120px !important; + max-width: 120px !important; } .print-header h3 { @@ -246,14 +299,21 @@ export default StylePrint; align-items: stretch; gap: 15px; margin-bottom: 20px; + width: 100%; + max-width: 100%; + box-sizing: border-box; } .print-info-left { flex: 2; + min-width: 0; /* 允许内容收缩 */ + box-sizing: border-box; } .print-info-right { flex: 1; + min-width: 0; /* 允许内容收缩 */ + box-sizing: border-box; } .print-info-qrcode { @@ -261,6 +321,9 @@ export default StylePrint; display: flex; flex-direction: column; align-items: center; + width: 120px; + max-width: 120px; + box-sizing: border-box; } .print-row { @@ -302,6 +365,8 @@ export default StylePrint; border-collapse: collapse; font-size: 11px; margin-bottom: 15px; + table-layout: fixed; /* 固定表格布局 */ + box-sizing: border-box; } .print-table th, @@ -310,6 +375,9 @@ export default StylePrint; padding: 6px 4px; text-align: left; vertical-align: top; + word-wrap: break-word; + overflow-wrap: break-word; + box-sizing: border-box; } .print-table th { @@ -377,12 +445,34 @@ export default StylePrint; box-shadow: none !important; border-radius: 0; page-break-after: auto !important; + box-sizing: border-box !important; + transform: none !important; + position: static !important; } body { margin: 0 !important; padding: 0 !important; } + + /* 打印时表格优化 */ + .print-table { + table-layout: fixed !important; + width: 100% !important; + page-break-inside: avoid; + } + + .print-table th, + .print-table td { + word-wrap: break-word !important; + overflow-wrap: break-word !important; + } + + .print-info-container { + width: 100% !important; + max-width: 100% !important; + box-sizing: border-box !important; + } } /* 响应式设计 */