背景
我有一个朋友,接到一个打印需求。现在有n多首古诗词,每首古诗词由(诗名,作者,内容组成),每首古诗词有长有短,内容多少不确定;需要有个打印功能,使用A4纸按顺序打印出全部的古诗词,每张A4纸可以有多首古诗词,每首古诗词(诗名、作者、内容)必须打印在一张A4纸上,不能被分开打印。
技术选型
考虑使用原生window.print实现,想了下,需要考虑各种场景,然后再封装,然后再使用,算了算了,还是使用打印插件吧,就vue3-print-nb了
搭建
新建vue3+vite项目
npm init vue@latest
引入vue3-print-nb
安装
npm i vue3-print-nb
配置
main.ts配置
import print from 'vue3-print-nb'
app.use(print)
打印
mock数据
新建poetries.ts文件,准备好古诗词
渲染数据,添加打印按钮
查看打印效果
一首词被分到两页去了,不满足需求
自动分页
- 通过设置style="page-break-after:always"可以实现打印分页
- 现在就是需要按class="poetry"的div进行分割,考虑到每张A4纸高度固定,所以通过判断每个poetry div的高度累加,当加上某个div的高度后,大于纸张高度时,就给上一个div加上style="page-break-after:always"
实现
const PAGE_HEIGHT = 1124 // A4纸高度
/**
* 打印前,在需要分割的poetry div上添加page-break-after:always
*/
const printPre = () => {
const splitDoms = document.getElementsByClassName('poetry')
let startY = 0 // 占用A4纸的高度,从每页第一个poetry div的top值开始累加
for (let i = 0; i < splitDoms.length; i++) {
const splitDom = splitDoms[i]
const splitValue = splitDom.getBoundingClientRect()
if (startY === 0) {
startY = splitValue.top
}
const pageHeight = splitValue.bottom - startY
// 当加上当前div的高度大于A4纸高度时,给前一个div加上分页标识
if (pageHeight > PAGE_HEIGHT) {
startY = 0
splitDoms[i - 1].style.pageBreakAfter = 'always'
}
}
}
验证
<el-button type="primary" @click="printPre" v-print="print">打印</el-button>
ok,可以简单的交差了