实现pc端打印文章、报告功能
一、需求分析
因为window的打印接口是把整体的窗口内容都打印了进去,而需求只是打印报告页面的内容,并不包括头部导航和侧边栏,所以就在网上找到print-js的这个第三方库,这个库可以打印html、json数据、pdf等。实现方式也很简单,只需要引入js文件,并调用方法就行。
二、准备工作
- 引入js
因为项目是用vue搭建的,所以采用了npm的安装方式。
npm install print-js --save
- 在需要实现打印功能的页面引入方法
import PrintJs from 'print-js'
- 打印方法参数:
参数 | 默认值 | 描述 |
---|---|---|
printable | null | 文档来源:pdf 或图片 url、html 元素 id 或 json 数据对象。 |
type | ‘pdf’ | 可打印类型。可用的打印选项有:pdf、html、image、json 和 raw-html。 |
header | null | 用于与 HTML、图像或 JSON 打印的可选标题。它将被放置在页面顶部。此属性将接受文本或原始 HTML。 |
headerStyle | ‘font-weight: 300;’ | 要应用于标题文本的可选标题样式。 |
maxWidth | 800 | 最大文档宽度(以像素为单位)。根据需要更改此设置。在打印 HTML、图像或 JSON 时使用。 |
css | null | 应用于正在打印的 html 的 css 文件 URL。值可以是具有单个 URL 的字符串或具有多个 URL 的数组。 |
style | null | 自定义样式的字符串。应用于正在打印的 html。 |
scanStyles | true | 设置为 false 时,库将不会处理应用于正在打印的 html 的样式。在使用 css 参数时很有用。 |
targetStyle | null | 默认情况下,库仅在打印 HTML 元素时处理某些样式。此选项允许您传递要处理的样式数组。例如:[‘padding-top’, ‘border-bottom’] |
targetStyles | null | 与 targetStyle 相同,但是,这将处理任意范围的样式。例如:[‘border’, ‘padding’],将包括’border-bottom’、‘border-top’、‘border-left’、‘border-right’、‘padding-top’等。也可以通过 [’*'] 来处理所有样式。 |
ignoreElements | [ ] | 传入打印父 html 元素时应忽略的 html id 数组。使其不打印。 |
properties | null | 打印 JSON 时使用。这些是对象属性名称。 |
gridHeaderStyle | ‘font-weight: bold;’ | 打印 JSON 数据时网格标题的可选样式。 |
gridStyle | ‘border: 1px solid lightgray; margin-bottom: -1px;’ | 打印 JSON 数据时网格行的可选样式。 |
repeatTableHeader | TRUE | 打印 JSON 数据时使用。设置为 false 时,数据表标题将仅显示在第一页。 |
showModal | null | 启用此选项可在检索或处理大型 PDF 文件时显示用户反馈。 |
modalMessage | Retrieving Document…’ | 当 showModal 设置为 true 时向用户显示的消息。 |
onLoadingStart | null | 加载 PDF 时要执行的功能 |
onLoadingEnd | null | 加载 PDF 后要执行的功能 |
documentTitle | Document’ | 打印 html、图像或 json 时,这将显示为文档标题。 |
fallbackPrintable | null | 打印 pdf 时,如果浏览器不兼容(检查浏览器兼容性表),库将在新选项卡中打开 pdf。这允许您传递要打开的不同pdf文档,而不是在printable中传递的原始文档。如果您在备用pdf文件中注入javascript,这可能很有用。 |
onPdfOpen | null | 打印 pdf 时,如果浏览器不兼容(检查浏览器兼容性表),库将在新选项卡中打开 pdf。可以在此处传递回调函数,该函数将在发生这种情况时执行。在某些情况下,如果要处理打印流、更新用户界面等,它可能很有用。 |
onPrintDialogClose | null | 在浏览器打印对话框关闭后执行的回调函数。 |
onError | error => throw error | 发生错误时要执行的回调函数。 |
base64 | false | 在打印作为 base64 数据传递的 PDF 文档时使用。 |
三、实现功能
- 打印按钮
<button @click="printHandle"></button>
- 方法调用
function printHandle() {
PrintJs({
printable: "elId",
type: "html",
scanStyles: false,
maxWidth: 1980,
css: ['./print.css']
})
}
因为我需要打印的对象是html,所以printable传的是元素id(传id时不用带#),打印的样式可以是字符串,也可以是一个css样式文件。当传入的样式是一个文件路径时,样式文件放在src文件夹下是找不到文件路径的,因为项目在运行当中,整个项目的css文件会被打包进一个文件夹里面。
所以需要把样式放在public文件夹下面,这样样式文件不会被打包。
四、页面样式
当打印的页面长度超出一定范围时,打印时会出现分页的情况,所以在写样式的时候需要考虑把内容分割成高度相等的很多个页面,这样打印出来的内容才不会出现内容被截断的情况(比如表格、图片等)。
一个页面的高度我采用的是1320px,亲测有效,实在不行可以给每页的父盒子一个比较显眼的边框,这样就能清除的看到页面被截断的位置,方便调整内容的布局。
页面的样式我才用的是rem布局,因为打印的时候会把打印的元素放进iframe框架里面,如果样式整体用px的话,在iframe框架里面的页面大小是和屏幕中的大小是不一致的,这会导致打印的时候页面变形。
rem的适配方案我是采用的大屏1920下做的适配:
var docEl = document.documentElement,
let recalc = function () {
var clientWidth = docEl.clientWidth
if (!clientWidth) return
docEl.style.fontSize = 16 * (clientWidth / 1980) + "px"
}
if (!document.addEventListener) return
recalc()
window.addEventListener('resize', recalc, false)
document.addEventListener("DOMContentLoaded", recalc, false)
转载自:https://juejin.cn/post/7208430167219650617