当前位置: 首页 > news >正文

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.lqws.cn/news/544177.html

相关文章:

  • Jmeter并发测试和持续性压测
  • 手机屏亮点缺陷修复及相关液晶线路激光修复原理
  • 利用云雾自动化在智能无人水面航行器中实现自主碰撞检测和分类
  • UI前端大数据处理实战技巧:如何有效应对数据延迟与丢失?
  • PILCO: 基于模型的高效策略搜索方法原理解析
  • HarmonyOS 5智能单词应用开发:记忆卡(附:源码
  • JVM 的 Dump分析以及 GC 日志
  • Vulkan模型查看器设计:相机类与三维变换
  • 【Python数据库】Python连接3种数据库方法(SQLite\MySQL\PostgreSQL)
  • 人工智能-基础篇-4-人工智能AI、机器学习ML和深度学习DL之间的关系
  • 人工智能-基础篇-3-什么是深度学习?(DL,卷积神经网络CNN,循环神经网络RNN,Transformer等)
  • fish安装node.js环境
  • 【CMake基础入门教程】第八课:构建并导出可复用的 CMake 库(支持 find_package() 查找)
  • 视觉疲劳检测如何优化智能驾驶的险情管理
  • Java练习题精选16-20
  • C++01背包问题
  • 汇总表支持表头分组,查询组件查询框可以调整高度,DataEase开源BI工具v2.10.11 LTS版本发布
  • ESP32 008 MicroPython Web框架库 Microdot 实现的网络文件服务器
  • A Machine Learning Approach for Non-blind Image Deconvolution论文阅读
  • 金蝶云星空客户端自定义控件插件-WPF实现自定义控件
  • 电磁波是如何传递信息的?
  • 鸿蒙 List 组件解析:从基础列表到高性能界面开发指南
  • 前端 E2E 测试实践:打造稳定 Web 应用的利器!
  • 海外 AI 部署:中国出海企业如何选择稳定、安全的云 GPU 基础设施?
  • 扬州搓澡非遗解码:三把刀文化的“水包皮“
  • 010 【入门】链表入门题目-合并两个有序链表
  • Linux驱动学习day9(异常与中断处理)
  • 华为云Flexus+DeepSeek征文|基于Dify构建故事绘本制作工作流
  • Spark 写入hive表解析
  • Spring Boot项目开发实战销售管理系统——系统设计!