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

vue2+html2canvas+js PDF实现试卷导出和打印功能

1.首先安装

import html2canvas from 'html2canvas';

import { jsPDF } from 'jspdf';

2.引入打印插件print.js

import Print from "@/assets/js/print";

Vue.use(Print)

// 打印类属性、方法定义
/* eslint-disable */
const Print = function (dom, options) {if (!(this instanceof Print)) return new Print(dom, options);this.options = this.extend({'noPrint': '.no-print'}, options);if ((typeof dom) === "string") {this.dom = document.querySelector(dom);} else {this.isDOM(dom)this.dom = this.isDOM(dom) ? dom : dom.$el;}this.init();
};
Print.prototype = {init: function () {var content = this.getStyle() + this.getHtml();this.writeIframe(content);},extend: function (obj, obj2) {for (var k in obj2) {obj[k] = obj2[k];}return obj;},getStyle: function () {var str = "",styles = document.querySelectorAll('style,link');for (var i = 0; i < styles.length; i++) {str += styles[i].outerHTML;}str += "<style>" + (this.options.noPrint ? this.options.noPrint : '.no-print') + "{display:none;}</style>";// str += "<style>html,body,div{height: auto!important;font-size:14px}</style>";return str;},getHtml: function () {var inputs = document.querySelectorAll('input');var textareas = document.querySelectorAll('textarea');var selects = document.querySelectorAll('select');for (var k = 0; k < inputs.length; k++) {if (inputs[k].type == "checkbox" || inputs[k].type == "radio") {if (inputs[k].checked == true) {inputs[k].setAttribute('checked', "checked")} else {inputs[k].removeAttribute('checked')}} else if (inputs[k].type == "text") {inputs[k].setAttribute('value', inputs[k].value)} else {inputs[k].setAttribute('value', inputs[k].value)}}for (var k2 = 0; k2 < textareas.length; k2++) {if (textareas[k2].type == 'textarea') {textareas[k2].innerHTML = textareas[k2].value}}for (var k3 = 0; k3 < selects.length; k3++) {if (selects[k3].type == 'select-one') {var child = selects[k3].children;for (var i in child) {if (child[i].tagName == 'OPTION') {if (child[i].selected == true) {child[i].setAttribute('selected', "selected")} else {child[i].removeAttribute('selected')}}}}}return this.dom.outerHTML;},writeIframe: function (content) {var w, doc, iframe = document.createElement('iframe'),f = document.body.appendChild(iframe);iframe.id = "myIframe";//iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";iframe.setAttribute('style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;');w = f.contentWindow || f.contentDocument;doc = f.contentDocument || f.contentWindow.document;doc.open();doc.write(content);doc.close();var _this = thisiframe.onload = function () {_this.toPrint(w);setTimeout(function () {document.body.removeChild(iframe)}, 100)}},toPrint: function (frameWindow) {try {setTimeout(function () {frameWindow.focus();try {if (!frameWindow.document.execCommand('print', false, null)) {frameWindow.print();}} catch (e) {frameWindow.print();}frameWindow.close();}, 10);} catch (err) {console.log('err', err);}},isDOM: (typeof HTMLElement === 'object') ?function (obj) {return obj instanceof HTMLElement;} :function (obj) {return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';}
};
const MyPlugin = {}
MyPlugin.install = function (Vue, options) {// 4. 添加实例方法Vue.prototype.$print = Print
}
export default MyPlugin

3.执行函数

 // loding等待toLoding() {this.loading = this.$loading({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'});// 导出按钮显示状态this.pdfIsShowData = false;// 展开所有节点let activeNames = [];for (let i = 0; i < Object.keys(this.dataAll).length; i++) {activeNames.push((i));}this.activeNames = activeNames;// 展开所有子节点if (this.$refs.collapse && this.$refs.collapse.length > 0) {this.$refs.collapse.forEach((item, index) => {item.activeNames = ['0'];})}// 关闭滚动条this.isMaxHeight = false;},// 打印试卷printPaper() {// 等待节点全部展开this.toLoding();setTimeout(() => {this.$nextTick(() => {this.$print(this.$refs.printContent);setTimeout(() => {this.loading.close();this.pdfIsShowData = true;}, 1000)});}, 2000)},// 导出试卷exportPaper() {// 等待节点全部展开this.toLoding()setTimeout(() => {this.$nextTick(() => {// 获取目标元素const element = document.querySelector('.toPdf');// 使用 html2canvas 捕获快照html2canvas(element).then(canvas => {// 将 canvas 转换为图片数据const imgData = canvas.toDataURL('image/png');// 创建一个 jsPDF 实例const pdf = new jsPDF('p', 'mm', 'a4');const imgWidth = 210; // A4纸宽const pageHeight = 297; // A4纸高let imgHeight = canvas.height * imgWidth / canvas.width;let heightLeft = imgHeight;// 添加图像到 PDF 第一页let position = 0;pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);heightLeft -= pageHeight;// 如果内容超过一页,则添加更多页while (heightLeft >= 0) {position = heightLeft - imgHeight;pdf.addPage();pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);heightLeft -= pageHeight;}// 下载 PDF 文件pdf.save(`${this.testName}.pdf`);this.pdfIsShowData = truethis.loading.close();this.$message({message: '导出成功',type: 'success'});// 关闭滚动条this.isMaxHeight = false;}).catch(error => console.error('Error capturing the snapshot:', error));});}, 2000)},

4.样式问题

打印时候把所有字体颜色改为黑色

.toPdf-black * {color: #000 !important;
}

<div :class="{ 'toPdf': true, 'toPdf-black': !pdfIsShowData }" ref="printContent"

相关文章:

vue2+html2canvas+js PDF实现试卷导出和打印功能

1.首先安装 import html2canvas from html2canvas; import { jsPDF } from jspdf; 2.引入打印插件print.js import Print from "/assets/js/print"; Vue.use(Print) // 打印类属性、方法定义 /* eslint-disable */ const Print function (dom, options) {if (…...

【Python网络爬虫 常见问题汇总】

目录 1. 爬取图片出现403解决办法&#xff1a;设置请求头中的Referer字段 2.关于干坏事的问题后续不定期更新 欢迎共同探讨学习进步 1. 爬取图片出现403 问题出自案例9&#xff0c;已解决。 【Python网络爬虫笔记】9- 抓取优美图库高清壁纸 当在爬取图库图片时遇到 403 错误…...

Java SpringBoot 项目怎样在 IDEA 中运行、部署

大家好&#xff0c;我是程序员徐师兄&#xff0c;今天为大家带来的是Java SpringBoot 项目怎样在 IDEA 中运行、部署。Java 项目的安装部署教程&#xff0c;包括软件的下载&#xff0c;软件的安装。该系统采用 Java 语言开发&#xff0c;SpringBoot 框架&#xff0c;MySql 作为…...

GAMES101:现代计算机图形学-笔记-10

今天来聊一些基本的概念&#xff1a;相机&#xff0c;棱镜与光场。 众所周知&#xff0c;成像的方法有两种&#xff1a;合成与捕获。 像我们之前所学的内容如光栅化&#xff0c;如光线追踪&#xff0c;本质上都是合成图像的方法&#xff0c;他们只是在计算机中模拟来成像。 那…...

【前端面试】Http篇

1. HTTPS 概念 加密&#xff08;Encryption&#xff09; 防止数据被截获 数据完整性&#xff08;Data Integrity&#xff09; 防止数据篡改 身份验证&#xff08;Authentication&#xff09; 验证网站的真实性 2. HTTPS 与 HTTP 的区别 HTTP 是明文传输&#xff0c;HTTPS 是…...

ZZCMS2023存在跨站脚本漏洞(CNVD-2024-44822、CVE-2024-44818)

ZZCMS是一款用于搭建招商网站的CMS系统&#xff0c;由PHP语言开发&#xff0c;可快速搭建&#xff1a;医药招商、保健品招商、化妆品招商、农资招商、孕婴童招商、酒类副食类等招商网站。 国家信息安全漏洞共享平台于2024-11-14公布其存在跨站脚本漏洞。 漏洞编号&#xff1a…...

Android 15 前台服务类型的变更

在 Android 15 中对前台服务类型做出以下更改。 仍在处理中的媒体内容 要在其清单中声明的前台服务类型 android:foregroundServiceType mediaProcessing在清单中声明的权限 FOREGROUND_SERVICE_MEDIA_PROCESSING要传递给 startForeground() 的常量 FOREGROUND_SERVICE_TYPE_ME…...

微信小程序开发简易教程

微信小程序文件结构详解 1. 项目配置文件 project.config.json 项目的配置文件包含项目名称、appid、编译选项等配置示例&#xff1a; {"description": "项目配置文件","packOptions": {"ignore": []},"setting": {&quo…...

树莓派 发那科 Fanuc Linux跨平台CNC数控数据采集协议,TCP协议包

市面上的数控基本都支持了跨平台通讯&#xff0c;下面以发那科为列讲解跨平台协议如何通讯&#xff0c;无需任何DLL&#xff0c;适配任何开发语言&#xff0c;纯Socket通讯 先上采集图 握手包&#xff1a;a0 a0 a0 a0 00 01 01 01 00 02 00 02 释放包&#xff1a;a0 a0 a0 a…...

Ubuntu中安装配置交叉编译工具并进行测试

01-下载获取交叉编译工具的源码 按照博文 https://blog.csdn.net/wenhao_ir/article/details/144325141的方法&#xff0c;把imx6ull的BSP下载好后&#xff0c;其中就有交叉编译工具。 当然&#xff0c;为了将来使用方便&#xff0c;我已经把它压缩并传到了百度网盘&#xff…...

C++核心day3作业

作业&#xff1a; 1.整理思维导图 2.整理课上代码 3.把课上类的三个练习题的构造函数写出来 函数全部类内声明&#xff0c;类外定义 定义一个矩形类Rec&#xff0c;包含私有属性length、width&#xff0c;包含公有成员方法&#xff1a; void set_length(int l); //设置长度v…...

socket UDP 环路回显的服务端

基于socket通讯的方式&#xff0c;无论用http或者udp或者自定义的协议&#xff0c;程序结构都是类似的。这个以UDP协议为例简要说明。 #include <stdio.h> // 标准输入输出库 #include <sys/types.h> // 提供了一些数据类型&#xff0c;如ssize_t #include <sy…...

springboot/ssm车辆违章信息管理系统Java代码web项目汽车违章处罚源码

基于springboot(可改ssm)htmlvue项目 springboot/ssm车辆违章信息管理系统Java代码web项目汽车违章处罚源码 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&…...

5G模组AT命令脚本-关闭模组的IP过滤功能

关闭模组的IP过滤功能 关闭模组的IP过滤功能 5G 模组通常使用nat方式为 下挂设备或上位机提供上网服务&#xff0c;默认情况&#xff0c;不做NAt的包无法经由 模组转发&#xff0c;如果禁掉这个限制 &#xff0c;可使用本文中的配置命令本脚本用于关闭模组的IP过滤功能&#xf…...

STM32:实现ping命令(lwip)

目录 0.协议介绍ICMP数据包格式ping指令发送的ICMP回声请求消息ping指令接收的ICMP回声应答消息1.实现步骤2.源码分析2.1 初始化函数2.2 发送函数2.3 回调函数2.3.1 函数定义:2.3.2 解析数据包:2.3.3.处理ICMP数据包:2.3.4 资源释放:2.3.5 返回值:3.源码展示4.源码链接5.问…...

nvm安装指定版本显示不存在及nvm ls-remote 列表只出现 iojs 而没有 node.js 解决办法

在使用 nvm install 18.20.3 安装 node 时会发现一直显示不存在此版本 Version 18.20.3 not found - try nvm ls-remote to browse available versions.使用 nvm ls-remote 查看可安装列表时发现&#xff0c;列表中只有 iojs 解决方法&#xff1a; 可以使用以下命令查看可安装…...

Spring Boot 中 WebClient 的实践详解

在现代微服务架构中&#xff0c;服务之间的通信至关重要。Spring Boot 提供了 WebClient&#xff0c;作为 RestTemplate 的替代方案&#xff0c;用于执行非阻塞式的 HTTP 请求。本文将详细讲解 WebClient 的实践&#xff0c;包括配置、使用场景以及常见的优化策略&#xff0c;帮…...

在GITHUB上传本地文件指南(详细图文版)

这份笔记简述了如何在GITHUB上上传文件夹的详细策略。 既是对自己未来的一个参考&#xff0c;又希望能给各位读者带来帮助。 详细步骤 打开目标文件夹&#xff08;想要上传的文件夹&#xff09; 右击点击git bash打开 GitHub创立新的仓库后&#xff0c;点击右上方CODE绿色按…...

【大模型系列篇】LLaMA-Factory大模型微调实践 - 从零开始

前一次我们使用了NVIDIA TensorRT-LLM 大模型推理框架对智谱chatglm3-6b模型格式进行了转换和量化压缩&#xff0c;并成功部署了推理服务&#xff0c;有兴趣的同学可以翻阅《NVIDIA TensorRT-LLM 大模型推理框架实践》&#xff0c;今天我们来实践如何通过LLaMA-Factory对大模型…...

30天学会Go--第7天 GO语言 Redis 学习与实践

30天学会Go–第7天 GO语言 Redis 学习与实践 文章目录 30天学会Go--第7天 GO语言 Redis 学习与实践前言一、Redis 基础知识1.1 Redis 的核心特性1.2 Redis 常见使用场景 二、安装 Redis2.1 在 Linux 上安装2.2 在 Windows 上安装2.3 使用 Docker 安装 Redis 三、Redis 常用命令…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

【iOS】 Block再学习

iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...

Python学习(8) ----- Python的类与对象

Python 中的类&#xff08;Class&#xff09;与对象&#xff08;Object&#xff09;是面向对象编程&#xff08;OOP&#xff09;的核心。我们可以通过“类是模板&#xff0c;对象是实例”来理解它们的关系。 &#x1f9f1; 一句话理解&#xff1a; 类就像“图纸”&#xff0c;对…...

DAY 45 超大力王爱学Python

来自超大力王的友情提示&#xff1a;在用tensordoard的时候一定一定要用绝对位置&#xff0c;例如&#xff1a;tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾&#xff1a; tensorboard的发展历史和原理tens…...