vue将页面导出pdf,vue导出pdf ,使用html2canvas和jspdf组件

vue导出pdf

需求:需要前端下载把当前html下载成pdf文件–有十八页超长,之前使用vue-html2pdf组件,但是这个组件有长度限制和比较新浏览器版本限制,所以改成使用html2canvas和jspdf组件
方法:
1、第一步:我们要添加两个模块

//第一个:将页面html转换成图片
npm install --save html2canvas
//第二个:将图片生成pdf
npm install jspdf --save

2、第二步:在.vue界面编写,例如我的页面叫BusinessAnalysis.vue,必须在你想要下载的父级加一个id,例如我下面代码 id=“html2PdfId”

<template>
<div ref="ananysisPageRef" class="business-analysis-wrap" ><div  id="html2PdfId">//=====这里是你自己写的想转成pdf的代码</div><a-buttontype="primary":loading="exportLoading"@click="handleExportAI2()">导出PDF</a-button>
</div>
</template>
<script>
import VueHtml2pdf from 'vue-html2pdf'
import html2canvas from 'html2canvas'
export default {
name: 'BusinessAnalysis',
data() {return {pdfOptions: {pageWidth: 594, // A2横向宽度(mm)pageHeight: 420, // A2横向高度(mm)imageQuality: 0.8,},exportLoading: false,pdfBase64: '',base64Images: [],}}methods: {handleExportAI2() {this.$message.loading({ content: '导出PDF文件中...', key: 'exportPagePdfLoading' })this.exportLoading = truethis.generatePDF() // 生产pdf base64 --物业经营分析2},async generatePDF() {const startTime = performance.now()try {await this.$nextTick()// 1. 定义要截图的元素ID(按顺序)// 2. 截图所有元素并计算高度const elements = await this.captureComponents1()console.log('elements', elements)const img = await this.loadImage(elements[0])// this.restoreAfterCapture();// 3. 创建PDF并智能分页const pdf = new JsPDF({orientation: 'l',unit: 'mm',format: [this.pdfOptions.pageWidth, this.pdfOptions.pageHeight],// format: 'a4',// compress: true})// 计算分页参数:ml-citation{ref="6,8" data="citationList"}const imgRatio = img.width / img.heightconst scaledWidth = this.pdfOptions.pageWidthconst scaledHeight = scaledWidth / imgRatioconst totalPages = Math.ceil(scaledHeight / this.pdfOptions.pageHeight)// 分页渲染:ml-citation{ref="5,8" data="citationList"}for (let i = 0; i < totalPages; i++) {if (i > 0) pdf.addPage()const canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')// 计算截取区域:ml-citation{ref="6,8" data="citationList"}const sliceHeight = (img.height * this.pdfOptions.pageHeight) / scaledHeightconst startY = i * sliceHeightconst isLastPage = i === totalPages - 1const currentSliceHeight = isLastPage ? img.height - startY : sliceHeight// 设置画布尺寸:ml-citation{ref="3,5" data="citationList"}canvas.width = img.widthcanvas.height = currentSliceHeight// 绘制图片分段:ml-citation{ref="5,6" data="citationList"}ctx.drawImage(img,0,startY, // 源坐标img.width,currentSliceHeight, // 源尺寸0,0, // 目标坐标canvas.width,canvas.height // 目标尺寸)// 计算PDF中的显示高度:ml-citation{ref="6,8" data="citationList"}const displayHeight = isLastPage? (currentSliceHeight * this.pdfOptions.pageWidth) / img.width: this.pdfOptions.pageHeightpdf.addImage(canvas, 'JPEG', 0, 0, this.pdfOptions.pageWidth, displayHeight, undefined, 'FAST')canvas.width = 1canvas.height = 1}this.exportLoading = falsethis.$message.success({ content: '导出成功!', key: 'exportPagePdfLoading', duration: 1 })pdf.save('物业经营小项目分享.pdf')} catch (error) {console.error('生成PDF失败:', error)alert('生成PDF失败: ' + error.message)} finally {this.isGenerating = false}},loadImage(base64) {return new Promise((resolve, reject) => {const img = new Image()img.onload = () => resolve(img)img.onerror = rejectimg.src = base64})},async captureComponents1() {// 确保DOM更新完成(针对Vue的动态渲染)await this.$nextTick()const elements = [document.getElementById('html2PdfId')]const base64Images = []// 顺序截图(避免并行导致内存溢出)for (const element of elements) {// 分块截图try {const canvas = await html2canvas(element, {useCORS: true, // 允许跨域资源logging: false, // 关闭日志backgroundColor: '#FFFFFF', // 设置纯白背景scale: 2, // 提高分辨率(2倍)allowTaint: true, // 禁止污染画布removeContainer: true, // 自动移除临时容器windowWidth: element.scrollWidth,windowHeight: element.scrollHeight,// ignoreElements: (el) => {//   // 过滤不需要渲染的元素//   if (//     el.contains(element) ||//     element.contains(el) ||//     el.tagName === 'STYLE' ||//     el.tagName === 'LINK' ||//     // el.tagName === 'IMG' ||//     el.getAttribute('data-html2canvas') != null // header里面的样式不能筛掉//   ) {//     // console.log(el);//     return false//   }//   // console.log(e.tagName);//   return true// },// dpi: 300})const dataUrl = canvas.toDataURL('image/png', 1.0)base64Images.push(dataUrl)} catch (error) {console.error('截图失败:', element, error)base64Images.push('') // 空值占位}}return base64Images},}
}
</script>

上面基本上是完整的代码,花了九头二虎之力,就是还是会出现截断的情况,我没办法解决,如果有大佬,求大佬指导
在这里插入图片描述
可以下载22页呢,就是下载的时候先截图成图片,再转为pdf很慢,如果有大佬能解决很慢的问题,求指导

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

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

相关文章

024 企业客户管理系统技术解析:基于 Spring Boot 的全流程管理平台

企业客户管理系统技术解析&#xff1a;基于Spring Boot的全流程管理平台 在企业数字化转型的浪潮中&#xff0c;高效的客户管理系统成为提升企业竞争力的关键工具。本文将深入解析基于Java和Spring Boot框架构建的企业客户管理系统&#xff0c;该系统涵盖员工管理、客户信息管…

JavaScript性能优化代码示例

JavaScript性能优化实战大纲 性能优化的核心目标 减少加载时间、提升渲染效率、降低内存占用、优化交互响应 代码层面的优化实践 避免全局变量污染&#xff0c;使用局部变量和模块化开发 减少DOM操作频率&#xff0c;批量处理DOM更新 使用事件委托替代大量事件监听器 优化循…

树的重心(双dfs,换根)

思路&#xff1a; 基于树形 DP 的两次遍历&#xff08;第一次dfs计算以某个初始根&#xff08;这里选了 1&#xff09;为根时各子树的深度和与节点数&#xff0c;第二次zy进行换根操作&#xff0c;更新每个节点作为根时的深度和&#xff09; 换根原理&#xff1a; 更换主根&…

官方App Store,直链下载macOS ,无需Apple ID,macOS10.10以上.

前言 想必很多人都有过维修老旧Mac的体验,也有过想要重装macos的体验. 尤其是前者,想要重装或者升级系统,由于官方已经无法更新,必须下载iSo镜像 这时就会遇到死循环:想要更新macOS ,必须先使用更高版本的App Store,但要使用更高版本的App Store,必须先更新macOS !!! 如果想…

芋道生成前端界面代码详解

一、搜索框 1、整体架构 <ContentWrap> ... </ContentWrap><ContentWrap> 是页面布局容器&#xff08;可能是自定义组件&#xff09;&#xff0c;包裹住页面的内容区域。 2、el-form 表单&#xff08;搜索区域&#xff09; 2.1参数 <el-formclass&quo…

小程序入门:推广技巧与运行数据查看解析

在当今数字化时代&#xff0c;小程序的应用愈发广泛&#xff0c;无论是企业还是个人开发者&#xff0c;都希望自己的小程序能够获得更多用户关注并顺利运行。本文将详细介绍小程序发布的流程、推广策略以及如何查看运行数据&#xff0c;助力开发者更好地运营小程序。 一、小程…

sql server 将nvarchar长度设置成max有什么隐患

在学习 SQL Server 的过程中&#xff0c;很多开发者会选择将 NVARCHAR 字段的长度设置为 MAX&#xff0c;以便于存储大量文本数据。虽然这样的设计在某些情况下可能会带来便利&#xff0c;但却潜藏着诸多隐患。本文将通过步骤性指导&#xff0c;帮助你理解这些隐患及其解决方式…

电商数据爬取实战:如何挖掘隐藏的商业价值 ||电商API接口的应用价值

当你在深夜浏览电商平台&#xff0c;目光被那些标注着“月销10万”的商品所吸引时&#xff0c;你是否曾思考过——这些惊人的数字背后隐藏着怎样的商业秘密&#xff1f;今天&#xff0c;就让我们化身为电商数据猎手&#xff0c;挥舞起爬虫这把锋利的手术刀&#xff0c;精心解剖…

​​MQTT​​通讯:​​物联网

​​MQTT​​通讯&#xff1a; ​​物联网&#xff08;IoT&#xff09;​​&#xff1a;传感器数据上报&#xff08;温度、湿度&#xff09;、智能家居设备控制。 ​​弱网络环境​​&#xff1a;移动网络、卫星通信&#xff08;如远程农业监测&#xff09;。 ​​云端集成​​…

swagger访问不了的解决方案 http://localhost:8080/swagger-ui/index.html

确保增加 swagger 依赖 pom.xml <!-- Swagger --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.5.0</version></dependency> 在浏览器打开…

在 .NET Core WebAPI 项目中,执行文件(.exe)方式运行并指定端口

✅ 方法一&#xff1a;使用命令行指定端口 .NET Core WebAPI 项目默认使用 Kestrel Web 服务器&#xff0c;你可以通过环境变量或命令行参数来覆盖默认监听地址和端口。 示例命令&#xff1a; MyApi.exe --urls "http://localhost:5001"或者绑定所有主机地址&…

前缀树进阶-经典案例详解

前缀树进阶-经典案例详解 一、前缀树基础内容回顾二、单词搜索建议系统2.1 问题描述2.2 解题思路2.3 Java代码实现2.4 复杂度分析 三、单词编码3.1 问题描述3.2 解题思路3.3 Java代码实现3.4 复杂度分析 四、最长单词4.1 问题描述4.2 解题思路4.3 Java代码实现4.4 复杂度分析 我…

Redis集群实现方式

✅ 一、什么是 Redis 集群&#xff08;Redis Cluster&#xff09; Redis 集群是 Redis 官方在 3.0 版本引入的分布式部署方案&#xff0c;它的目标是解决以下几个问题&#xff1a; 单个 Redis 实例容量有限&#xff08;最多只能使用一个服务器的内存&#xff09; 单点故障&am…

《中国电信运营商骨干网:历史、现状与未来演进》系列 第五篇:新玩家入局——中国广电CBNNET如何构建全国一张网?

专栏引言 在中国电信、联通、移动三足鼎立的骨干网格局中&#xff0c;一位身负特殊使命的“国家队新兵”正加速入场。它就是中国广电。根据2023年发布的《广电网络融合发展战略》&#xff0c;其核心任务是构建一张“新型广电网络”。手握700MHz“黄金频段”和5G牌照&#xff0c…

QT 国际化 翻译 总结

目录 生成TS文件 单纯Qt Creator工程 生成ts文件方式一&#xff1a;creator方式 生成ts文件方式二&#xff1a;命令行方式 vs2019QT工程 CMake工程 生成qm文件 代码 需要先根据ui产生ts文件&#xff0c;再根据ts文件产生qm文件&#xff0c;然后代码加载 生成TS文件 单…

Java 中实现 Excel 导入一些疑难杂症

在 Java 中实现 Excel 导入功能时&#xff0c;除了已讨论的字段映射、类型转换和内存管理外&#xff0c;还需注意以下关键问题&#xff0c;结合常见踩坑点和最佳实践总结如下&#xff1a; ⚙️ 一、文件与格式校验 文件类型与版本兼容性 明确区分 .xls&#xff08;HSSF&#x…

修改Docker-compose使Uptime-Kuma支持IPV6

之前部署了一个Uptime-Kuma用来监控服务的运行&#xff0c;最近&#xff0c;在监控IPV6网络的时候出现了一点问题&#xff0c;Docker不支持IPV6网络&#xff1a; 解决方案&#xff1a; 修改/etc/docker/daemon.json文件 {"experimental": true,"fixed-cidr-v6&…

分布式存储架构的优势

分布式存储架构通过将数据分散存储在多个物理节点上&#xff0c;在性能、可靠性及成本效益方面展现显著优势&#xff0c;具体核心优势如下&#xff1a; 一、‌弹性扩展能力‌ 水平无缝扩容‌ 通过添加节点即可线性扩展存储容量与性能&#xff0c;支持EB级数据规模&#xff0…

【4目全景】基于海思3403平台开发4目360°全景拼接相机方案

此文主要介绍基于海思3403平台通过实时视频采集&拼接&融合&显示实现实时全景空间漫游体验&#xff0c;该模组将4路视频拼接成一幅360全景图&#xff0c;涉及到计算机视觉、计算机图形学、数字视频处理等技术。 基本开发步骤主要包括以下几个方面&#xff1a;4路视频…

element-plus 按钮 展开/隐藏

文章目录 1、小记2、页面3、typescript事件4、测试数据5、样式 1、小记 element-plus中el-table 的 expand,箭头控制子项显示&#xff0c;有点丑。 想实现类似bootstrap &#xff0c;用按钮 展开/隐藏子项的功能 2、页面 <!-- 表内容 --><el-table:data"tabl…