导出为PDF加封面且分页处理dom元素分割

news2024/11/29 12:37:46

文章目录

  • 正常展示页面
  • 导出后效果
  • 代码

正常展示页面

在这里插入图片描述

导出后效果

在这里插入图片描述

代码

组件内

<template>
  <div>
    <div class="content" id="content" style="padding: 0px 20px">
      <div class="item">
        <div
          style="height: 1600px; width: 100%; background: pink; display: none"
          ref="wrap"
        >
          <h1>封面</h1>
        </div>
      </div>
      <!--    每一块dom的class类设置成item(自定义)以此处理内容分割  -->
      <div class="item">
        <button @click="outPutPdfFn">导出</button>
        <!-- 组件  可为任意内容  -->
        <MyTableView></MyTableView><TableView />
      </div>
      <div class="item">
        内容22
        <!-- 组件  可为任意内容  -->
        <MyTableView></MyTableView><TableView />
      </div>
      <div class="item">内容22 <TableView /><TableView /></div>
      <div class="item" style="padding: 20px 0">
        gsd
        <!-- 组件  可为任意内容  -->
        <TableView />
        <TableView />
      </div>
      <div class="item" style="padding: 20px 0">
        内容22
        <!-- 组件  可为任意内容  -->

        <TableView /><TableView />
      </div>
      <div class="item">
        gsd
        <!-- 组件  可为任意内容  -->

        <TableView />
        <TableView />
      </div>
    </div>
  </div>
</template>
 
<script>
import MyTableView from "./table2";
import TableView from "./table";
import getPdf from "../../utils/jsPdf";

export default {
  components: {
    MyTableView,
    TableView,
  },
  data() {
    return {};
  },
  mounted() {
    // this.getMain();
  },
  methods: {
    outPutPdfFn() {
      let vm = this;
      const A4_WIDTH = 592.28;
      const A4_HEIGHT = 841.89;
      // $myLoading 自定义等待动画组件,实现导出事件的异步等待交互
      // this.$myLoading('正在导出pdf,请稍候。。。', true);
      vm.$nextTick(() => {
        // dom的id。
        this.$refs.wrap.style.display = "block";
        let target = document.getElementById("content");
        let pageHeight = (target.scrollWidth / A4_WIDTH) * A4_HEIGHT;
        // 获取分割dom,此处为class类名为item的dom
        let lableListID = document.getElementsByClassName("item");
        // 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空dom,把他挤下去,分割
        for (let i = 0; i < lableListID.length; i++) {
          let multiple = Math.ceil(
            (lableListID[i].offsetTop + lableListID[i].offsetHeight) /
              pageHeight
          );
          if (this.isSplit(lableListID, i, multiple * pageHeight)) {
            let divParent = lableListID[i].parentNode; // 获取该div的父节点
            let newNode = document.createElement("div");
            newNode.className = "emptyDiv";
            newNode.style.background = "#ffffff";
            let _H =
              multiple * pageHeight -
              (lableListID[i].offsetTop + lableListID[i].offsetHeight);
            newNode.style.height = _H + 100 + "px";
            newNode.style.width = "100%";
            let next = lableListID[i].nextSibling; // 获取div的下一个兄弟节点
            // 判断兄弟节点是否存在
            console.log(next);
            if (next) {
              // 存在则将新节点插入到div的下一个兄弟节点之前,即div之后
              divParent.insertBefore(newNode, next);
            } else {
              // 不存在则直接添加到最后,appendChild默认添加到divParent的最后
              divParent.appendChild(newNode);
            }
          }
        }
        // 传入title和dom标签,此处是 #content
        // 异步函数,导出成功后处理交互
        getPdf("巡检报告单-" + "000" + "-" + "嘿嘿嘿", "#content")
          .then(() => {
            // 自定义等待动画关闭
            // this.$myLoading(false);
            this.$message({
              type: "success",
              message: "导出成功",
            });
          })
          .catch(() => {
            // this.$myLoading(false);
            this.$message({
              type: "error",
              message: "导出失败,请重试",
            });
          });
          this.$refs.wrap.style.display = "none";
            const arr = document.getElementsByClassName("emptyDiv");
            const l = arr.length;
            for (let i = l - 1; i >= 0; i--) {
              if (arr?.[i] != null) {
                arr?.[i]?.remove(arr[i]);
              }
            }
      });
    },
    isSplit(nodes, index, pageHeight) {
      // 计算当前这块dom是否跨越了a4大小,以此分割
      if (
        nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight &&
        nodes[index + 1] &&
        nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight
      ) {
        return true;
      }
      return false;
    },
  },
};
</script>
 
<style scoped>
.mainFirst {
  display: flex;
  justify-content: space-between;
  padding: 0 20px 10px 20px;
}
</style>

jsPdf.js

// 导出页面为PDF格式
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';
 
const getPdf = function (title, dom) {
    // 注册getPdf方法,传入两个参数,此处使用了promise处理导出后的操作
    /*
    title: 导出文件名
    dom: 需要导出dom的id
     */
    return new Promise((resolve, reject) => {
        html2Canvas(document.querySelector(dom), {
            useCORS: true, // 由于打印时,会访问dom上的一些图片等资源,解决跨域问题!!重要
            allowTaint: true // 允许跨域
        }).then(function (canvas) {
            let contentWidth = canvas.width;
            let contentHeight = canvas.height;
            // 根据A4纸的大小,计算出dom相应比例的尺寸
            let pageHeight = contentWidth / 592.28 * 841.89;
            let leftHeight = contentHeight;
            let position = 0;
            let imgWidth = 595.28;
            // 根据a4比例计算出需要分割的实际dom位置
            let imgHeight = 592.28 / contentWidth * contentHeight;
            // canvas绘图生成image数据,1.0是质量参数
            let pageData = canvas.toDataURL('image/jpeg', 1.0);
            // a4大小
            let PDF = new JsPDF('', 'pt', 'a4');
            // 当内容达到a4纸的高度时,分割,将一整块画幅分割出一页页的a4大小,导出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();
                    }
                }
            }
            // 导出
            PDF.save(title + '.pdf');
            resolve(true);
        })
            .catch(() => {
                reject(false);
            });
    });
};
export default getPdf;

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

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

相关文章

电压放大器在管道缺陷检测中应用有哪些

管道是一种重要的输送工业介质的设施&#xff0c;广泛应用于石油、化工、水利等领域。然而&#xff0c;由于长期使用和外界环境因素等原因&#xff0c;管道内部常会出现各种缺陷和损伤&#xff0c;如腐蚀、裂纹、磨损等&#xff0c;这些问题如果得不到及时发现和修复&#xff0…

基于vue实现权限控制,动态渲染菜单栏

Vue菜单权限动态路由 实现原理&#xff1a;用户登录&#xff0c;服务端返回相关权限&#xff0c;进行持久化存储&#xff0c;筛选动态路由&#xff0c;同时菜单栏也需动态渲染 静态路由 静态路由&#xff0c;也叫常量路由&#xff0c;即所有角色都可以访问到的路由界面。如:…

手把手移植 simpleFOC (二)

目录 前言 1、建立 arduino文件夹&#xff0c;如图&#xff1a; 2、提取必要的文件 二、修改源码 1.屏蔽arduino.h、wiring.h里代码 2.修改Print.cpp文件 三&#xff0c;编译 总结 一、前言 本章主要实现 simpleFoc 里的 Serial.print功能&#xff0c;建立setup、loop函…

Games101学习笔记 - 变换矩阵基础

二维空间下的变换 缩放矩阵 缩放变换: 假如一个点&#xff08;X,Y&#xff09;。x经过n倍缩放&#xff0c;y经过m倍缩放&#xff0c;得到的新点&#xff08;X1&#xff0c;Y1&#xff09;&#xff1b;那么新点和远点有如下关系&#xff0c;X1 n*X, Y1 m*Y写成矩阵就是如下…

Matlab----下载和安装教程

Matlab----下载 文件中有以下文件 Matlab----安装 步骤1&#xff1a;打开安装软件 步骤2&#xff1a;运行安装软件 在matlab 2018的文件夹下找到setup&#xff0c;选中右键以管理员身份运行。 步骤3 选择使用文件安装密钥&#xff0c;然后点击下一步。 步骤4 是否接收…

C语言---动态内存管理

C语言—动态内存管理 文章目录 C语言---动态内存管理1. 为什么要进行动态内存分配1.1 动态内存管理所在的区域 2. 动态内存函数的介绍2.1 malloc2.1.1 malloc语法2.1.2 malloc具体实例 2.2 free2.2.1 free语法2.2.2 free具体实例 2.3 calloc2.3.1 calloc语法2.3.2 calloc具体实…

基于Linux操作系统中的MySQL数据库SQL语句(三十一)

MySQL数据库SQL语句 目录 一、SQL语句类型 1、DDL 2、DML 3、DCL 4、DQL 二、数据库操作 1、查看 2、创建 2.1、默认字符集 2.2、指定字符集 3、进入 4、删除 5、更改 6、练习 三、数据表操作 &#xff08;一&#xff09;数据类型 1、数值类型 1.1、TINYINT …

【C++】总结3

文章目录 1.类的访问限定符2.封装3.类对象的存储方式4.为什么要进行内存对齐&#xff1f;结构体怎么对齐&#xff1f;5.如何让结构体按照指定的对齐参数进行对齐6.如何知道结构体中某个成员相对于结构体起始位置的偏移量7.C有哪几种构造函数8.类的六个默认成员函数9.构造函数10…

web-xss

HTML的< >&amp;&quot;©分别是<&#xff0c;>&#xff0c;&&#xff0c;"&#xff0c;©;的转义字符 XML只有5个转义符: < >&amp; &quot; &apos; HTTP请求中&#xff0c;Referer是header的一部分&#xff0c;当浏览器…

【防火墙】iptables防火墙(二)

1.写在命令行的备份和还原 2.把我们的规则配置在服务的文件当中&#xff0c;形成永久生效 iptables-save > /opt/ky30.bak iptables-restore < /opt/ky30.bak cat /etc/sysconfig/iptables 永久生效的配置文件 自定义链&#xff1a; 1.创建自定义链&#xff1a; i…

【数据结构】---时间复杂度与空间复杂度

时间复杂度与空间复杂度 1.&#x1f4c9; 时间复杂度&#x1f4cc;1.1 时间复杂度的概念1.2 大O的渐进表示法 &#x1f3f0;空间复杂度&#x1f4c3;例题分析1.案例&#xff08;常数阶&#xff09;2.案例&#xff08;线性阶&#xff09;3.案例&#xff1a;&#xff08;平方阶&a…

香港中文大学多媒体实验室——人工智能与计算机视觉的创新引擎

原创 | 文 BFT机器人 01 引言 香港中文大学多媒体实验室&#xff08;MultimediaLaboratory&#xff09;成立于2001年7月&#xff0c;是香港中文大学信息工程学系的重要组成部分。该实验室由汤晓鸥教授执导&#xff0c;是最早应用深度学习进行计算机视觉研究的华人团队之一。因…

Latex | 将MATLAB图并导入Latex中的方法

一、问题描述 用Latex时写paper时&#xff0c;要导入MATLAB生成的图进去 二、解决思路 &#xff08;1&#xff09;在MATLAB生成图片的窗口中&#xff0c;导出.eps矢量图 &#xff08;2&#xff09;把图上传到overleaf的目录 &#xff08;3&#xff09;在文中添加相应代码 三…

麒麟v10-coredns 启动失败

现象 在麒麟ARM芯片的机器上搭建k8s&#xff0c;其中的的一个组件cordons 发现启动失败&#xff0c;查看日志如下所示&#xff1a;No such device or address 问题分析 期初猜测kubelet与containerd的cgroupDriver驱动不一致导致。分别查看是一致的。没有问题。发现系统存在…

阿里云NVIDIA A100 GPU云服务器性能详解及租用费用

阿里云GPU服务器租用费用表包括包年包月、一个小时收费以及学生GPU服务器租用费用&#xff0c;阿里云GPU计算卡包括NVIDIA V100计算卡、T4计算卡、A10计算卡和A100计算卡&#xff0c;GPU云服务器gn6i可享受3折&#xff0c;阿里云百科分享阿里云GPU服务器租用表、GPU一个小时多少…

javafx拖拽图片实现

效果 代码 package cn.juhe.zjsb.test;import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; import javaf…

jmeter接口自动化测试工具在企业开展实际的操作

在企业使用jmeter开展实际的接口自动化测试工具&#xff0c;建议按如下操作流程&#xff0c; 可以使整个接口测试过程更规范&#xff0c;更有效。 接口自动化的流程&#xff1a; 1、获取到接口文档&#xff1a;swagger、word、excel ... 2、熟悉接口文档然后设计测试用例&am…

SAFe工具,SAFe规模化敏捷工具,SAFe实施流程,SAFe框架管理工具

​Leangoo领歌敏捷工具覆盖了敏捷项目研发全流程&#xff0c;包括小型团队敏捷开发&#xff0c;Scrum of Scrums大规模敏捷。 随着SAFe的越来越普及&#xff0c;Leangoo本次上线提供了完整的SAFe框架功能&#xff0c;包括&#xff1a;Program Backlog&#xff0c;PI规划&#…

Linux相关指令(上)

常见指令&#xff1a; 1 pwd&#xff1a;查看用户当前所在目录 以下面的路径为例&#xff1a; 2 ls&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。 对于文件&#xff0c;将列出文件名以及其他信息 ls-l&#xff08;or ll&#xff09;&#xff1a;列…

插槽slot复习

1.认识插槽 ◼ 在开发中&#xff0c;我们会经常封装一个个可复用的组件&#xff1a;  前面我们会通过props传递给组件一些数据&#xff0c;让组件来进行展示&#xff1b;  但是为了让这个组件具备更强的通用性&#xff0c;我们不能将组件中的内容限制为固定的div、span等等…