前端实现把整个页面转成PDF保存到本地(DOM转PDF)

发布于:2024-11-28 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、问题
遇到一个需求,就是要把整个看板页面导出成PDF用在汇报,也就是要把整个DOM生成一个PDF保存到本地。

二、解决方法
1、解决思路:使用插件 jspdf 和 html2canvas,我用的版本如下图
在这里插入图片描述
2、代码实现

import  { jsPDF }  from 'jspdf'
import html2canvas from 'html2canvas'


// 封装成一个公共的方法(核心代码)
export const htmlToPDF = async (htmlId: string, title: string, bgColor = "#fff") => {
  const pdfDom = document.getElementById(htmlId) as HTMLElement | null;
  if (!pdfDom) {
    console.error('Element not found');
    return '';
  }

  const scale = window.devicePixelRatio || 1; // 使用设备像素比来提高清晰度
  const canvas = await html2canvas(pdfDom, {
    scale: scale,
    useCORS: true,
    backgroundColor: bgColor,
  });

  const imgProps = canvas.toDataURL('image/png'); // 使用PNG格式提高质量
  const pdf = new jsPDF({
    orientation: 'portrait',
    unit: 'px',
    format: [595.28, 841.89], // A4尺寸(以像素为单位)
  });

  const imgPropsObj = pdf.getImageProperties(imgProps);
  const pdfWidth = 576; // A4宽度减去一些边距
  // 控制页面展示 调整这个98 防止出现空白页
  const pdfHeight = (imgPropsObj.height * pdfWidth) / imgPropsObj.width - 98;

  const pageHeight = 841.89; // A4页面的高度
  let heightLeft = pdfHeight; // 剩余高度
  let y = 0; // 当前Y坐标

  // 处理分页逻辑
  while (heightLeft > 0) {
    const imgHeight = Math.min(heightLeft, pageHeight); // 当前图像可显示的高度

    pdf.addImage(imgProps, 'PNG', 0, y, pdfWidth, imgHeight); // 添加图像

    heightLeft -= imgHeight; // 减去已添加的高度
    y += imgHeight; // 移动Y坐标

    if (heightLeft > 0) {
      pdf.addPage(); // 如果还有内容,则添加新页面
    }
  }

  // 生成并返回PDF文件
  pdf.save(title + '.pdf');
  const pdfUrl = window.URL.createObjectURL(new Blob([pdf.output('blob'), { type: 'application/pdf' }]));
  return pdfUrl;
};




// 页面中调用 box:要转成pdf文件的盒子
<div id="box">
// 此处为你的页面内容
</div>
// 点击如下方法保存pdf
<button @click="fn">生产pdf</button>

// htmlToPDF 第一个参数:要生成pdf文件的盒子id  第二个参数:生成pdf的文件名
const fn = ()=> {
  const pdfUrl = htmlToPDF("box", 'xxx.pdf')
}