diff --git a/inventory-web/src/views/outbound/Selection.vue b/inventory-web/src/views/outbound/Selection.vue index 55361a6..77586f4 100644 --- a/inventory-web/src/views/outbound/Selection.vue +++ b/inventory-web/src/views/outbound/Selection.vue @@ -23,7 +23,7 @@ 批量操作 - 清空货车 + 清空列表 @@ -794,18 +794,9 @@ const handlePreview = () => { previewVisible.value = true } -// 创建隐藏 iframe 用于打印 -const printFrame = document.createElement('iframe'); -printFrame.style.position = 'absolute'; -printFrame.style.width = '0'; -printFrame.style.height = '0'; -printFrame.style.border = '0'; -document.body.appendChild(printFrame); -const iframeDoc = printFrame.contentWindow.document; - const confirmPrint = async () => { previewVisible.value = false; - // 记录日志 + try { const payload = validSelectedItems.value.map(item => ({ name: item.name, standard: item.standard, quantity: item.export_quantity @@ -813,85 +804,89 @@ const confirmPrint = async () => { printSelectionList(JSON.parse(JSON.stringify(payload))).catch(() => {}); } catch (e) {} - // 获取 #print-area 元素和当前 computed 样式 - const printElement = document.getElementById('print-area'); - if (!printElement) return; - const styles = Array.from(document.styleSheets) - .filter(sheet => { - try { return !sheet.href || sheet.href.indexOf(window.location.host) !== -1; } catch { return false; } - }) - .map(sheet => { - try { - return Array.from(sheet.cssRules).map(rule => rule.cssText).join('\n'); - } catch { return ''; } - }).join('\n'); + setTimeout(() => { + // 1. 获取要打印的区域 DOM + const printElement = document.getElementById('print-area'); + if (!printElement) return; - // 4. 将提取的样式和要打印的 HTML 写入 iframe - iframeDoc.open(); - iframeDoc.write(` - - - - IRIS出库拣货确认单 - ${styles} - - - - ${printElement.outerHTML} - - - `); - iframeDoc.close(); - - // 等 iframe 加载完毕后触发打印 - printFrame.onload = () => { - printFrame.contentWindow.focus(); - printFrame.contentWindow.print(); - }; + // 4. 【核心修复】安全克隆所有样式节点,彻底告别乱码 + const styles = document.querySelectorAll('style, link[rel="stylesheet"]'); + styles.forEach(styleNode => { + iframeDoc.head.appendChild(styleNode.cloneNode(true)); + }); + + // 5. 动态追加针对打印的强制分页 CSS + const customStyle = iframeDoc.createElement('style'); + customStyle.innerHTML = ` + /* 重置基础布局,解除所有高度死锁 */ + html, body { + height: auto !important; + min-height: 100% !important; + overflow: visible !important; + background: white !important; + margin: 0; + padding: 0; + } + /* 规范 A4 纸张 */ + @page { + size: A4 portrait; + margin: 10mm; + } + /* 确保打印区正常流式显示 */ + #print-area { + display: block !important; + position: static !important; + width: 100% !important; + height: auto !important; + } + /* 核心:保护表格不被跨页截断 */ + .print-table { + width: 100% !important; + table-layout: auto !important; + border-collapse: collapse; + } + .print-table tr, .print-table td, .print-table th { + page-break-inside: avoid !important; + break-inside: avoid !important; + } + /* 隐藏不需要的全局 UI */ + .el-overlay, .el-dialog__wrapper, .no-print-content { + display: none !important; + } + `; + iframeDoc.head.appendChild(customStyle); + + // 6. 【核心修复】安全克隆打印区域到 body 中 + iframeDoc.body.appendChild(printElement.cloneNode(true)); + + // 7. 延迟触发打印,等待样式完全渲染 + setTimeout(() => { + iframe.contentWindow?.focus(); + iframe.contentWindow?.print(); + // 打印结束后清理 iframe + setTimeout(() => { + document.body.removeChild(iframe); + }, 1000); + }, 500); // 预留 500ms 渲染时间 + }, 300); } const confirmExport = () => {