首页 > 其他分享 >前端导出pdf,多个元素一起使用

前端导出pdf,多个元素一起使用

时间:2023-01-06 18:13:43浏览次数:32  
标签:canvas const 前端 导出 element 滚动条 leftHeight pdf

需求:最近有个需求,需要导出一份报告文档,有封面页和内容页,封面页内容不多,需要作为pdf单独的一页,内容页的内容很丰富,一页展示不完,那就需要分页展示。

思路:我的实现方法是封面页作为一个元素,内容页作为一个元素,内容页通过pdf分页后和之前的封面页组合在一起,就成了一份完整的pdf报告。

实现:先是用到插件,下载后引用:

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

然后全局设置一个变量:

const pdf = new jsPDF('p', 'pt', 'a4');

然后改下导出pdf的方法:参数1是元素的id名,参数2是在函数最后确认要不要加一页空白pdf.

  exportPage = async (node,adds) =>{
    const element = document.getElementById(node);    // 这个dom元素是要导出pdf的容器
    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);
    // 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此
    // translate的时候,要把这个差值去掉
    await html2canvas(element,{
      allowTaint: true,
      scale: 2 // 提升画面质量,但是会增加文件大小
    }).then( (canvas) => {
      const contentWidth = canvas.width;
      const contentHeight = canvas.height;
      // 一页pdf显示html页面生成的canvas高度;
      const pageHeight = contentWidth / 592.28 * 841.89;
      // 未生成pdf的html页面高度
      let leftHeight = contentHeight;
      // 页面偏移
      let position = 0;
      // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
      const imgWidth = 595.28;
      const imgHeight = 592.28 / contentWidth * contentHeight;
      const pageData = canvas.toDataURL('image/jpeg', 1.0);
      // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
      // 当内容未超过pdf一页显示的范围,无需分页
      if (leftHeight < pageHeight) {
        pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
      }else{  // 分页
        while (leftHeight > 0) {
          pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
          leftHeight -= pageHeight;
          position -= 841.89;
          // 避免添加空白页
          if (leftHeight > 0) {
            pdf.addPage();
          }
        }
      }
    });
    if(adds){
      pdf.addPage(); // 不同元素之间的pdf合在一起需要先加个空白页
    }
  }

 使用方法:

<div>
 <Button
    onClick={
     ()=>{
         this.exportPage("pageOne",true).then(()=>{
              this.exportPage("pageTow").then(()=>{
                  pdf.save(`报告.pdf`);
              })
          })
 }} 

>导出 </Button>
 <div id="pageOne"> 111</div> 
 <div id="pageTow"> 222</div> 
</div>

多个元素之间使用,需要分pdf页的先后顺序,所以存在一个回调地域,只有最里面的一层不需要加第二个参数,一层等一层去生成完整的pdf,然后去下载。

 

标签:canvas,const,前端,导出,element,滚动条,leftHeight,pdf
From: https://www.cnblogs.com/class1/p/17031186.html

相关文章

  • 过滤导出指定app的日志
      @ECHOOFFECHO.[导出logcat日志]ECHO[等待插入手机...]adbwait-for-deviceECHO.-------------------------------adblogcat|findstr"com.xxx.browser">E......
  • three.js场景地形导出到物理引擎
    太长不看版遍历场景地形里的Mesh,从geometry里抽取index和position,通过这两个数组构建物理引擎里的Trimesh。 背景最近在试制网页MMORPG,内核用最顺手的three.js,资产使......
  • 前端实现docx格式文件在线预览
    docx的实现需要使用docx-preview插件安装npmidocx-preview使用html<divref="file"></div>import{renderAsync}from"docx-preview";constdocxOptions=......
  • 2023前端二面必会vue面试题指南
    action与mutation的区别mutation是同步更新,$watch严格模式下会报错action是异步操作,可以获取数据后调用mutation提交最终数据Vue路由hash模式和history......
  • 软件测试和前端开发哪个发展更好?
    没有最好的,只有最适合自己的工作,但是不论是哪个岗位,都是需要不断地更新学习新的知识,这样才能让自己在岗位上立于不败之地。 首先测试和前端虽然都是身处互联网......
  • 前端一面react面试题总结
    redux与mobx的区别?两者对⽐:redux将数据保存在单⼀的store中,mobx将数据保存在分散的多个store中redux使⽤plainobject保存数据,需要⼿动处理变化后的操作;mobx适⽤observ......
  • 美团前端一面必会react面试题
    state和props触发更新的生命周期分别有什么区别?state更新流程:这个过程当中涉及的函数:shouldComponentUpdate:当组件的state或props发生改变时,都会首先触发这......
  • 前端关闭页面前发送请求
    需求描述:当用户关闭/刷新页面后,发送请求通知后端监听事件:beforeunload使用axios发送异步请求发现,刷新时后端可以接收到请求,但是页面关闭时后端无法接收请求navigato......
  • 通用权限系统:(2)前端基础知识
    一、前端开发和前端开发工具1、前端开发介绍前端工程师“Front-End-Developer”源自于美国。大约从2005年开始正式的前端工程师角色被行业所认可,到了2010年,互联网开始全......
  • ORACLE : 数据迁移踩过的大坑,clob字段导入sql失败, 导入/导出 .dmp数据泵时标头验证失
    一、背景数据迁移,并且只需要迁移几张无比巨大的表。本来是打算直接导出导入sql文件的,但是导入sql时报错:ORA-01704字符串文字太长这是因为导出的sql中,clob字段的值被......