From 48733f3b7c9453f7abaae6cfce3f108c824b0ce7 Mon Sep 17 00:00:00 2001 From: liamzi Date: Wed, 15 Jan 2025 11:21:49 +0800 Subject: [PATCH] feat --- src/pages/company/quotation/view/index.jsx | 97 ++++++++++++---------- src/routes/routes.js | 18 +++- 2 files changed, 70 insertions(+), 45 deletions(-) diff --git a/src/pages/company/quotation/view/index.jsx b/src/pages/company/quotation/view/index.jsx index 333b4bf..4adfeda 100644 --- a/src/pages/company/quotation/view/index.jsx +++ b/src/pages/company/quotation/view/index.jsx @@ -42,61 +42,70 @@ const QuotationPreview = () => { // PDF导出函数 const exportPDF = async () => { try { - // 显示加载中 message.loading('正在生成PDF...', 0); - - // 获取要导出的DOM元素 const element = document.getElementById('quotation-content'); - // 使用html2canvas将DOM转换为canvas - const canvas = await html2canvas(element, { - scale: 2, // 提高清晰度 - useCORS: true, // 允许加载跨域图片 - logging: false, // 关闭日志 - backgroundColor: '#ffffff' // 设置背景色 + // A4 尺寸(单位:pt,1mm ≈ 2.83pt) + const a4Width = 595.28; + const a4Height = 841.89; + const margin = 40; // 页边距(pt) + + // 初始化 PDF + const pdf = new jsPDF({ + unit: 'pt', + format: 'a4', }); - // 获取canvas的宽高 - const imgWidth = 210; // A4纸的宽度(mm) - const pageHeight = 297; // A4纸的高度(mm) - const imgHeight = canvas.height * imgWidth / canvas.width; - const pdfWidth = imgWidth; - const pdfHeight = imgHeight; - - // 将canvas转为图片 - const imgData = canvas.toDataURL('image/jpeg', 1.0); - - // 初始化jsPDF - const pdf = new jsPDF('p', 'mm', 'a4'); + // 获取内容的总高度 + let remainingContent = element.cloneNode(true); + document.body.appendChild(remainingContent); + remainingContent.style.width = `${a4Width - 2 * margin}pt`; + const totalHeight = remainingContent.offsetHeight; - // 计算分页 - let position = 0; - let currentPage = 1; - - while (position < pdfHeight) { - // 添加图片到PDF - pdf.addImage( - imgData, - 'JPEG', - 0, // x坐标 - position === 0 ? 0 : -position, // y坐标 - pdfWidth, // 图片宽度 - pdfHeight // 图片高度 - ); - - position += pageHeight; - - // 如果还有内容,添加新页面 - if (position < pdfHeight) { + // 计算需要的页数 + const contentHeight = a4Height - 2 * margin; + const pageCount = Math.ceil(totalHeight / contentHeight); + + // 逐页处理内容 + for (let i = 0; i < pageCount; i++) { + if (i > 0) { pdf.addPage(); - currentPage++; } + + // 创建当前页的容器 + const pageDiv = document.createElement('div'); + pageDiv.style.width = `${a4Width - 2 * margin}pt`; + pageDiv.style.height = `${contentHeight}pt`; + pageDiv.style.position = 'absolute'; + pageDiv.style.top = '0'; + pageDiv.style.left = '0'; + pageDiv.style.overflow = 'hidden'; + + // 克隆原始内容 + const contentClone = element.cloneNode(true); + contentClone.style.transform = `translateY(-${i * contentHeight}pt)`; + pageDiv.appendChild(contentClone); + document.body.appendChild(pageDiv); + + // 转换为图片并添加到 PDF + const canvas = await html2canvas(pageDiv, { + scale: 2, + useCORS: true, + logging: false, + backgroundColor: '#ffffff', + }); + + const imgData = canvas.toDataURL('image/jpeg', 1.0); + pdf.addImage(imgData, 'JPEG', margin, margin, a4Width - 2 * margin, contentHeight); + + // 清理临时元素 + document.body.removeChild(pageDiv); } - // 保存PDF + // 清理克隆的元素 + document.body.removeChild(remainingContent); + pdf.save(`${quotation.attributes.quataName || '报价单'}.pdf`); - - // 关闭加载提示 message.destroy(); message.success('PDF导出成功!'); } catch (error) { diff --git a/src/routes/routes.js b/src/routes/routes.js index 93a01af..ae7f2c2 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -81,6 +81,15 @@ export const allRoutes = [ hidden: true, key: "company/quotaInfo", }, + { + path: "quotaInfo/preview/:id?", + hidden: true, + component: lazy(() => import("@/pages/company/quotation/view")), + name: "报价单预览", + icon: "file", + key: "company/quotaInfo/preview", + }, + { path: "project", component: lazy(() => import("@/pages/company/project")), @@ -140,7 +149,14 @@ export const allRoutes = [ icon: "appstore", hidden: true, key: "company/projectView", - } + }, + { + path: "templateItemManage", + component: lazy(() => import("@/pages/company/service/itemsManange")), + name: "资源类型", + icon: "container", + key: "company/templateItem", + }, ] } ];