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文件,然后保存到本地。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值