前端生成PDF预览、下载功能实现

468 阅读2分钟

需求

可根据填写的表单生成PDF文档,预览并下载,要求A4纸张,根据内容进行分页处理

实现思路

借助两个库html2canvasjspdf

html2canvas 可以将网页的部分或全部内容截图,并转换为图像格式,例如 PNG 或 JPEG。

jsPDF 可以在客户端生成 PDF 文件,而无需借助后端服务。

实现代码

const createPDF = (preview) => {
    let pdfDom = document.getElementById("pdf-content");
      const pdfScrollHeight = pdfDom.scrollHeight;
      // 获取pdfDom的宽度
      const pdfDomWidth = pdfDom.offsetWidth;
      html2Canvas(pdfDom, {
        useCORS: true,
        scale: 1,
        // 指定内容的宽度,如果设置会导致截取的内容不全,不包括滚动条以外的内容
        width: pdfDomWidth,
        // 指定内容的高度,如果设置会导致截取的内容不全,不包括滚动条以外的内容
        height: pdfScrollHeight,
        allowTaint: true,
      }).then((canvas) => {
        // a4纸的正常尺寸是宽592.28,高是841.89
        const pageHeight = 841.89;
        const pageWidth = 592.28;
        // 设置内容的宽高
        const contentWidth = canvas.width;
        const contentHeight = canvas.height;
        // 默认的偏移量
        let position = 0;
        // 设置生成图片的宽高
        const imgCanvasWidth = pageWidth;
        const imgCanvasHeight = (pageWidth / contentWidth) * contentHeight;
        let imageHeight = imgCanvasHeight;
        // 生成canvas截图,1表示生成的截图质量(0-1)
        let pageData = canvas.toDataURL("image/jpeg", 1);
        // new JsPDF接收三个参数,landscape表示横向,(默认不填是portrait纵向),打印单位和纸张尺寸
        let PDF = new JsPDF("portrait", "pt", "a4");
        // 当内容不超过a4纸一页的情况下
        if (imageHeight < pageHeight) {
          PDF.addImage(pageData, "JPEG", 14, 10, imgCanvasWidth, imgCanvasHeight);
        } else {
          // 当内容超过a4纸一页的情况下,需要增加一页
          while (imageHeight > 0) {
            PDF.addImage(
              pageData,
              "JPEG",
              14,
              position,
              imgCanvasWidth,
              imgCanvasHeight
            );
            imageHeight -= pageHeight;
            position -= pageHeight;
            // 避免添加空白页
            if (imageHeight > 0) {
              PDF.addPage();
            }
          }
        }
        if (preview) {
          // 新页面打开预览生成的PDF
          PDF.output("dataurlnewwindow");
        } else {
          // 下载生成的PDF
          PDF.save(details.value?.projectName + "-评估报告" + ".pdf");
        }
})

注意事项

如果输入框带有box-shadow 可能会导致样式有些奇怪

iShot_2024-07-10_09.48.21.png 修改box-shadow:none后的效果

image.png