用html做的单据,导出下载为pdf文件,表格内容截断,怎么解决

1,243 阅读2分钟

使用html生成pdf文件,开始用html2canvas,然后使用jsPDF导出,要是一页内容结构简单还是可以使用的,但是内容多的时候,如下

Snipaste_2024-11-29_13-56-00.png

表格内容会截断,怎么解决?

方法一:把表格内容切割A4纸大小,html是循环dom结构实现每一页单据,然后有几页导出几个pdf文件,这种方法可以解决内容被截断问题。 但是有致命缺陷,内容多少不确定,导出的pdf文件数量也不确定,点击导出按钮,下载成恶魔了,电脑还容易卡住,而且导出每页提前定义多少行数不太好控制。

  // 导出页面为PDF格式
  import html2Canvas from "html2canvas";
  import JsPDF from "jspdf";
  Vue.prototype.getPdfPage = function (title) {
      <!-- el  .hz-bill -->
      let PDFViews = document.querySelectorAll(".hz-bill");
      for (let i = 0; i < PDFViews.length; i++) {
        html2Canvas(PDFViews[i], {
          useCORS: true, //看情况选用上面还是下面的,
          logging: false,
          dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍
          scale: 4,
        }).then(function (canvas) {
          let pdf = new JsPDF("p", "mm", "a4"); // A4纸,纵向
          let ctx = canvas.getContext("2d");
          //A4大小,210mm x 297mm,四边各保留20mm的边距,显示区域170x257
          let a4w = 170;
          let a4h = 257;
          //按A4显示比例换算一页图像的像素高度
          let imgHeight = Math.floor((a4h * canvas.width) / a4w);
          let renderedHeight = 0;
          let page = document.createElement("canvas");
          page.width = canvas.width;
          page.height = canvas.height;
          page
            .getContext("2d")
            .putImageData(
              ctx.getImageData(0, 0, canvas.width, canvas.height),
              0,
              0
            );
          pdf.addImage(
            page.toDataURL("image/jpeg", 1.0),
            "JPEG",
            20,
            10,
            a4w,
            Math.min(a4h, (a4w * page.height) / page.width)
          );
          pdf.save(title + ".pdf");
        });
      }
    };

方法二:推荐 这个方法导出的内容清晰度高,上面方法毕竟是先创建canvas画布,然后图片转pdf清晰度差点。 安装依赖jspdf-autotable,可以解决内容截断问题,但是导出的pdf文件内容是乱码。 解决办法查阅 huaweicloud.csdn.net/639febcddac…自行实现,也可联系我分享给你。

import JsPDF from "jspdf";
import "@/plugins/simhei-normal"; // 导入字体
import autoTable from "jspdf-autotable";

Vue.prototype.getPdfOfAutoTable = function (params) {
     let { html, title } = params;
     let doc = new JsPDF();

     let finalY = doc.lastAutoTable.finalY || 10;
     doc.setFontSize(14);
     doc.setFont("simhei");
     doc.text(title, 88, 15);

     doc.autoTable({
       html: html,//dom 结构选择器 如:"#id"
       startY: finalY + 20,
       useCss: true,
       margin: { bottom: 20, left: 10, right: 10 },
       styles: {
         useCss: true,
         font: "simhei", //字体,如果不配置,表格中的中文仍会乱码
         textColor: [0, 0, 0],
       },
     });
      // title 打印pdf的标题
     doc.save(title + ".pdf");
   };

上面的是传dom结构的方式,还有传json数据的方式导出pdf,可以参考网站 github.com/simonbengts… 提供了好多粒子。

另外也有直接打印时的表格不被截断css

table tr { 
    word-break: break-all; 
    page-break-before: always; 
    page-break-after: always; 
    page-break-inside: avoid; 
}