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

VUE页面导出PDF方案

1,技术方案为:html2canvas把页面生成canvas图片,再通过jspdf生成PDF文件;

2,安装依赖:

npm i html2canvas -S
npm i jspdf -S

3,封装导出pdf方法exportPdf.js:

// 页面导出为pdf格式 //title表示为下载的标题,html表示document.querySelector('#myPrintHtml')
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';let noTableHeight = 0; //table外的元素高度
export function pageToPDF(title, html, lableList, type) {// type传有效值pdf则为横版if (lableList) {const pageHeight = Math.floor((277 * html.scrollWidth) / 190) + 20; //计算pdf高度for (let i = 0; i < lableList.length; i++) {//循环获取的元素const multiple = Math.ceil((lableList[i].offsetTop + lableList[i].offsetHeight) / pageHeight); //元素的高度if (isSplit(lableList, i, multiple * pageHeight)) {//计算是否超出一页var _H = ''; //向pdf插入空白块的内容高度if (lableList[i].localName !== 'tr') {//判断是不是表格里的内容_H = multiple * pageHeight - (lableList[i].offsetTop + lableList[i].offsetHeight);} else {_H = multiple * pageHeight - (lableList[i].offsetTop + lableList[i].offsetHeight + noTableHeight) + 20;}var newNode = getFooterElement(_H); //向pdf插入空白块的内容const divParent = lableList[i].parentNode; // 获取该div的父节点const next = lableList[i].nextSibling; // 获取div的下一个兄弟节点// 判断兄弟节点是否存在if (next) {// 存在则将新节点插入到div的下一个兄弟节点之前,即div之后divParent.insertBefore(newNode, next);} else {// 否则向节点添加最后一个子节点divParent.appendChild(newNode);}}}}html2Canvas(html, {allowTaint: false,taintTest: false,logging: false,useCORS: true,dpi: window.devicePixelRatio * 1,scale: 1, // 按比例增加分辨率}).then(canvas => {var pdf = new JsPDF('p', 'mm', 'a4'); // A4纸,纵向var ctx = canvas.getContext('2d');var a4w = type ? 277 : 190;var a4h = type ? 190 : 277; // A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277var imgHeight = Math.floor((a4h * canvas.width) / a4w); // 按A4显示比例换算一页图像的像素高度var renderedHeight = 0;while (renderedHeight < canvas.height) {var page = document.createElement('canvas');page.width = canvas.width;page.height = Math.min(imgHeight, canvas.height - renderedHeight); // 可能内容不足一页// 用getImageData剪裁指定区域,并画到前面创建的canvas对象中page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0);pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4w, Math.min(a4h, (a4w * page.height) / page.width)); // 添加图像到页面,保留10mm边距renderedHeight += imgHeight;if (renderedHeight < canvas.height) {pdf.addPage(); // 如果后面还有内容,添加一个空页}// delete page;}// 保存文件pdf.save(title + '.pdf');});
}
// pdf截断需要一个空白位置来补充
function getFooterElement(remainingHeight, fillingHeight = 0) {const newNode = document.createElement('div');newNode.style.background = '#ffffff';newNode.style.width = 'calc(100% + 8px)';newNode.style.marginLeft = '-4px';newNode.style.marginBottom = '0px';newNode.classList.add('divRemove');newNode.style.height = remainingHeight + fillingHeight + 'px';return newNode;
}
function isSplit(nodes, index, pageHeight) {// 判断是不是tr 如果不是高度存起来// 表格里的内容要特殊处理// tr.offsetTop 是tr到table表格的高度// 所以计算高速时候要把表格外的高度加起来// 生成的pdf没有表格了这里可以不做处理 直接计算就行if (nodes[index].localName !== 'tr') {//判断元素是不是trnoTableHeight += nodes[index].clientHeight;}if (nodes[index].localName !== 'tr') {return (nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight &&nodes[index + 1] &&nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight);} else {return (nodes[index].offsetTop + nodes[index].offsetHeight + noTableHeight < pageHeight &&nodes[index + 1] &&nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight + noTableHeight > pageHeight);}
}

4,调用方式及页面id和class值添加,添加class="pdf-details"是为了处理分页隔断:

function downloadPdf() {const lableList = document.getElementsByClassName('pdf-details');pageToPDF('降雨结论报告', document.querySelector('#rainReport'), lableList);}

相关文章:

VUE页面导出PDF方案

1&#xff0c;技术方案为&#xff1a;html2canvas把页面生成canvas图片&#xff0c;再通过jspdf生成PDF文件&#xff1b; 2&#xff0c;安装依赖&#xff1a; npm i html2canvas -S npm i jspdf -S 3&#xff0c;封装导出pdf方法exportPdf.js: // 页面导出为pdf格式 //titl…...

机器学习笔记 - WGAN生成对抗网络概述和示例

一、简述 Wasserstein GAN或WGAN是一种生成对抗网络,它最小化地球移动器距离 (EM) 的近似值,而不是原始 GAN 公式中的 Jensen-Shannon 散度。与原始 GAN 相比,它的训练更加稳定,模式崩溃的证据更少,并且具有可用于调试和搜索超参数的有意义的曲线。 Wasserstein 生成对抗网…...

HoudiniVex笔记_P0_Houdini中文文档与翻译

1、19.0版本中文说明文档 链接&#xff1a;https://pan.baidu.com/s/1oJcX5pdnBZ_YWWwOSnFB5g?pwdz3tw 提取码&#xff1a;z3tw 2、翻译插件 有上网条件的同学可以试试这个翻译插件&#xff1a;双语网页翻译 - 电子书翻译 - PDF翻译 - 字幕文件翻译浏览器扩展 | 沉浸式翻译…...

基于PowerWord的储能在主动配电网中的仿真研究

摘要 主动配电网是智能配电网技术发展的高级阶段&#xff0c;分布式储能是主动配电网的重要组成部分&#xff0c;分布式储能的应用对主动配电网的规划、运行、网络拓扑、故障处理和保护、可再生能源电源的协调优化等方面带来不容忽视的影响&#xff0c;针对这一现状&#xff0c…...

并查集与最小生成树

并查集 HDOJ-1232 畅通工程 题目&#xff1a; 省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通&#xff0c;输入现有城镇道路统计表&#xff08;表中列出了每条道路直接连通的城镇&#xff09;&#xff0c;求最少还需要建设的道路数量。&#xff08;城镇从1到…...

平面运动机器人的传感器外参标定

简述 对任意两个传感器进行外参标定可以采用手眼标定算法来完成&#xff0c;但是&#xff0c;传统手眼标定算法对于运动具有一定的要求&#xff0c;可以证明&#xff0c;至少需要两个以上轴角方向不同的旋转运动才可以正确估计出外参旋转&#xff0c;因此&#xff0c;如果使用…...

【星海随笔】SDN neutron (二) Neutron-plugin(ML2)

Neutron架构之Neutron-plugin Core-plugin(ML2)篇 Neutron-server接收两种请求&#xff1a; REST API请求&#xff1a;接收REST API请求&#xff0c;并将REST API分发到对应的Plugin&#xff08;L3RouterPlugin&#xff09;。 RPC请求&#xff1a;接收Plugin agent请求&#…...

野火i.MX6ULL开发板检测按键evtest(Linux应用开发)

之前一直查找不到evtest&#xff0c;因为没有下载成功&#xff0c;很可能是网络不好&#xff0c;下次可以软件源可以换成国内大学镜像网站。 重新断开板子电源启动&#xff0c;再次连接网络&#xff0c;下载evtest成功&#xff01;&#xff01;...

k8s存储

nfs 理论上nfs 其实并不是存储设备&#xff0c;它是一种远程共享存储服务。 k8s 存储卷 volume emptyDir&#xff1a;可以实现pod中的容器之间共享数据&#xff0c; 但是存储卷不能持久化数据&#xff0c;且会随着pod的生命周期一起删除。 hostpash&#xff1a;可以实现持久…...

数据分析实战 | 贝叶斯分类算法——病例自动诊断分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 八、模型评价 九、模型调参 十、模型预测 一、数据及分析对象 CSV文件——“bc_data.csv” 数据集链接&#xff1a;https://download.csdn.net/d…...

实用技巧:嵌入式人员使用http服务模拟工具模拟http服务器测试客户端get和post请求

文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/134305752 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…...

P9836 种树

容易想到分解因数。 对于一个数 p p p 的因数个数&#xff0c;假设它可以被分解质因数成 a 1 i 1 a 2 i 2 a 3 i 3 ⋯ a k c k a_1^{i_1} a_2^{i_2} a_3^{i_3}\cdots a_k^{c_k} a1i1​​a2i2​​a3i3​​⋯akck​​ 的形式&#xff0c;则其因数个数为 ( i 1 1 ) ( i 2 1 )…...

C# 查询腾讯云直播流是否存在的API实现

应用场景 在云考试中&#xff0c;为防止作弊行为的发生&#xff0c;会在考生端部署音视频监控系统&#xff0c;当然还有考官方监控墙系统。在实际应用中&#xff0c;考生一方至少包括两路直播流&#xff1a; &#xff08;1&#xff09;前置摄像头&#xff1a;答题的设备要求使…...

JAVA开源项目 于道前端项目 启动步骤参考

1. 安装 启动过程有9个步骤&#xff1a; 1.1 安装 Node JS , V18版本的 &#xff08;安装步骤省略&#xff09; 1.2 安装 npm install -g yarn &#xff0c;node JS里边好像自带npm &#xff0c;通过npm的命令安装 yarn 1.3 切换到项目中去安装&#xff0c;npm install &a…...

深入理解ElasticSearch分片

1. 路由计算 当索引一个文档的时候&#xff0c;文档会被存储到一个主分片中。 Elasticsearch 如何知道一个文档应该存放到哪个分片中呢&#xff1f;当我们创建文档时&#xff0c;它如何决定这个文档应当被存储在分片 1 还是分片 2 中呢&#xff1f;首先这肯定不会是随机的&…...

【Python】AppUI自动化—appium自动化元素定位、元素事件操作(17)下

文章目录 前言一.Appium 元素定位1.定位方式种类2.如何定位2.1 id定位2.2 className定位2.3 content-desc 定位2.4 Android Uiautomator定位4.1 text定位4.2 text模糊定位4.3 text正则匹配定位4.4 resourceId定位4.5 resourceId正则匹配定位4.6 className定位4.7 className正则…...

SpringBoot使用MyBatis多数据源

SpringBoot使用MyBatis多数据源 我们以 Mybatis Xml和注解两种版本为例&#xff0c;给大家展示如何如何配置多数据源。 1、注解方式 数据库文件&#xff1a; DROP TABLE IF EXISTS users; CREATE TABLE users (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键id,userN…...

小程序版本审核未通过,需在开发者后台「版本管理—提交审核——小程序订单中心path」设置订单中心页path,请设置后再提交代码审核

小程序版本审核未通过&#xff0c;需在开发者后台「版本管理—提交审核——小程序订单中心path」设置订单中心页path&#xff0c;请设置后再提交代码审核 因小程序尚未发布&#xff0c;订单中心不能正常打开查看&#xff0c;请先发布小程序后再提交订单中心PATH申请 初次提交…...

Netty入门指南之NIO Selector监管

作者简介&#xff1a;☕️大家好&#xff0c;我是Aomsir&#xff0c;一个爱折腾的开发者&#xff01; 个人主页&#xff1a;Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏&#xff1a;Netty应用专栏_Aomsir的博客-CSDN博客 文章目录 参考文献前言问题解…...

Spring Cloud学习(六)【统一网关 Gateway】

文章目录 网关的功能搭建网关服务路由断言工厂Route Predicate Factory路由过滤器 GatewayFilter过滤器执行顺序跨域问题处理 网关的功能 网关功能&#xff1a; 身份认证和权限校验服务路由、负载均衡请求限流 在SpringCloud中网关的实现包括两种&#xff1a; gatewayzuul …...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...