html2canvas和jspdf实现html导出pdf文件

实现原理

先使用html2canvas对页面进行截图,再使用jspdf将截图生成pdf文件

html2canvas:通过纯JS对浏览器页面进行截图
jspdf:一个基于 HTML5 的客户端解决方案,用于在客户端 JavaScript 中生成 pdf文件 的库

安装html2canvas和pdf

npm install --save htmlcanvas2
npm install --save jspdf

截图源码

1. 截长图不分页

function handleHtml2canvas(canvas) {
  let contentWidth = canvas.width;
  let contentHeight = canvas.height;

  //一页pdf显示html页面生成的canvas高度;
  let pageHeight = (contentWidth / 592.28) * 841.89;
  //未生成pdf的html页面高度
  let leftHeight = contentHeight;
  //页面偏移
  let position = 0;
  //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
  let imgWidth = 595.28;
  let imgHeight = (592.28 / contentWidth) * contentHeight;

  let pageData = canvas.toDataURL('image/jpeg', 1.0);

  let doc = new JsPDF('', 'pt', 'a4');

  //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
  //当内容未超过pdf一页显示的范围,无需分页
  if (leftHeight < pageHeight) {
    doc.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
  } else {
    while (leftHeight > 0) {
      doc.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
      leftHeight -= pageHeight;
      position -= 841.89;
      //避免添加空白页
      if (leftHeight > 0) {
        doc.addPage();
      }
    }
  } 
  
  return doc;
}

2. 截图分页

function handleHtml2canvas(canvas) {
  let contentWidth = canvas.width;
  let contentHeight = canvas.height;

  //一页pdf显示html页面生成的canvas高度;
  let pageHeight = (contentWidth / 592.28) * 841.89;
  //未生成pdf的html页面高度
  let leftHeight = contentHeight;
  //页面偏移
  let position = 0;
  //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
  let imgWidth = 595.28;
  let imgHeight = (592.28 / contentWidth) * contentHeight;

  let pageData = canvas.toDataURL('image/jpeg', 1.0);

  let doc = new JsPDF('', 'pt', 'a4');

  //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
  //当内容未超过pdf一页显示的范围,无需分页
  if (leftHeight < pageHeight) {
    doc.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
  } else {
    while (leftHeight > 0) {
      doc.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
      leftHeight -= pageHeight;
      position -= 841.89;
      //避免添加空白页
      if (leftHeight > 0) {
        doc.addPage();
      }
    }
  } 
  
  return doc;
}

导出pdf源码

export function exportPdf({ selector, name = 'file', usePage = false, handler }) {
  if (!selector) return;
  const ele = document.querySelector(selector);
  window.setTimeout(() => {
    html2Canvas(ele, {
      logging: false,
      scrollY: 0,
      scrollX: 0,
      scale: 2, // 添加的scale 参数
      width: ele.clientWidth, // dom 原始宽度
      // height: Math.max(ele.clientHeight, ele.clientWidth),
      allowTaint: false,
      useCORS: true, // 开启跨域
      // ignoreElements: (item) => {
      //   return item.classList.contains('export-ignore');
      // },
      onclone(doc) { // html2canvas会把所有dom节点拷贝到一个虚拟节点中,在拷贝结束后执行onclone函数,在onclone函数中修改节点不会影响真实dom
        if (handler) {
          handler(doc);
        }
      }
    }).then(canvas => {
      let doc = usePage ? handleHtml2canvas(canvas) : handleHtml2canvasWithoutPage(canvas);
      doc.save(`${name}.pdf`);
    });
  }, 300);
}

函数调用

handleDoc(doc) {
// doc处理方法,这里可以修改导出节点内容
doc.querySelector('.export-box').classList.add('exporting');
},
    
exportPdf({
     selector: '.domSelector',
     name: 'pdf文件名',
     usePage: true,
     handler: handleDoc
   });

你可能感兴趣的:(JS,HTML,html,pdf,前端)