jsPDF + html2canvas + Vue3 + ts项目内,分页导出当前页面为PDF、A 页面内导出 B 页面的内容为PDF,隐藏导出按钮等多余元素

jsPDF + html2canvas + Vue3 + ts + Arco Design项目,分页导出当前页面为PDF、A 页面内导出 B 页面的内容为PDF,隐藏导出按钮等多余元素…

1.下载所需依赖

 pnpm install --save html2canvas
 pnpm install --save jspdf
  1. 引入依赖
<script setup lang="ts">
  import html2canvas from 'html2canvas';
  import jsPDF from 'jspdf';
</script>
  1. 页面如下
    在这里插入图片描述

  2. 页面结构(示例代码

  • id=pdfContent,为整个导出区域
  • id=extraElement,为导出时需要隐藏的DOM元素(左上方返回及右上方按钮)
  • handelExportPdf,为右上角“导出PDF”点击导出的事件
// id=pdfContent,为打印区域
 <a-card id="pdfContent" class="general-card">
   <a-row justify="space-between" style="min-height: 32px">
	 // id=extraElement,为打印时需要隐藏的DOM元素
     <div id="extraElement" class="back-btn" @click="router.go(-1)">
       <icon-undo />
       <span style="margin-left: 4px">返回</span>
     </div>
     <div class="middle-title">这是PDF文件的标题</div>
     <a-button id="extraElement" type="primary" @click="handelExportPdf">
       导出PDF
     </a-button>
   </a-row>
   <a-divider />
   <div>
     <a-row class="info" style="margin-bottom: 15px">
       <a-col>
         <span class="label">姓名:</span>
         <span class="value">张三</span>
       </a-col>
       <a-col>
         <span class="label">性别:</span>
         <span class="value"></span>
       </a-col>
       <a-col>
         <span class="label">年龄:</span>
         <span class="value">18</span>
       </a-col>
     </a-row>
   </div>
 </a-card>
  1. 分页。设置好每一页PDF的高度,然后canvas的高度一页一页剪掉再分别添加,相关代码在下面第九步写出
  2. 隐藏多余元素(左上方返回及右上方按钮)
const extraElementStyle = ref();	
// 隐藏元素
extraElementStyle.value = document.querySelectorAll('#extraElement');
extraElementStyle.value.forEach((item: any) => {
  if (item) {
    item.style.display = 'none';
  }
});

隐藏后点击导出,此时页面如下

在这里插入图片描述

  1. 下载PDF文件成功后,上一步隐藏的DOM元素要恢复原装
// 恢复隐藏的元素
extraElementStyle.value.forEach((item: any) => {
  if (item) {
    item.style.display = 'block';
  }
});
  1. 整体方法(相关解释在注释)
 //获取需要的DOM元素
 const element = ref();
 const extraElementStyle = ref();

 // 执行导出方法
 const handelExportPdf = () => {
   element.value = document.getElementById('pdfContent');
   // 隐藏或删除不需要的元素
   extraElementStyle.value = document.querySelectorAll('#extraElement');
   extraElementStyle.value.forEach((item: any) => {
     if (item) {
       item.style.display = 'none';
     }
   });
   // 为了保证显示质量,1.5倍PDF尺寸(数值越大,显示质量越好,但文件越大)
   const scale = 1.5;
   // 获取 HTML 元素的原始宽度,如果获取不到,则设置默认宽度为 700
   const originWidth = element.value.offsetWidth || 700;
   // 算生成 PDF 所需的宽度,这里将原始宽度增加了 20
   const width = originWidth + 20;
   // 计算生成 PDF 的最终宽度、高度
   const PDF_WIDTH = width * scale;
   const PDF_HEIGHT = width * 1.414 * scale;
   // 将元素转换为canvas对象
   html2canvas(element.value, {
     scale,
   }).then((canvas) => {
 	 // 获取 Canvas 对象的宽度、高度
     const contentWidth = canvas.width;
     const contentHeight = canvas.height;
     // 一页pdf显示页面生成的canvas高度
     // canvas图像在画布上的尺寸
     const pageHeight = (contentWidth / PDF_WIDTH) * PDF_HEIGHT;
     const imgWidth = PDF_WIDTH;
     const imgHeight = (PDF_WIDTH / contentWidth) * contentHeight;
     // 初始化剩余未插入 PDF 的 Canvas 高度为 Canvas 的总高度
     let leftHeight = contentHeight;
     // 初始化插入 PDF 的位置为 0
     let position = 0;
     // eslint-disable-next-line new-cap
     const pdf = new jsPDF('p', 'px', [PDF_WIDTH, PDF_HEIGHT]);
     // 判断剩余未插入 PDF 的高度是否小于一页 PDF 的高度,如果是,则代表剩余内容不足一页,直接将 Canvas 图像添加到 PDF 中
     if (leftHeight < pageHeight) {
       pdf.addImage(canvas, 'PNG', 0, 0, imgWidth, imgHeight);
     } else {
       // 多页
       while (leftHeight > 0) {
         // 将 Canvas 图像添加到 PDF 中,指定图像的位置和尺寸
         pdf.addImage(canvas, 'PNG', 0, position, imgWidth, imgHeight);
         // 更新剩余未插入 PDF 的高度
         leftHeight -= pageHeight;
         // 更新下一页插入 PDF 的位置
         position -= PDF_HEIGHT;
         // 如果还有剩余内容未插入 PDF,添加新的页面,避免添加空白页
         if (leftHeight > 0) {
           pdf.addPage();
         }
       }
     }
     // 保存PDF文件
     pdf.save('演练报告.pdf');
     // 恢复隐藏的元素
     extraElementStyle.value.forEach((item: any) => {
       if (item) {
         item.style.display = 'block';
       }
     });
     Message.success('导出成功');
   });
 };
  1. 导出文件如下
  • 浏览器内
    在这里插入图片描述
  • office内
    在这里插入图片描述
  1. 如果是想实现在A 页面内点击“导出”,随即导出 B 页面的内容为PDF:可以使用 Vue Router 将 A 页面和 B 页面分别定义为两个路由,并在 A 页面中使用路由导航跳转到 B 页面,在 B 页面中,页面加载完成后使其自动调用导出方法导出 PDF文件,然后保存到本地。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript —— APIs(五)

一、Window对象 1. BOM&#xff08;浏览器对象模型&#xff09; 2. 定时器-延时函数 ①、定义 ②、定时器比较 ③、【案例】 3. JS执行机制 4. location对象 注意&#xff1a;hash应用 不点击页面刷新号&#xff0c;点击刷新按钮也可以实现页面刷新 【案例】 5. navig…

WAF防火墙可以给您解决什么问题?哪些情况下使用WAF最适合?

一、什么是WAF&#xff1f; Web应用防护系统&#xff08;也称为&#xff1a;网站应用级入侵防御系统。英文&#xff1a;Web Application Firewall&#xff0c;简称&#xff1a;WAF&#xff09;。利用国际上公认的一种说法&#xff1a;Web应用防火墙是通过执行一系列针对HTTP/H…

Occlum原理解析及使用说明

目录 一、设计初衷 二、背景知识 1.什么是可信计算 2.什么是TEE 3.传统SGX SDK的问题 三、Occlum 1.如何使用 2.特点 3.如何使用 1.Docker部署 1 硬件支持 2 环境 3 拉取镜像创建虚机 4 简单验证 4.Occlum中gcc编译 1 交叉编译 2 初始化Occlum实例 3 Occlum构…

如何更好的使用cpm

nvidia发布了RAFT库&#xff0c;支持向量数据库的底层计算优化&#xff0c;RAFT 也使用CMake Package Manager( CPM )和rapids-cmake管理项目&#xff0c;可以方便快捷的下载到需要的对应版本的thirdparty的依赖库&#xff0c;但是&#xff0c;一般情况下&#xff0c;项目是直接…

数据库复习1

1.试述数据、数据库、数据库管理系统、数据库系统的概念 1.数据(Data): 数据是关于事物的符号表示或描述。它可以是任何事实、观察或者测量的结果&#xff0c;如数字、字符、声音、图像等。数据在没有上下文的情况下可能没有明确的意义。 2.数据库(Database): 数据库是一个持…

面试题:集合篇

说说 List, Set, Queue, Map 四者的区别&#xff1f; List(对付顺序的好帮手): 存储的元素是有序的、可重复的。Set(注重独一无二的性质): 存储的元素是无序的、不可重复的。Queue(实现排队功能的叫号机): 按特定的排队规则来确定先后顺序&#xff0c;存储的元素是有序的、可重…

传输层协议 TCP UDP协议 解析(二)

文章目录 UDP&#xff1a;用户数据报协议UDP报文格式TCP与UDP的区别 UDP&#xff1a;用户数据报协议 UDP是一种面向无连接的传输层协议&#xff08;数据一直发送&#xff0c;没有ack&#xff0c;所以不需要考虑ack&#xff09;&#xff0c;传输可靠性没有保证。 UDP不提供重传…

Rust 实战thiserror+自定义错误消息体

导航 一、背景二、实践1、导入thiserror2、自定义错误消息体&#xff08;1&#xff09;创建ErrMsg.rs和创建自定义结构体&#xff08;2&#xff09;lib.rs添加ErrMsg&#xff08;3&#xff09;main函数&#xff08;4&#xff09;完整代码 一、背景 开发中遇到需要通用、能够满…

Note-backbone预训练权重对模型收敛速度的影响和mmlab实验测试

简介 在训练一些复杂模型时候&#xff0c;通常会考虑读取backbone的预训练权重&#xff0c;这种方法有以下好处&#xff1a; 初始化网络参数&#xff1a;在深度学习模型训练过程中&#xff0c;通常需要随机初始化神经网络的参数。然而&#xff0c;如果采用Backbone预训练权重进…

拼多多不花钱推广能做起来吗

拼多多推广可以使用3an推客。3an推客&#xff08;CPS模式&#xff09;给商家提供的营销工具&#xff0c;由商家自主设置佣金比例&#xff0c;激励推广者去帮助商家推广商品链接&#xff0c;按最终有效交易金额支付佣金&#xff0c;不成交不扣费。是商家破零、积累基础销量的重要…

背景音乐广播系统解决方案

背景音乐广播系统解决方案18123651365 在公共广播背景音乐系统虽然是一个小小分支&#xff0c;但是却与人们的生活质量直接挂钩&#xff0c;如早晨时间&#xff0c;可以通过播放一些愉快的音乐&#xff0c;使得住宅居名、上班一族和晨运一族有一个愉快的心情&#xff0c;精神抖…

《QT实用小工具·五十六》自适应界面变化的控件

1、概述 源码放在文章末尾 该项目实现了网格显示多张带文字的图片在界面中自适应布局 特点 跟随窗口大小变换位置&#xff0c;并带移动动画 响应鼠标事件&#xff0c;图片缩放动画 点击水波纹动画 项目demo演示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #i…

剖析QMS质量管理系统:推动企业效益提升的关键因素

质量管理系统&#xff08;QMS&#xff09;是企业管理中至关重要的一环&#xff0c;它涵盖了组织的所有流程和活动&#xff0c;并旨在提高产品和服务的质量。通过实施和运营一个有效的QMS&#xff0c;企业能够不断改进其业务&#xff0c;满足客户需求&#xff0c;提高竞争力&…

书生浦语第三节茴香豆:搭建你的RAG智能助理笔记

RAG&#xff08;Retrieval Augmented Generation&#xff09;是一项通过检索与用户输入相关的信息片段&#xff0c;并结合外部知识库来生成更准确、更丰富的回答的技术。解决 LLMs 在处理知识密集型任务时可能遇到的挑战, 如幻觉、知识过时和缺乏透明、可追溯的推理过程等。提供…

4月威胁态势 | 0day占比82%!Polyransom勒索家族强势来袭

近日&#xff0c;亚信安全正式发布《2024年4月威胁态势报告》&#xff08;以下简称“报告”&#xff09;&#xff0c;报告显示&#xff0c;4月份新增安全漏洞1260个&#xff0c;涉及0day漏洞占82%&#xff1b;监测发现当前较活跃的勒索病毒家族是Polyransom和Blocker&#xff0…

SPI思想机制

目录 如何解释简单概括SPI 和 APISPI 实现原理&#xff08;重要-线程上下文类加载器&#xff09; 如何使用一个Demo功能介绍使用效果&#xff08;直接在本地模拟服务商提供服务&#xff09;使用效果&#xff08;通过 jar 的方式引入&#xff09; 应用分析参考文章 如何解释 简…

Docker容器:Docker-Consul的容器服务更新与发现

目录 前言 一、什么是服务注册与发现 二、 Docker-Consul 概述 1、Consul 概念 2、Consul 提供的一些关键特性 3、Consul 的优缺点 4、传统模式与自动发现注册模式的区别 4.1 传统模式 4.2 自动发现注册模式 5、Consul 核心组件 5.1 Consul-Template组件 5.2 Consu…

Blazor流程编排的艺术:深入Z.Blazor.Diagrams库的使用与实践

合集 - .Net(3)1.基于AntSK与LLamaSharp打造私人定制的离线AI知识库03-032.深入解析&#xff1a;AntSK 0.1.7版本的技术革新与多模型管理策略03-123.Blazor流程编排的艺术&#xff1a;深入Z.Blazor.Diagrams库的使用与实践05-05收起 为现代网页应用开发提供动力的其中一…

招展工作的接近尾声“2024上海国际科技创新展会”即将盛大开幕

2024上海国际科技创新展会&#xff0c;即将于6月中旬在上海新国际博览中心盛大召开。随着招展工作的接近尾声&#xff0c;目前仍有少量余位可供各企业和机构预定。这一盛大的科技展会&#xff0c;将汇聚全球智能科技领域的精英&#xff0c;共同展示最新的科技成果&#xff0c;探…
最新文章