使用html2canvas将html转pdf,由于table表的水平和竖直有滚动条导致显示不全(或者有空白)

news2025/1/11 11:57:23

结果:

业务:将页面右侧的table打印成想要的格式的pdf,首先遇到的问题是table表上下左右都有滚轮而html2canvas相当于屏幕截图,那滚动区域如何显示出来是个问题?

gif有点模糊,但是大致功能可以看出

可复制代码在最下面

参考文章:主要思路就是table既然原始高度宽度不对,那你在转pdf之前就把他的宽度高度还原成真实的高度宽度然后打印成pdf,最后再转成原始高度宽度。(值得注意的是画布的高度宽度也要设置,和table一样就行)

html代码:

script代码

table表上有个“导出按钮”,点击就会触发handleExport函数

全部代码:

html:

      <div
        ref="myContainer"
        id="fatherDiv"
        class="demo-form-inline"
        style="height: calc(100% - 120px)"
      >
        <el-table
          ref="workforceTable"
          :data="tableData"
          border
          @drop.native="drop($event)"
          @dragover.native="allowDrop($event)"
          stripe
          :span-method="objectSpanMethod"
          :cell-class-name="tableCellClassName"
          max-height="100%"
          height="100%"
          class="demo-form-inline"
          id="factTable"
        >
          <el-table-column
            prop="time"
            label="时间"
            width="70"
            align="center"
            fixed
          ></el-table-column>
          <el-table-column
            :prop="item.sectorCode"
            :label="item.sectorName"
            v-for="item in sectorList"
            :key="item.sectorCode"
            align="center"
          >
            <el-table-column
              :prop="seat.seatId"
              :label="seat.seatName"
              v-for="seat in item.seatList"
              :key="seat.seatId"
              align="center"
              min-width="102px"
            >
              <template slot-scope="scope">
                <span
                  :defProp="seat.seatId"
                  :defTime="scope.row.time"
                  :defIndex="scope.$index"
                ></span>
                <span
                  class="el-tag el-tag--light"
                  defid="scope.row[seat.seatId]"
                  v-if="scope.row[seat.seatId]"
                >
                  <!-- 姓名(班组名称) -->
                  <!-- {{ scope.row[seat.seatId]+"("+scope.row["team"+seat.seatId]+")" }} -->
                  <!-- 姓名 -->
                  {{ scope.row[seat.seatId] }}
                  <i
                    class="el-tag__close el-icon-close"
                    @click="onRemovePerson(scope.$index, seat.seatId)"
                    v-if="isManual"
                  ></i>
                </span>
              </template>
            </el-table-column>
          </el-table-column>

          <el-table-column
            :prop="seat.seatId"
            :label="seat.seatName"
            v-for="seat in seatList"
            :key="seat.seatId"
            align="center"
            min-width="102px"
          >
            <template slot-scope="scope">
              <span
                :defProp="seat.seatId"
                :defTime="scope.row.time"
                :defIndex="scope.$index"
              ></span>
              <span
                class="el-tag el-tag--light"
                defid="scope.row[seat.seatId]"
                v-if="scope.row[seat.seatId]"
              >
                <!-- 姓名(班组名称) -->
                <!-- {{ scope.row[seat.seatId]+"("+scope.row["team"+seat.seatId]+")" }} -->
                <!-- 姓名 -->
                {{ scope.row[seat.seatId] }}
                <i
                  class="el-tag__close el-icon-close"
                  @click="onRemovePerson(scope.$index, seat.seatId)"
                  v-if="isManual"
                ></i>
              </span>
            </template>
          </el-table-column>
        </el-table>
      </div>

script代码:

    handleExport() {
      this.$nextTick(() => {
        let pdfName =
          (this.deptRegion == "TWR"
            ? "塔台"
            : this.deptRegion == "APP"
            ? "进近"
            : "区域") +
          "管制室" +
          this.$common.parseTime(this.selectedMonth, "{y}/{m}/{d}") +
          "日排班表";
        document
          .getElementsByClassName("demo-form-inline")[0]
          .classList.add("export-pdf-style");
        this.generatePDF(this.$refs.myContainer, pdfName);
      });
    },
    generatePDF(el, name) {
      let bodyWrapper = document.querySelector(
        "#factTable .el-table__body-wrapper"
      );
      let headerNode = document.querySelector(
        "#factTable .el-table__header-wrapper"
      );
      bodyWrapper.style.height = `${bodyWrapper.scrollHeight}px`;
      document.getElementById("fatherDiv").style.width = `${bodyWrapper.scrollWidth}px`;
      document.getElementById("fatherDiv").style.height = `${bodyWrapper.scrollHeight + headerNode.scrollHeight不}px`;
      setTimeout(function () {
        html2canvas(el, {
          scale: 4,
          width: bodyWrapper.scrollWidth + 60, // 为了使横向滚动条的内容全部展示,这里必须指定!!
          height: bodyWrapper.scrollHeight + headerNode.scrollHeight ,
        }).then((canvas) => {
          let contentWidth = canvas.width;
          let contentHeight = canvas.height;
          let pageHeight = (contentWidth / 592.28) * 841.89;      //一页pdf显示html页面生成的canvas高度;
          let leftHeight = contentHeight;      //未生成pdf的html页面高度
          let position = 0;          //页面偏移
          let imgWidth = 595.28;     //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
          let imgHeight = (592.28 / contentWidth) * contentHeight;
          let pageData = canvas.toDataURL("image/jpeg", 1.0);
          let pdf = new jsPDF("", "pt", "a4");
          if (leftHeight < pageHeight) {          //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
            pdf.addImage(pageData, "JPEG", 5, 30, imgWidth, imgHeight);       //当内容未超过pdf一页显示的范围,无需分页
          } else {
            while (leftHeight > 0) {
              pdf.addImage(pageData, "JPEG", 5, position, imgWidth, imgHeight); //arg3-->距离左边距;arg4-->距离上边距;arg5-->宽度;arg6-->高度
              leftHeight -= pageHeight;
              position -= 841.89;
              if (leftHeight > 0) {           //避免添加空白页
                pdf.addPage();                //添加新页
              }
            }
          }
          pdf.save(`${name}.pdf`);
          document.getElementById("fatherDiv").style.width = `${100}%`;
          document.getElementById("fatherDiv").style.height = `calc(100% - 120px)`;
          document.getElementsByClassName("demo-form-inline")[0].classList.remove("export-pdf-style");
        });
      }, 200);
    },

css代码:

.export-pdf-style >>> .el-table ,
.export-pdf-style >>> .el-tag{
  background: white !important;
  color: black !important;
}

.export-pdf-style >>> .el-table th,
.export-pdf-style >>> .el-table .el-table__cell {
  color: black;
  border: 1px solid black;
  background: white !important;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1100072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于双级阈值及过零率的语音激活检测(VAD)

语音激活检测&#xff08;Voice Activity Detection, VAD&#xff09;:也称为端点检测&#xff0c;目的就是要找到音频信号的开始和结束位置。 时域方法&#xff1a; 音量&#xff1a;只用音量来进行端点检测&#xff0c;是最简单的方法&#xff0c;但是会对清音造成误判。音…

C#,数值计算——分类与推理Gaumixmod的计算方法与源程序

1 文本格式 using System; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Gaumixmod { private int nn { get; set; } private int kk { get; set; } private int mm { get; set; } private double…

力扣第17题 电话号码的字母组合 c++ 回溯 经典提升题

题目 17. 电话号码的字母组合 中等 相关标签 哈希表 字符串 回溯 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。…

Elasticsearch系列组件:Logstash强大的日志管理和数据分析工具

Elasticsearch 是一个开源的、基于 Lucene 的分布式搜索和分析引擎&#xff0c;设计用于云计算环境中&#xff0c;能够实现实时的、可扩展的搜索、分析和探索全文和结构化数据。它具有高度的可扩展性&#xff0c;可以在短时间内搜索和分析大量数据。 Elasticsearch 不仅仅是一个…

sqlserver系统存储过程添加用户学习

sqlserver有一个系统存储过程sp_adduser&#xff1b;从名字看是添加用户的&#xff1b;操作一下&#xff0c; 从错误提示看还需要先添加一个登录名&#xff0c;再执行一个系统过程sp_addlogin看一下&#xff0c; 执行完之后看一下&#xff0c;安全性-登录名下面有了rabbit&…

【ARM Coresight Debug 系列 -- Linux 断点 BRK 中断使用详细介绍】

文章目录 1.1 ARM BRK 指令1.2 BRK 立即数宏定义介绍1.3 断点异常处理流程1.3.1 el1_sync_handler1.3.2 el1_dbg 跟踪 1.4 debug 异常处理函数注册1.4.1 brk 处理函数的注册 1.1 ARM BRK 指令 ARMv8 架构的 BRK 指令是用于生成一个软件断点的。当处理器执行到 BRK 指令时&…

电脑办公助手之桌面便签,助力高效率办公

在现代办公的快节奏中&#xff0c;大家有应接不暇的工作&#xff0c;每天面对着复杂的工作任务&#xff0c;总感觉时间不够用&#xff0c;而且工作无厘头。对于这种状态&#xff0c;大家可以选择在电脑上安装一款好用的办公便签软件来辅助日常办公。 敬业签是一款专为办公人士…

android--屏幕适配

基础概念 像素密度 dpi &#xff08; √宽^2高^2 &#xff09; / 屏幕大小 手机分辨率 1080 * 1920 1080代表宽 1920代表高 单位为px像素 屏幕大小为英寸 标准的像素密度 mdpi 160dpi dp 密度无关像素 dp与px的转换 density (dpi / 16…

python 之enumerate()函数

文章目录 enumerate() 是 Python 中的一个内置函数&#xff0c;它用于在遍历可迭代对象&#xff08;如列表、元组、字符串等&#xff09;时同时获取每个元素的索引和值。这个函数非常有用&#xff0c;因为它允许您在迭代过程中轻松地访问元素的索引&#xff0c;而不需要手动维护…

基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持自定义业务表单流程(二)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 之前讲到了流程保存的时候还要看是否是自定义业务流程应用类型&#xff0c;若是保存的时候不再检查是否有关…

常见三维建模软件有哪些?各自的特点是什么?

常见的三维建模软件包括以下这些&#xff1a; 1. 3DS Max 3D Studio Max&#xff0c;简称3DS MAX&#xff0c;是当今世界上销售量最大的三维建模、动画及渲染软件。它的应用范围广泛&#xff0c;包括计算机游戏中的动画制作、影视片的特效制作等。3DS MAX的操作相对容易&#…

幸运的袋子(递归+回溯)

目录 一、题目 二、代码 一、题目 幸运的袋子__牛客网 二、代码 #include <iostream> #include <vector> #include <algorithm> using namespace std;static int _count 0; static int sum 0; static int product 1;void Combination(vector<int>…

JAVA学习(6)-全网最详细~

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

【Proteus仿真】【51单片机】电蒸锅温度控制系统

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用LCD1602液晶、按键开关、蜂鸣器、DS18B20温度传感器&#xff0c;液位传感器、继电器控制加热保温装置等。 主要功能&#xff1a; 系统运行后&#…

Elasticsearch7.9.3保姆级安装教程

Linux版本Elasticsearch版本(待安装)Kibana版本(待安装)CentOS 77.9.37.9.3 一、下载地址 1、官网下载 打开地址 https://www.elastic.co/cn/downloads/past-releases#elasticsearch&#xff0c;按如图所示选择对应版本即可 2、采用wget下载 为了不必要的麻烦&#xff0c;建…

nginx.3——local的优先级和匹配方式

在http模块有server模块,在server模块才有location模块, location匹配的是uri location 匹配一旦成功&#xff0c;就不向下匹配 一、location的分类&#xff1a; 1.精确匹配 location /test 2.正则匹配 location ^~ :前缀匹配&#xff0c;以什么为开头 location ~ 区…

【RocketMQ系列四】消息示例-简单消息的实现

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

十五届蓝桥选拔赛Scratch-2023.08.20STEMA测评试题解析

2023年8月20日举行的第15届蓝桥杯STEMA测评Scratch编程中级组 T2 飞驰的高铁 具体要求: 1). 点击绿旗,角色、背景如图所示; 2). 按下一次数字1按键之后,画面中的景色持续向左侧水平移动(参照程序演示视频); 3). 按下一次数字2按键之后,程序结束。 评判标准: 5分:…

“岗课赛证”融通的物联网综合实训室建设方案

一、概述 随着5G技术的普及应用和产业经济的革新发展,物联网产业所呈现的广阔前景带来了对创新型技术技能人才的迫切需求。高职院校物联网专业建设也因此转变为面向国家战略性新兴产业发展需求。当前,“岗位课程竞赛证书”融通的培育理念,是高职院校物联网人才培养和专业优化的…

2023年中国商业版服务器操作系统市场发展规模分析:未来将保持稳定增长[图]

服务器操作系统一般指的是安装在大型计算机上的操作系统&#xff0c;比如Web服务器、应用服务器和数据库服务器等&#xff0c;是企业IT系统的基础架构平台&#xff0c;也是按应用领域划分的三类操作系统之一。同时服务器操作系统也可以安装在个人电脑上。 服务器操作系统分类 …