纯前端实现数据下载为PDF

170 阅读4分钟

这里我采用的是将数据渲染为html,然后html转图片,图片转pdf,具体代码如下 渲染就不展示了

第一步 安装插件

npm i html2canvas jsPDF -S

第二步 配置然后引用到组件里面

/** 下载为pdf */
export const downloadPDF = async (element:要转为图片的html元素) => {
    //html转图片
  const canvas = await html2canvas(element, {
    scale: 2, // 提高截图清晰度
    useCORS: true, // 如果需要跨域图片,请确保设置此选项
    allowTaint: true, // 允许跨域图片
    //上面两个属性设置了,但是没有生效,有知道原因可以评论
    height: element.getBoundingClientRect().height,
  });

  const imgData = canvas.toDataURL('image/png');
  // 根据Canvas尺寸选择或计算PDF页面尺寸
  // 这里我们简单地使用Canvas的尺寸作为PDF页面的尺寸,但你可以根据需要调整
  const pdfWidth = canvas.width ;
  const pdfHeight = canvas.height;
  // 如果你想要添加边距,可以增加pdfWidth和pdfHeight的值

  const pdf = new jsPDF({
    orientation: 'landscape', // 使用横向模式
    unit: 'px',
    format: [pdfWidth, pdfHeight], // 使用Canvas的尺寸作为PDF页面的尺寸
  });

  // 由于PDF页面尺寸已经与Canvas匹配,我们不需要缩放图片
  // 直接将图片添加到PDF的(0, 0)位置
  pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
  // 保存PDF
  pdf.save(`test.pdf`);
};
jsPDF常用参数
html2canvas常用参数

html2canvas 函数接受一些常用的参数,用于配置转换后的 canvas 元素的行为和样式。以下是一些常用的参数:

  • element: 必需参数,表示需要转换为 canvas 的 HTML 元素。
  • width 和 height: 可选参数,分别表示转换后的 canvas 元素的宽度和高度。如果不设置这些参数,则 canvas 元素会自动调整大小以适应所包含的 HTML 元素。
  • scale: 可选参数,表示 canvas 元素的比例。默认值为 1,表示 canvas 元素会保持原始大小。
  • border: 可选参数,表示 canvas 元素的边框宽度。默认值为 0,表示没有边框。
  • backgroundColor: 可选参数,表示 canvas 元素的背景颜色。默认值为 “#ffffff”,表示白色。
  • foregroundColor: 可选参数,表示 canvas 元素的前景色颜色。默认值为 “#000000”,表示黑色。
  • imageQuality: 可选参数,表示转换后的图像的质量。默认值为 1,表示高质量。
  • jsPDF: 可选参数,表示需要使用的 jsPDF 对象。如果不设置这个参数,则不会将 canvas 转换为 PDF 文件。
jsPDF 是一个用于创建 PDF 文件的 JavaScript 库。以下是 jsPDF 常用的参数:
  1. jsPDF('1', 'pt', [width, height]): 创建一个新的 PDF 对象,其中 '1' 表示 A4 纸张(l:竖向,p:横向),'pt' 表示单位为 point,width 和 height 分别表示页面宽度和高度。
  2. pdf.setFont(font, size): 设置 PDF 文件的字体和大小。其中 font 表示字体名称,如 'Helvetica' 或 'Times'size 表示字体大小。
  3. pdf.setLineWidth(width): 设置 PDF 文件的线宽。其中 width 表示线宽的像素值。
  4. pdf.drawLine(x1, y1, x2, y2): 在 PDF 文件中绘制一条直线。其中 x1y1 和 x2y2 分别表示直线的起点和终点坐标。
  5. pdf.drawRect(x, y, width, height): 在 PDF 文件中绘制一个矩形。其中 xy 分别表示矩形左上角的坐标,width 和 height 分别表示矩形的宽度和高度。
  6. pdf.drawText(text, x, y): 在 PDF 文件中绘制一段文本。其中 text 表示要绘制的文本,x 和 y 分别表示文本的左上角坐标。
  7. pdf.save('filename.pdf'): 将 PDF 文件保存为指定的文件名。其中 'filename.pdf' 表示要保存的 PDF 文件的文件名。
  8. pdf.addImage(imageData, type, x, y, width, height): 在 PDF 文件中添加一个图像。其中 imageData 表示图像的数据,type 表示图像的类型,如 'JPEG' 或 'PNG'xy 分别表示图像左上角的坐标,width 和 height 分别表示图像的宽度和高度。
  9. pdf.rotate(angle, x, y): 旋转 PDF 文件中的图像或文本。其中 angle 表示旋转的角度,x 和 y 分别表示旋转中心的位置。
  10. pdf.translate(x, y): 将 PDF 文件中的文本或图像移动到指定位置。其中 x 和 y 分别表示要移动的坐标。
常见问题
图片跨域

问题现象: 转换之后的图片,原本展示图片资源的地方空白

解决方案:

  • 设置配置项 allowTaint: false

    canvas 的 CanvasRenderingContext2D 属于浏览器的对象,如果渲染过跨域资源,浏览器就认定 canvas 已经被污染了 Taint:污点

  • 设置配置项 useCORS: false

    表示允许跨域资源共享,注意不能与 allowTaint 同时配置为 true

  • img 标签中添加 crossOrigin = "anonymous"

    anonymous:如果使用这个值的话就会在请求 header 中带上 Origin 属性,但请求不会带上 cookie 和客户端 ssl 证书等其他的一些认证信息

  • 图片服务器配置 Access-Control-Allow-Origin: *

    重要的配置项,是跨域问题的根本源泉,需要后端配合

其实可以有html转PDF的方法,但是不知道为什么转换之后的是乱码,如果有知道实现办法和原因的可以评论,感谢!!!