文章目录
前言关于 Print.js里PDF 打印里网页(HTML)打印里图像打印里JSON 打印里下载并安装使用里相关配置
Vue3 中使用 Print.js 实战Vue3 + Nodejs + Print.js 模拟打印实战案例里启动 Nodejs 服务里启动 Vue 项目
最后文末送书里编辑推荐里内容介绍里作者介绍
参与方式
前言
今天久违的更新一下关于 Vue 的文章了,本篇文章是基于 Vue3 + Node.js + ElementPlus 的实战项目分享,实战内容包括有打印插件 Print.js 的使用,以及关于 ElementPlus 中的 el-table 与 el-pagination 的深入使用。本次项目以文章(axios 实战进阶练习——基于 Vue3 + Node.js + ElementPlus 实现的联系人列表管理后台)中的项目为模板进行改动和编写。
关于 Print.js
在使用 Print.js 插件之前,我们可以通过下面的链接先了解和认识一下这个 JavaScript 插件。 官方地址:Print.js - Javascript library for HTML elements, PDF and image files printing. GitHub地址:GitHub - crabbly/Printjs: A tiny javascript library to help printing from the web. 如何认识和快速上手 Print.js,我们可以从官网的内容开始阅读,在官网中有很详细的介绍和使用例子,虽然是英文版的。Print.js 打印插件包括了 PDF 打印、HTML 打印、JSON 打印、图像打印等,这篇文章主要分享的 PDF 打印的实战,其中在使用过 Print.js 之后,对于这几种打印的类型,其实都是差不多的,主要区别还是参数配置问题。接下来就简单介绍一下这几种打印的类型。
里PDF 打印
Print.js 主要是为了帮助我们直接在应用程序中打印 PDF 文件,无需离开界面,也不使用嵌入。对于用户不需要打开或下载 PDF 文件,而只需要打印它们的独特情况。
例如,当用户请求打印在服务器端生成的报表时,这很有用的一种情况。这些报告以 PDF 文件的形式发回。在打印这些文件之前,无需打开它们。Print.js 提供了一种在我们的应用程序中打印这些文件的快速方法。
❗注意:PDF 文件必须从托管应用的同一网域提供。Print.js 在打印文件之前使用 iframe 加载文件,因此,它受到同源策略的限制。这有助于防止跨站点脚本 (XSS) 攻击。(关于这点也是实际项目中出现的一个问题)
Print PDF
Print PDF with Message
Print PDF with Message
里网页(HTML)打印
有时我们只想打印HTML页面的选定部分,这可能很棘手。使用 Print.js,我们可以轻松传递要打印的元素的 id。该元素可以是任何标记,只要它具有唯一的 id。图书馆将尝试非常接近它在屏幕上的外观进行打印,同时,它将为其创建打印机友好的格式。
Print Form
Print Form with Header
里图像打印
Print.js 可用于通过传递图像 URL 快速打印页面上的任何图像。当您使用低分辨率版本的图像在屏幕上有多个图像时,这可能很有用。当用户尝试打印所选图像时,您可以将高分辨率 url 传递给 Print.js。
printJS('images/print-01-highres.jpg', 'image')
printJS({printable: 'images/print-01-highres.jpg', type: 'image', header: 'My cool image header'})
printJS({
printable: ['images/print-01-highres.jpg', 'images/print-02-highres.jpg', 'images/print-03-highres.jpg'],
type: 'image',
header: 'Multiple Images',
imageStyle: 'width:50%;margin-bottom:20px;'
})
里JSON 打印
打印动态数据或 JavaScript 对象数组的简单快捷方法。
someJSONdata = [
{
name: 'John Doe',
email: 'john@doe.com',
phone: '111-111-1111'
},
{
name: 'Barry Allen',
email: 'barry@flash.com',
phone: '222-222-2222'
},
{
name: 'Cool Dude',
email: 'cool@dude.com',
phone: '333-333-3333'
}
]
Print JSON Data
我们可以通过传递一些自定义 css 来设置数据网格的样式:
Print JSON Data
我们可以自定义发送对象数组的表头文本:
Print with custom table header text
JSON、HTML 和 Image print 可以接收原始 HTML 标头:
style: '.custom-h3 { color: red; }'
})">
Print header raw html
里下载并安装使用
可以从 GitHub 版本下载最新版本的 Print.js。(链接在上面提及过) 使用 npm 进行安装,请执行以下操作:
npm install print-js --save
使用 yarn 安装:
yarn add print-js
通过 npm 或 yarn 安装时,将库导入到项目中:
import print from 'print-js'
也可以使用在线的 CDN:
https://printjs-4de6.kxcdn.com/print.min.js
https://printjs-4de6.kxcdn.com/print.min.css
里相关配置
Print.js 将接受一个对象作为参数,下面表格的参数则为该对象的属性,通过控制属性值来控制打印。
参数默认值说明printablenull文档来源:pdf或图像的url,html元素的id或json数据的对象typePDF可打印类型。可用的打印选项包括:pdf,html,image,json和raw-html。headernull用于HTML,Image或JSON打印的可选标头。它将放在页面顶部。此属性将接受文本或原始HTMLheaderStyle‘font-weight:300;’要应用于标题文本的可选标题样式maxWidth800最大文档宽度(像素)。根据需要更改此项。在打印HTML,图像或JSON时使用。cssnull这允许我们传递一个或多个应该应用于正在打印的html的css文件URL。值可以是包含单个URL的字符串,也可以是包含多个URL的数组。stylenull这允许我们传递一个字符串,该字符串应该应用于正在打印的html。scanStylestrue设置为false时,库不会处理应用于正在打印的html的样式。使用css参数时很有用。targetStylenull默认情况下,在打印HTML元素时,库仅处理某些样式。此选项允许您传递要处理的样式数组。例如:[‘padding-top’,‘border-bottom’]targetStylesnull与targetStyle相同,这将处理任何一系列样式。例如:[‘border’,‘padding’],将包括’border-bottom’,‘border-top’,‘border-left’,‘border-right’,‘padding-top’等。你也可以传递[’*']来处理所有样式ignoreElements[]接受打印父html元素时应忽略的html的id数组。propertiesnull在打印JSON时使用。这些是对象属性名称。gridHeaderStyle‘font-weight:bold;’打印JSON数据时网格标题的可选样式。gridStyle‘border: 1px solid lightgray; margin-bottom: -1px;’打印JSON数据时网格行的可选样式repeatTableHeadertrue在打印JSON数据时使用。设置为时false,数据表标题仅显示在第一页中。showModalnull启用此选项可在检索或处理大型PDF文件时显示用户反馈modalMessage‘Retrieving Document…’当向用户显示的消息showModal被设定为true。onLoadingStartnull加载PDF时要执行的功能onLoadingEndnull加载PDF后要执行的功能documentTitle‘Document’打印html,image或json时,它将显示为文档标题。如果用户尝试将打印作业保存为pdf文件,它也将是文档的名称。fallbackPrintablenull打印pdf时,如果浏览器不兼容(检查浏览器兼容性表),库将在新选项卡中打开pdf。这允许您传递要打开的不同pdf文档,而不是传递给printable的原始文档。如果您在备用pdf文件中注入javascript,这可能很有用。onPdfOpennull打印pdf时,如果浏览器不兼容(检查浏览器兼容性表),库将在新选项卡中打开pdf。可以在此处传递回调函数,这将在发生这种情况时执行。在您想要处理打印流程,更新用户界面等的某些情况下,它可能很有用。onPrintDialogClosenull关闭浏览器打印对话框后执行回调功能onErrorerror => throw error发生错误时要执行的回调函数。base64false在打印作为base64数据传递的PDF文档时使用honorMarginPadding(不建议使用)true这用于保留或删除正在打印的元素的填充和边距。有时这些样式设置在屏幕上很棒,但在打印时看起来很糟糕。您可以通过将其设置为false来删除它。honorColor(不建议使用)false要以彩色打印文本,请将此属性设置为true。默认情况下,所有文本都将以黑色打印。font(不建议使用)‘TimesNewRoman’打印HTML或JSON时使用的字体font_size(不建议使用)‘12pt’打印HTML或JSON时使用的字体大小imageStyle (不建议使用)‘width:100%;’打印图像时使用。接受包含要应用于每个图像的自定义样式的字符串。frameIdnullprint.js会将要打印的内容复制到一个新的Frame中,此参数是frame的id值
Vue3 中使用 Print.js 实战
接下来,我们通过业务需求和代码解析来分享一下在 Vue3 中使用 Print.js 的实战。首先我们来讲一下需求,非常简单,就是某个表格或列表的打印按钮,然后页面调起打印窗口,打印完成就删除这条打印数据。不往深入的讲,我们不谈数据来源,以及如何添加数据到打印列表,我只要知道点击这个按钮可以打印就行了,这里我们就用 Nodejs 来写一个返回 PDF 的接口,写死一条 PDF 的数据,来模拟用户添加打印数据到打印列表,实现打印功能。
接下来我们通过代码来看看如何使用 Print.js,首先是要安装 Print.js ,上面也提及到了这个 npm 命令,这里就不重复了。安装完成之后,我们要在项目中导入 Print.js,如下图。 我们可以先简单写个按钮来测试一下,是否可以使用正常使用这个插件。
上面这段代码,是打印 PDF 的一个简单例子,上面我们也说到,打印 PDF 文件时,PDF 文件必须从托管应用的同一网域提供,受到同源策略的限制。这有助于防止跨站点脚本 (XSS) 攻击。所以我们要确保这个 PDF 与项目是在同一个域(比如说 PDF 和项目都在 https://xxx.com 这个域名的服务器上面),如果不一样的话会出现跨域的情况。 上面图片是官网的 example 的例子,点击 Print PDF 那个按钮后,会弹出打印的窗口如上图所示。下面则是我在本地项目使用 Print.js 的例子截图。 我们可以看到出现了跨域的情况,是因为这个在线的 PDF (这里就不提供这个 PDF 链接,读者可以用自己的在线 PDF 来测试)跟我本地跑的 Vue 项目不是同一个网域。因此我们在后台返回获取到的 PDF 路径要跟运行的项目是同一个网域。假设把 PDF 路径上传到 OSS(对象存储服务),然后项目部署在其他的服务器什么,这种情况下,是可以进行打印访问的,但是前提是在 OSS 上面设置了允许跨域。接下来看一下这段实战中的代码片段,以及其功能的解析。
const printdelete = (row) => {
ElMessage({
message: "正在加入打印",
grouping: true,
type: "success",
});
printJS(IMG.value + row.path);
console.log(IMG.value + row.path);
const params = {
id: row.id,
};
instance
.post("/xxxapi/print/delete?id=" + params.id)
.then((res) => {
console.log(res);
if (res.status === 200) {
console.log("已添加到打印!");
ElMessage({
message: "已添加到打印!",
grouping: true,
type: "success",
});
} else {
ElMessage({
message: "打印失败",
grouping: true,
type: "error",
});
}
})
.catch((err) => {
ElMessage({
message: err,
grouping: true,
type: "error",
});
});
};
这段代码就是打印实战的代码,总体思路就是,通过后端返回的 PDF 路径,然后拼接好 OSS 的路径,在之后使用 printJS 进行打印,最后打印成功后调用删除打印列表的接口,删除刚刚打印完的打印列表数据,其他就是是一些交互操作,打印前后的消息栏。
接下来我们具体看到代码,从上往下,首先这个函数接收一个参数 row,这个参数的来源是 el-table 中每一行的数据信息,比如说打印列表有打印文件的名称,发起人,打印文件的创建时间等等,其中不在列表显示的 PDF 路径是参数 row 中尤为重要的数据。我们可以看到代码中 printJS(IMG.value + row.path); 的这段代码,其中 IMG.value 是 OSS 的路径,然后 row.path 就是刚刚所说的在列表没有显示的 PDF 路径,二者拼接起来就是一个完整打印路径,通过调用 printJS 即可实现打印。接着往下看,调起打印窗口,打印完成,接下来就是删除这条打印完的打印数据,通过请求删除的接口(这段代码 .post(“/xxxapi/print/delete?id=” + params.id)),其中代码中的 instance 是指封装的 axios.create,这样写方便后续多次调用 axios.create。
总体流程就是在函数内部,首先使用ElMessage方法显示一个成功的消息,提示正在加入打印。然后使用 printJS 方法打印 IMG.value + row.path ,并在控制台输出该路径。接下来,创建一个包含 row.id 的 params 对象。接着,使用 instance 发送一个 POST 请求到 /xxxapi/print/delete?id= 加上 params.id 作为参数的 URL。如果请求成功(状态码为 200),在控制台输出响应结果,并显示一个成功的消息。否则,显示一个失败的消息。如果发生错误,会在控制台输出错误,并显示一个错误的消息。
Vue3 + Nodejs + Print.js 模拟打印实战案例
通过上面的基础学习和实战分享,我们对 Print.js 有了一定的了解,通过上手实例和项目分享的内容也可以快速 Print.js 了。接下来分享一个简单的实战案例,来巩固和总结一下前面文章提及的内容。 首先,我们使用 Nodejs 写一个服务,把本地的 PDF 部署在 http://localhost:8080/ 上面,在使用 Print.js 确保 PDF 和 Vue 项目都在同一个网域下,避免出现跨域的情况。接下来,我们一起来看一下 Nodejs 的代码。
const express = require('express');
const app = express();
const path = require('path');
const fs = require('fs');
const {
createProxyMiddleware
} = require('http-proxy-middleware');
// 设置端口号
const port = 8080;
// 加载静态资源
// app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname)));
// 处理下载请求
app.get('/api/getPdfLink', (req, res) => {
// 构造文件绝对路径
// const filePath = path.join(__dirname, 'P020221111501862950279.pdf');
const pdfPath = 'http://localhost:8080/P020221111501862950279.pdf';
console.log(`File path: ${pdfPath}`);
// 返回文件路径
res.send({
link: pdfPath
});
});
// 反向代理到 Vue 项目
app.use(
'/',
createProxyMiddleware({
target: 'http://localhost:8080',
changeOrigin: true,
})
);
// 启动服务
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}/api/getPdfLink`);
});
首先创建 app.js 作为项目的入口文件,后续只要 node app 即可运行服务,然后安装所需的配置文件,如下命令。
npm install express // 安装 Express 框架
因为Vue 项目已经占用了 8080 端口,为了确保 Nodejs 服务也监听在同一个端口上,以保持相同的域名,我们可以尝试使用反向代理来实现这一目的,安装命令如下。
npm install http-proxy-middleware // 安装反向代理
安装好这些配置后,我们看具体代码的功能。这个程序的主要目的就是写一个接口返回 PDF 路径,然后前端调用这个接口获取到 PDF 的路径,然后实现打印功能。接下来简单分析一下这段代码。
设置端口号为 8080:const port = 8080;加载静态资源:app.use(express.static(path.join(__dirname)));。这里使用 Express 的 express.static 中间件来加载静态资源。path.join(__dirname) 表示将当前目录作为静态资源所在的根目录。这意味着 PDF 文件应该放在服务器启动的根目录中,如下图。 /api/getPdfLink 接口:当客户端通过 /api/getPdfLink 路径发送 GET 请求时,服务器会返回一个包含 PDF 文件路径的 JSON 响应。在这个例子中,PDF 文件的路径是硬编码的,为 http://localhost:8080/P020221111501862950279.pdf。
app.get('/api/getPdfLink', (req, res) => {
const pdfPath = 'http://localhost:8080/P020221111501862950279.pdf';
console.log(`File path: ${pdfPath}`);
res.send({ link: pdfPath });
});
反向代理到 Vue 项目:这部分代码将所有对根路径 / 的请求反向代理到目标地址为 http://localhost:8080 的服务器。这通常用于将 Express 服务器和 Vue 项目集成在一起,实现前后端的联合开发。
app.use(
'/',
createProxyMiddleware({
target: 'http://localhost:8080',
changeOrigin: true,
})
);
启动服务器:最后,通过调用 app.listen 方法,启动服务器并监听指定的端口号。
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}/api/getPdfLink`);
});
里启动 Nodejs 服务
接下来通过 node app 启动服务,并且测试一下接口是否可以获取到数据。 直接在浏览器访问 http://localhost:8080/api/getPdfLink。 然后再访问 http://localhost:8080/P020221111501862950279.pdf。 到此 Nodejs 服务启动没用问题,接下来我们运行一下 Vue 项目。
里启动 Vue 项目
npm run serve 直接启动项目。 页面非常简单,就只有一个按钮。通过下图控制台输出的结果,可以说明成功调用接口,返回了参数。 然后我们点击这个按钮,试一下能不能成功调起打印窗口呢。 最后成功调起的了打印窗口,运行成功,到此项目的主流程已经完成了。下面是这个页面的代码。
// import { ElMessage, ElMessageBox } from "element-plus";
import printJS from "print-js";
import { ref, onMounted } from "vue";
import axios from "axios";
import Http from "@/service/http";
// axios默认数据
// const instance = axios.create({
// baseURL: "http://localhost:8080",
// timeout: 10000,
// });
// 在组件挂载完毕后调用 refreshList 函数
onMounted(() => {
refreshList();
});
const pdflink = ref();
const refreshList = async () => {
let res = await Http.getPdfLink();
pdflink.value = res.link;
console.log(res);
console.log(res.link);
};
const printPDF = () => {
printJS(pdflink.value);
};
.contact-list {
max-width: 800px;
margin: auto;
padding: 20px;
}
如果需要完整代码或者项目的读者,可以私信我或者添加我的联系方式获取,如收到消息会第一时间回复。
最后
到此就是 Vue 实战篇——打印插件 Print.js 的使用(Vue3 + Nodejs + Print.js 实战)以及 el-table 与 el-pagination 的深入使用(上)的全部内容了,通过这篇文章,我们可以多学一招,学会使用 Print.js 插件打印 PDF 文件。以及通过 Vue3 + Nodejs + Print.js 实战,我们可以加深对该插件的熟悉程度,其实该实战的难点是 Nodejs 服务的编写,但这不是我们所要深究的,这只是解决跨域问题的一个前提,最主要是体验和上手过一遍打印的流程。通过接口获取到 PDF 文件的路径,然后在项目中使用 Print.js 插件的 printJS 方法,把获取到的路径传入这个方法,然后调起打印窗口,最后完成打印。
除此之外,关于该项目的实战延申,还有关于 el-table 与 el-pagination 的内容,这些内容会在《Vue3 开发实战分享——打印插件 Print.js 的使用(Vue3 + Nodejs + Print.js 实战)以及 el-table 与 el-pagination 的深入使用(下)》介绍和分享,敬请期待。
文末送书
里编辑推荐
(1)实用性强:本书的案例是基于真实的企业级项目需求而开发的,读者可通过学习本 书,掌握实际项目开发中的技巧和方法。 (2)实用性强:本书的案例是基于真实的企业级项目需求而开发的,读者可通过学习本 书,掌握实际项目开发中的技巧和方法。 (3)互动性强:本书赠送配套的微课视频约164集,读者可通过观看视频更好地理解代码的实现过程和实现方法。
里内容介绍
本书是一本实用性很强的Vue.js 3实战项目书。书中结合实际项目场景,构建了一个完整的企业级应用。全书共分13章,内容包含项目概述、Vue3项目管理、登录管理、后台主框架、图库管理、管理员管理、用户管理、商品管理、订单管理、优惠券管理、商品评论管理、分销管理和公告管理,并且讲解了这些模块的实际应用方法。同时,本书还介绍了如何使用Vite、Axios、Vue Router、Vuex等流行工具和库,以提高开发效率、提升用户体验。
里作者介绍
袁龙,从事Web开发、教学培训等业务,创建“锦匠特效”和“锦匠课堂”两大Web前端工具类网站,为数万前端开发者提供高效率的工作方式,轻松实现网页动画特效,目前是51CTO、CSDN等在线教育平台讲师。著有《Vue.js核心技术解析与uni-app跨平台开发实战》《Node.js从基础到项目实践(视频教学版) 》等多部著作。
参与方式
《 Vue.js 3企业级项目开发实战》免费包邮送出 3 本!
抽奖方式:评论区随机抽取 3 位小伙伴免费送出! 参与方式:关注博主、点赞、收藏、评论区评论 “人生苦短,我学Vue!” (切记要点赞+收藏,否则抽奖无效,每个人最多评论三次!) 活动截止时间:2023-10-21 20:00:00 当当自营店购买链接:http://product.dangdang.com/29621812.html
好文推荐
发表评论