From ab528e6c321d3d36b5e8bae9fd8e90cc4175fc02 Mon Sep 17 00:00:00 2001 From: 86156 <823267011@qq.com> Date: Fri, 9 Jan 2026 13:58:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=E5=89=8D=E7=AB=AF=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wms/coil/panels/LabelRender/index.vue | 137 ++++++++++++++---- 1 file changed, 110 insertions(+), 27 deletions(-) diff --git a/klp-ui/src/views/wms/coil/panels/LabelRender/index.vue b/klp-ui/src/views/wms/coil/panels/LabelRender/index.vue index 54de586b..64c760ae 100644 --- a/klp-ui/src/views/wms/coil/panels/LabelRender/index.vue +++ b/klp-ui/src/views/wms/coil/panels/LabelRender/index.vue @@ -76,7 +76,8 @@ export default { // -------- 重构后的打印方法(核心优化) -------- async printLabel() { // 1. 获取标签容器DOM - const labelContainer = document.querySelector('.label-container'); + const labelContainer = document.querySelector('.label-container') || + document.querySelector('.material-label-container'); if (!labelContainer) { Message.error('未找到标签容器,无法打印'); return; @@ -88,67 +89,149 @@ export default { // 2. 等待二维码/字体等资源加载完成(复用之前的等待逻辑) await this.waitForAllResources(labelContainer); - // 3. 用html2canvas生成高清Canvas(解决文字模糊+二维码丢失) + // 3. 计算纸张尺寸和缩放比例 + // 纸张尺寸:180mm x 100mm + // 1mm ≈ 3.779527559px (96 DPI) + const paperWidthMm = 180; + const paperHeightMm = 100; + const dpi = 96; + const mmToPx = dpi / 25.4; + const paperWidthPx = paperWidthMm * mmToPx; // 约 680.3px + const paperHeightPx = paperHeightMm * mmToPx; // 约 377.95px + + // 获取标签容器的实际尺寸 + const containerRect = labelContainer.getBoundingClientRect(); + const containerWidth = containerRect.width; + const containerHeight = containerRect.height; + + // 计算缩放比例,确保内容适配到纸张(留出2mm边距) + const marginMm = 2; + const marginPx = marginMm * mmToPx; + const availableWidth = paperWidthPx - marginPx * 2; + const availableHeight = paperHeightPx - marginPx * 2; + + const scaleX = containerWidth > 0 ? availableWidth / containerWidth : 1; + const scaleY = containerHeight > 0 ? availableHeight / containerHeight : 1; + const printScale = Math.min(scaleX, scaleY, 1); // 不超过1,不放大 + + // 计算最终Canvas尺寸(适配纸张) + const finalCanvasWidth = containerWidth * printScale; + const finalCanvasHeight = containerHeight * printScale; + + // 使用合适的scale值生成高清Canvas(但不超过纸张尺寸) + const canvasScale = Math.min(1.5, printScale * 1.5); // 确保不超过纸张 + + // 4. 用html2canvas生成高清Canvas(解决文字模糊+二维码丢失) const canvas = await html2canvas(labelContainer, { - scale: 1.5, // 3倍高清渲染(核心) + scale: canvasScale, backgroundColor: '#ffffff', // 强制白色背景,避免打印时背景透明 useCORS: true, // 支持跨域图片 allowTaint: true, // 允许渲染canvas(二维码) taintTest: false, // 关闭canvas污染检测 - windowWidth: labelContainer.offsetWidth * 1.5, // 适配缩放后的宽度 - windowHeight: labelContainer.offsetHeight * 1.5, // 适配缩放后的高度 + width: containerWidth, + height: containerHeight, logging: false, }); - // 4. 创建临时打印容器(避免影响原DOM) + // 5. 如果Canvas尺寸超出纸张,需要缩放Canvas + let finalCanvas = canvas; + if (canvas.width > paperWidthPx || canvas.height > paperHeightPx) { + // 创建新的Canvas,尺寸适配纸张 + const scaledCanvas = document.createElement('canvas'); + scaledCanvas.width = Math.min(canvas.width, paperWidthPx); + scaledCanvas.height = Math.min(canvas.height, paperHeightPx); + const ctx = scaledCanvas.getContext('2d'); + ctx.drawImage(canvas, 0, 0, scaledCanvas.width, scaledCanvas.height); + finalCanvas = scaledCanvas; + } + + // 6. 创建临时打印容器(避免影响原DOM) const printContainerId = 'temp-print-container-' + new Date().getTime(); const tempPrintContainer = document.createElement('div'); tempPrintContainer.id = printContainerId; - // 将高清Canvas插入临时容器 - tempPrintContainer.appendChild(canvas); - // document.body.appendChild(tempPrintContainer); + tempPrintContainer.style.cssText = 'position: absolute; left: -9999px; top: -9999px;'; + // 将Canvas插入临时容器 + finalCanvas.style.cssText = `width: ${paperWidthMm}mm; height: ${paperHeightMm}mm; max-width: 100%; max-height: 100%; object-fit: contain;`; + tempPrintContainer.appendChild(finalCanvas); + document.body.appendChild(tempPrintContainer); - // 5. 调用printJS打印高清Canvas(而非原HTML) + // 7. 调用printJS打印高清Canvas(而非原HTML) printJS({ printable: tempPrintContainer, // 打印临时容器 type: 'html', header: null, footer: null, scanStyles: false, // 禁用自动扫描样式,手动控制 - // 自定义打印样式:确保Canvas适配纸张、无多余边距 + // 自定义打印样式:确保Canvas适配纸张、无多余边距、强制单页 style: ` + @page { + size: ${paperWidthMm}mm ${paperHeightMm}mm; + margin: 0 !important; + padding: 0 !important; + } + * { + -webkit-print-color-adjust: exact !important; + print-color-adjust: exact !important; + } + html, body { + margin: 0 !important; + padding: 0 !important; + width: ${paperWidthMm}mm !important; + height: ${paperHeightMm}mm !important; + overflow: hidden !important; + } #${printContainerId} { - width: 100%; - height: auto; - margin: 0; - padding: 0; + width: ${paperWidthMm}mm !important; + height: ${paperHeightMm}mm !important; + margin: 0 !important; + padding: 0 !important; + display: flex !important; + align-items: center !important; + justify-content: center !important; } #${printContainerId} canvas { - max-width: 100%; - height: auto; - border: none; + width: ${paperWidthMm}mm !important; + height: ${paperHeightMm}mm !important; + max-width: ${paperWidthMm}mm !important; + max-height: ${paperHeightMm}mm !important; + object-fit: contain !important; + border: none !important; } @media print { - body * { visibility: hidden; } - #${printContainerId}, #${printContainerId} * { visibility: visible; } - #${printContainerId} { position: absolute; top: 0; left: 0; } + body * { visibility: hidden !important; } + #${printContainerId}, #${printContainerId} * { visibility: visible !important; } + #${printContainerId} { + position: absolute !important; + top: 0 !important; + left: 0 !important; + page-break-inside: avoid !important; + break-inside: avoid !important; + page-break-after: avoid !important; + break-after: avoid !important; + page-break-before: avoid !important; + break-before: avoid !important; + orphans: 999 !important; + widows: 999 !important; + } } `, printContainer: true, onAfterPrint: () => { - // 6. 打印完成后清理临时容器 - document.body.removeChild(tempPrintContainer); - Message.success('打印准备完成,请在打印预览中确认打印'); + // 8. 打印完成后清理临时容器 + if (document.body.contains(tempPrintContainer)) { + document.body.removeChild(tempPrintContainer); + } + Message.success('打印完成'); }, onError: (error) => { // 异常时也清理临时容器 - document.body.removeChild(tempPrintContainer); + if (document.body.contains(tempPrintContainer)) { + document.body.removeChild(tempPrintContainer); + } console.error('打印失败:', error); Message.error('打印失败,请重试'); } }); - - // document.removeChild(tempPrintContainer); } catch (error) { console.error('打印准备失败:', error); Message.error('打印内容准备失败,请重试');