zoukankan      html  css  js  c++  java
  • html2canvas+jspdf生成PDF

    1、安装 html2canvas 和 jspdf :

    npm install html2canvas
    
    npm install jspdf

    2、按A4纸标准生成PDF(同内容块不裁剪分页):

    1)引入 html2canvasjspdf

    import jsPDF from 'jspdf';
    import html2canvas from 'html2canvas';

    2)下载按钮点击前用延迟函数等待页面渲染完成:

    setStateFun = () => {
        const _this = this;
        let creatPdfTimer=window.setTimeout(_this.creatPdf,500);
        _this.setState({
          creatPdfTimer,
        })
    }

    3)生成PDF:

    creatPdf = () => {
        const _this = this;
        html2canvas(this.standardPlanpdfs,{//把此dom节点下的内容生成pdf
          dpi: 192,
          scale: 2,
          useCORS: true,
          async: false,//同步执行
        }).then(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 = 64;
          let position = 0;
          //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
          let a4Width = 595.28
          let a4Height = 841.89 //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
          //一页pdf显示html页面生成的canvas高度;
          let a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height)
          let pageData = canvas.toDataURL('image/jpeg', 1.0);
          let pdf = new jsPDF('', 'pt', 'a4') //A4纸,纵向
          let index = 1,
          canvas1 = document.createElement('canvas'),
          height;
          pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen')
    
          let pdfName = "standardPlan.pdf";
          if(_this.state.name&&_this.state.grade&&_this.state.grade.name){
            pdfName = `${_this.state.grade.name}-${_this.state.name}.pdf`;
          }else if(_this.state.name){
            pdfName = `${_this.state.name}.pdf`;
          }
          function createImpl(canvas) {
            if (leftHeight > 0) {
              index++
      
              let checkCount = 0
              if (leftHeight > a4HeightRef) {
                let i = position + a4HeightRef;
                for (i = position + a4HeightRef; i >= position; i--) {
                  let isWrite = true
                  for (let j = 0; j < canvas.width; j++) {
                    let c = canvas.getContext('2d').getImageData(j, i, 1, 1).data;
                    if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {
                      isWrite = false
                      break
                    }
                  }
                  if (isWrite) {
                    checkCount++
                    if (checkCount >= 20) {
                      break
                    }
                  } else {
                    checkCount = 0
                  }
                }
                height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef);
                if (height <= 0) {
                  height = a4HeightRef
                }
              } else {
                height = leftHeight
              }
      
              canvas1.width = canvas.width
              canvas1.height = height
      
              let ctx = canvas1.getContext('2d')
              ctx.drawImage(
                canvas,
                0,
                position,
                canvas.width,
                // a4Width,
                height,
                0,
                0,
                canvas.width,
                // a4Width,
                height,
              )
      
              let pageHeight = Math.round((a4Width / canvas.width) * height)
              // pdf.setPageSize(null, pageHeight)
              if (position != 0) {
                pdf.addPage()
              }
              pdf.addImage(
                canvas1.toDataURL('image/jpeg', 1.0),
                'JPEG',
                // 32,//左侧边距
                28,//左侧边距
                // 0,
                32,//头部边距
                a4Width - 64,
                // a4Width,
                (a4Width / canvas1.width) * height - 64,
              )
              leftHeight -= height
              position += height
              if (leftHeight > 0) {
                setTimeout(createImpl, 500, canvas)
              }
              else {
                pdf.save(pdfName);
                _this.setState({
                  downloadLoading:false,
                });
              }
            }
          }
          //当内容未超过pdf一页显示的范围,无需分页
          if (leftHeight < a4HeightRef) {
            pdf.addImage(
              pageData,
              'JPEG',
              // 32,//左侧边距
              28,//左侧边距
              // 0,
              32,//头部边距
              a4Width - 64,
              // a4Width,
              (a4Width / canvas.width) * leftHeight - 64,
            )
            pdf.save(pdfName);
            _this.setState({
              downloadLoading:false,
            });
          } else {
            try {
              pdf.deletePage(0);
              setTimeout(createImpl, 500, canvas);
            } catch (err) {
              // console.log(err);
            }
          }
      }

    3、按页面标准生成PDF(内容过长时:同内容块不裁剪分页--根据颜色进行裁剪):

    creatPdf = () => {
        const { reportData } = this.state;
        const _this = this;
        html2canvas(this.fitnessReportClasss,{//把此dom节点下的内容生成pdf
          allowTaint: true,
          taintTest: false,
          // dpi: window.devicePixelRatio,
          dpi: 120,
          useCORS: true,
          // background: '#FFFFFF',
        }).then(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 = 64;
          let position = 0;
          //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
          let a4Width = 595.28
          let a4Height = 841.89 //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
          //一页pdf显示html页面生成的canvas高度;
          let a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height)
          let pageData = canvas.toDataURL('image/jpeg', 1.0);
          let pdf = new jsPDF('p', 'pt', 'a4') //A4纸,纵向
          let index = 1,
          canvas1 = document.createElement('canvas'),
          height;
          pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen')
    
          let pdfName = reportData && reportData.schoolName && reportData.classesName?
            reportData.schoolName+' '+reportData.classesName+'-报告':'fitnessReportClass';
          function createImpl(canvas) {
            if (leftHeight > 0) {
              index++
      
              let checkCount = 0
              if (leftHeight > a4HeightRef) {
                let i = position + a4HeightRef;
                for (i = position + a4HeightRef; i >= position; i--) {
                  let isWrite = true
                  for (let j = 0; j < canvas.width; j++) {
                    let c = canvas.getContext('2d').getImageData(j, i, 1, 1).data;
                    if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {
                      isWrite = false
                      break
                    }
                  }
                  if (isWrite) {
                    checkCount++
                    if (checkCount >= 20) {
                      break
                    }
                  } else {
                    checkCount = 0
                  }
                }
                height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef);
                if (height <= 0) {
                  height = a4HeightRef
                }
              } else {
                height = leftHeight
              }
      
              canvas1.width = canvas.width
              canvas1.height = height
      
              let ctx = canvas1.getContext('2d')
              ctx.drawImage(
                canvas,
                0,
                position,
                canvas.width,
                height,
                0,
                0,
                canvas.width,
                height,
              )
      
              let pageHeight = Math.round((a4Width / canvas.width) * height)
              if (position != 0) {
                pdf.addPage()
              }
              pdf.addImage(
                canvas1.toDataURL('image/jpeg', 1.0),
                'JPEG',
                32,
                32,
                a4Width - 64,
                (a4Width / canvas1.width) * height - 64,
              )
              leftHeight -= height
              position += height
              if (leftHeight > 0) {
                setTimeout(createImpl, 500, canvas)
              } else {
                pdf.save(pdfName + '.pdf');
                _this.setState({
                  downloadLoading:false,
                });
              }
            }
          }
          //当内容未超过pdf一页显示的范围,无需分页
          if (leftHeight < a4HeightRef) {
            pdf.addImage(
              pageData,
              'JPEG',
              32,
              32,
              a4Width - 64,
              (a4Width / canvas.width) * leftHeight - 64,
            )
            pdf.save(pdfName + '.pdf');
            _this.setState({
              downloadLoading:false,
            });
          } else {
            try {
              pdf.deletePage(0);
              setTimeout(createImpl, 500, canvas);
            } catch (err) {
              // console.log(err);
            }
          }
        })
      }

    4、生成一页PDF(内容不超长):

    creatPdf = () => {
        const {evaluation_report: {data},} = this.props;
        const _this = this;
        // 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此
        // translate的时候,要把这个差值去掉
        html2canvas(this.classReportpdfs,{//把此dom节点下的内容生成pdf
          allowTaint: true,
          dpi: window.devicePixelRatio,
          useCORS: true,
        }).then(canvas=>{
          let element = document.getElementById("classReportOne");    // 这个dom元素是要导出pdf的div容器
          let w = element.offsetWidth;    // 获得该容器的宽
          let h = element.offsetHeight;    // 获得该容器的高
          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 = 64;
          // let position = 0;
          //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
          // let imgWidth = 560.28;
          let imgWidth = 595.28;
          let imgHeight = 592.28/contentWidth * contentHeight;
          let pageData = canvas.toDataURL('image/jpeg', 1.0);
          let pdf = new jsPDF('', 'pt', [contentWidth, contentHeight]);
          pdf.addImage(pageData, 'JPEG', 48, position, contentWidth-96, contentHeight-128 );
          //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
          //当内容未超过pdf一页显示的范围,无需分页
          if(data.hvgData && data.hvgData.schoolName && data.hvgData.classesName){
            pdf.save(`${data.hvgData.schoolName+' '+data.hvgData.classesName}.pdf`);
            _this.setState({
              downloadLoading:false,
            });
          }else{
            pdf.save("classReport.pdf");
            _this.setState({
              downloadLoading:false,
            });
          }
          // pdf.save("creat.pdf");
        })
      }

    注:插件参数请参考对应官网

  • 相关阅读:
    hibernate set的3个属性
    我的Android进阶之旅------&gt;Android无第三方Jar包的源代报错:The current class path entry belongs to container ...的解决方法
    SAN,NAS,DAS的差别
    SSDT表概念具体解释
    《COM本质论》COM是一个更好的C++心得分享
    Hadoop学习小结
    出来混,是否应该吹牛皮
    出来混,是否应该吹牛皮
    创业的关键:顺势而为
    创业的关键:顺势而为
  • 原文地址:https://www.cnblogs.com/dreambin/p/15329603.html
Copyright © 2011-2022 走看看