feat
This commit is contained in:
@@ -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;
|
||||
// 获取内容的总高度
|
||||
let remainingContent = element.cloneNode(true);
|
||||
document.body.appendChild(remainingContent);
|
||||
remainingContent.style.width = `${a4Width - 2 * margin}pt`;
|
||||
const totalHeight = remainingContent.offsetHeight;
|
||||
|
||||
// 将canvas转为图片
|
||||
const imgData = canvas.toDataURL('image/jpeg', 1.0);
|
||||
// 计算需要的页数
|
||||
const contentHeight = a4Height - 2 * margin;
|
||||
const pageCount = Math.ceil(totalHeight / contentHeight);
|
||||
|
||||
// 初始化jsPDF
|
||||
const pdf = new jsPDF('p', 'mm', 'a4');
|
||||
|
||||
// 计算分页
|
||||
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) {
|
||||
// 逐页处理内容
|
||||
for (let i = 0; i < pageCount; i++) {
|
||||
if (i > 0) {
|
||||
pdf.addPage();
|
||||
currentPage++;
|
||||
}
|
||||
}
|
||||
|
||||
// 保存PDF
|
||||
// 创建当前页的容器
|
||||
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);
|
||||
}
|
||||
|
||||
// 清理克隆的元素
|
||||
document.body.removeChild(remainingContent);
|
||||
|
||||
pdf.save(`${quotation.attributes.quataName || '报价单'}.pdf`);
|
||||
|
||||
// 关闭加载提示
|
||||
message.destroy();
|
||||
message.success('PDF导出成功!');
|
||||
} catch (error) {
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user