html2canvas+jsPDF 把网页节点转成图片和pdf

370 阅读4分钟

安装

npm install html2canvas
npm install jspdf

基本使用

没有啥难度,就是用两个库,先转成图片,然后转成pdf 代码如下:

一些问题。

如果出了问题,调试的时候记得分步骤调试,因为你不知道是生成图片那步出了问题还是生成pdf那步出了问题。

  • 下载生成的图片调试代码
  // 下载图片
    let link = domcument.createElement('a');
    link.href = imgUrl; 
    link.setAttribute('download','测试.png') // 设置下载的名字
    link.style.dispaly = 'none' 
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  • 生成图片阴影问题.

如果目标节点也就是示例中的targetDom设置了box-shadow样式,生成的图片带又比较大块的阴影,暂时没啥 根本解决的方案。只能巧妙地绕开。
绕开方案就是:目标节点外面套一层div,把目标节点的阴影样式移动到外层div。

  • 图片过长,生成pdf被截断问题

pdf生成的纸张大小默认是A4,上面例子我是根据图片大小自定义了纸张大小(因为我不用打印,不规定纸张大小),如果你需要规定,那么就得面对这个问题。
解决方案就是:根据图片长度进行分页:

const convertTOPDF = () => {
  const con = targetDom.value; // dom节点
  loading.value = true;
  // 设置html2canvas参数
  const hOptions = {
    dpi: window.devicePixelRatio * 2, // 对应的屏幕dpi,适配高清屏,解决生成图片模糊问题
    allowTaint: true, // 允许图片跨域
    useCORS: true, // 使用图片跨域
  };
  //   执行dom节点转换成图片
  html2canvas(con, hOptions).then((canvas) => {
    let pdf = new jsPDF()
    pdf = setPaging(canvas,0,pdf)
    pdf.save("网页节点.pdf");
  }).finally(()=>{
    loading.value = true;
  })
};
function setPaging(canvas,cutY,pdf){
    const {width:cw,height:ch} = canvas // 获取原图片的宽高
    let cutH = 2480; // A4纸张的高度的像素
    //创建截断后的图片
    const subCanvas = document.createElement('canvas')
    subCanvas.width = cw
    subCanvas.height = cutH
    const context = subCanvas.getContext('2d')
    context.drawImage(canvas,0,cutY,cw,cutH,0,0,cw,cutH)
    const subImgUrl = subCanvas.toDataURL("image/png");  // 生成裁剪后的子图

    cutY !== 0 &&pdf.addPage()  // 如果不是第一页,添加一个页。
    pdf.addImage(subImgUrl,'PNG',0,0) // 把裁剪后的图片添加到pdf
    if(ch - cutY >0){
        cutY += cutH
        return setPaging(canvas,cutY,pdf)
    }else{
        return pdf
    }
}

html2canvas的参数说明

  • html2canvas的options
    • allowTaint:决定是否允许跨域图片“污染”画布,即是否允许将跨域的图片绘制到canvas上。默认值为false,表示不允许跨域图片渲染到canvas上。
    • backgroundColor:设置画布的背景颜色。默认颜色是白色(#fff)。
    • foreignObjectRendering:指定是否使用foreignObject渲染。如果设置为true,则可以渲染一些SVG图像,但这可能会影响性能。默认为false。
    • scale:定义画布的缩放比例。默认值为1,即不缩放。
    • useCORS:指定是否使用CORS(跨源资源共享)进行跨域请求。默认值为false,表示不使用CORS。
  • drawImage

drawImage方法用于在画布上绘制图像,它有多种形态和参数配置。具体如下:

  1. drawImage(image, dx, dy):这种形态会在画布的指定位置(dx, dy)绘制原图。其中image是要绘制的图像对象,dxdy是图像左上角在画布上的坐标位置。
  2. drawImage(image, dx, dy, dw, dh):这种形态不仅会在画布的指定位置绘制图像,还会按照指定的宽度(dw)和高度(dh)来绘制图像。如果不提供dwdh,则会使用原图的大小。
  3. drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh):这种形态允许你从原图中剪切出一个矩形区域(由sx, sy, sw, sh指定),并将这个区域绘制到画布上的指定位置(dx, dy),同时可以指定所绘制图像的宽度(dw)和高度(dh)。

jsPDF的参数说明

  • addImage
    addImage方法在JSPDF库中用于将图像添加到PDF文档中。具体参数如下:
    • image: 需要添加的图像对象或者图像的URL。
    • x: 图像在PDF页面上的x坐标。
    • y: 图像在PDF页面上的y坐标。
    • width (可选): 图像的宽度。如果未指定,则会使用图像的原始宽度。
    • height (可选): 图像的高度。如果未指定,则会使用图像的原始高度。
    • ratio (可选): 图像的宽高比。如果未指定,图像可能会被拉伸以适应指定的宽度和高度。
  • new jspdf(options)
    在创建一个新的jsPDF实例时,可以通过传递一个options对象来定义PDF文档的各种属性。以下是一些可以传递的参数及其含义:
    • orientation:指定PDF页面的方向。可以是'p'(默认,纵向)或'l'(横向)。
    • unit:设置测量单位。可以是"pt"(点),"mm"(毫米),"cm"(厘米),"m"(米),"in"(英寸)或"px"(像素)。
    • format:定义PDF页面的大小。可以传递一个包含宽度和高度的数组,如[595.28, 841.89]表示A4纸大小,或者使用预定义的格式如'a3', 'a4', 'letter'等。
    • compress:布尔值,指定是否启用PDF文件压缩。默认为false。
    • worker:布尔值,指示是否使用Web Worker。如果设置为true,jsPDF将在Web Worker中执行操作以提高性能。默认为false。
    • imageType:指定在PDF中使用的图像类型。可以是'jpeg'、'png'或'svg'。