首页 > 其他分享 >前端导出pdf字体表格被截断问题解决

前端导出pdf字体表格被截断问题解决

时间:2023-02-13 19:34:33浏览次数:45  
标签:canvas const 表格 导出 a4HeightRef let leftHeight pdf

最近有个导出pdf的需求,写好之后分页出现字体,表格被截断的问题,影响美观,需要解决。

 

 经过多方查找,发现一个比较好的思路,设置背景色为白色,然后转成图片后,获取截断处图片像素点,从截断处往上一行行扫描像素点颜色,碰到这一行颜色都是全白的,代表是从这里开始截断,将这个高度开始将往下的内容都放到下一页。这个是原博客,https://cloud.tencent.com/developer/article/1752946?from=information.detail.js%E7%BD%91%E9%A1%B5%E7%94%9F%E6%88%90pdf。

根据自身需求,做了改造:

  exportPage = async (node,adds) =>{
    const element = document.getElementById(node);    // 这个dom元素是要导出pdf的div容器
    const w = element.offsetWidth;    // 获得该容器的宽
    const h = element.offsetWidth;    // 获得该容器的高
    const {offsetTop} = element;    // 获得该容器到文档顶部的距离
    const {offsetLeft} = element;    // 获得该容器到文档最左的距离
    const canvas = document.createElement("canvas");
    let abs = 0;
    const winI = document.body.clientWidth;    // 获得当前可视窗口的宽度(不包含滚动条)
    const winO = window.innerWidth;    // 获得当前窗口的宽度(包含滚动条)
    if (winO > winI) {
      abs = (winO - winI) / 2;    // 获得滚动条长度的一半
    }
    canvas.width = w * 2;    // 将画布宽&&高放大两倍
    canvas.height = h * 2;
    const context = canvas.getContext("2d");
    context.scale(2, 2);
    context.translate(-offsetLeft - abs, -offsetTop);
    await html2canvas(element,{
      allowTaint: true,
      scale: 2, // 提升画面质量,但是会增加文件大小
      useCORS: true,
      background: '#FFFFFF', // 如果指定的div没有设置背景色会默认成黑色,这里是个坑
      // tslint:disable-next-line:no-shadowed-variable
      // eslint-disable-next-line no-shadow
    }).then( (canvas) => {
      // 未生成pdf的html页面高度
      let leftHeight = canvas.height;

      const a4Width = 594.28  // 595.28,写小是纸的内容要完全在canvas里
      const a4Height = 841.89 // A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
      // 一页pdf显示html页面生成的canvas高度;
      const a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height)

      // pdf页面偏移
      let position = 0

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

      let index = 1;
      const canvas1 = document.createElement('canvas');
      let height;
      pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen')

      function createImpl(paramsCanvas) {
       // console.log(leftHeight, a4HeightRef)
        if (leftHeight > 0) {
          index+=1;
          let checkCount = 0
          if (leftHeight > a4HeightRef) {
            let i ;
            for (i = position + a4HeightRef; i >= position; i-=1) {
              let isWrite = true
              for (let j = 0; j < paramsCanvas.width; j+=1) {
                const c = paramsCanvas.getContext('2d').getImageData(j, i, 1, 1).data

                if (c[0] !== 0xff || c[1] !== 0xff || c[2] !== 0xff) {
                  isWrite = false
                  break
                }
              }
              if (isWrite) {
                checkCount+=1
                if (checkCount >= 10) {
                  break
                }
              } else {
                checkCount = 0
              }
            }
            height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef)
            if (height <= 0) {
              height = a4HeightRef
            }
          } else {
            height = leftHeight
          }

          canvas1.width = paramsCanvas.width
          canvas1.height = height

        //  console.log(index, 'height:', height, 'pos', position)
          const ctx = canvas1.getContext('2d')
          ctx.drawImage(paramsCanvas, 0, position, paramsCanvas.width, height, 0, 0, paramsCanvas.width, height,)

          //  const pageHeight = Math.round((a4Width / canvas.width) * height)
          // pdf.setPageSize(null, pageHeight)
          if (position !== 0) {
          //  console.log("最后的位置", position)
            pdf.addPage()
          }
          if(index===2){
            // 有分页的时候,第一页时候,index===2,保证首页不需要有偏移量。而从第二页起,上下偏移16
            pdf.addImage(canvas1.toDataURL('image/jpeg', 1.0), 'JPEG', 0, 0, a4Width, (a4Width / canvas1.width) * height,)
          }else{
            pdf.addImage(canvas1.toDataURL('image/jpeg', 1.0), 'JPEG', 0, 16, a4Width, (a4Width / canvas1.width) * height,)
          }

          // eslint-disable-next-line no-const-assign
          leftHeight -= height
          position += height
          if (leftHeight > 0) {
           // console.log("leftHeight", leftHeight)
            createImpl(paramsCanvas)
          } else {
            // pdf.save(pdfName + '.pdf')
          }
        }
      }

      // 当内容未超过pdf一页显示的范围,无需分页
      if (leftHeight < a4HeightRef) {
        pdf.addImage(pageData, 'JPEG', 0, 0, a4Width, (a4Width / canvas.width) * leftHeight)
      } else {
        try {
          pdf.deletePage(0);
          createImpl(canvas);
        } catch (err) {
          // console.log(err);
        }
      }
    });
    if(adds){
      pdf.addPage();
    }
  }

 使用同上一篇pdf内容相同

标签:canvas,const,表格,导出,a4HeightRef,let,leftHeight,pdf
From: https://www.cnblogs.com/class1/p/17117494.html

相关文章

  • Js导出csv
    functionexportCSV(title,jsonData,name){//要导出的json数据letstr=``;for(letioftitle){......
  • import/export按需导出的成员
            使用as重命名 按需导入可以和默认导入一起使用 ......
  • 将Markdown文件转换成PDF文件
    1.下载并安装1.1vscode  首先需要说明的是vscode分为System和User两种版本。对于完成该任务来说,并没有太大区别。这里提供一个windows64位的User版本的下载地址:https:......
  • 数据库导出excel信息(mysql数据库已经验证)
    导出表信息1SELECT2TABLE_NAME表名,3REPLACE(4REPLACE(TABLE_COMMENT,CHAR(10),''),5CHAR(13),6','7......
  • Bootstrap-table的客户端分页渲染表格
    文章目录​​一、前言:​​​​1、服务端分页地址:​​​​2、插件下载地址:​​​​二、客户端分页步骤:​​​​1、table标签:​​​​2、js渲染:​​​​2.1、表格初始化​​......
  • 利用bootstrap-table插件自带的打印功能打印表格
    文章目录​​1、前端代码:​​​​2、前端页面:​​​​1、表格数据展示​​​​2、点击打印按钮之后:​​​​3、插件下载地址:​​​​4、碰到的bug​​1、前端代码:<linkhre......
  • leangoo领歌共享协作思维导图导入导出XMind文件。
    协作型共享多人协作思维导图Leangoo,可以导出导入XMind文件了,我们来看看如何操作:进入leangoo官网:www.leangoo.com,登陆账号。点击右上角“+”新建脑图,然后导入XMind文件......
  • reportlab 生成pdf
    使用fromreportlab.lib.stylesimportgetSampleStyleSheet产生基础格式。如何修改需要的格式:styles=getSampleStyleSheet()style.normal=copy.deepcopy(styles['N......
  • AD22 PCB导出Gerber文件详细步骤
    PCB绘制好,检查完成后,就可以把文件交给PCB工厂生产了,一般有两种方式:第一种最简单就是直接将PCB文件压缩打包,发给工厂。第二种生成Gerber等相关资料,再压缩打包,发给......
  • javascript表单提交的内容显示在表格中
    实现三个文本域的内容提交之后显示在表格中,代码直接用文本文件运行,记得后缀改为.html运行结果输入123,并点击提交按钮之后,数据就会显示在下面的表格中,有什么问题可以私聊我......