vue实现对指定dom进行打印

1,767 阅读3分钟

需求

  1. 打印指定dom内容
  2. dom内容中有表格,表格的表头或内容在html中,如果过长,显示省略号,在打印预览需要通过换行的方式完全显示通过: @media print {...} 编写单独的打印预览样式实现

打印指定dom内容,可选方案

  1. print-js
  2. vue-print-nb
  3. html2canvas + print-js

最终采用的方案

print-js

为什么没有选择vue-print-nb, 因为使用过程中遇到了个bug, width:100%, 在打印预览时,实际宽度变成了A3纸的宽度,在A4纸上,有部分内容被隐藏了

为什么没有选择html2canvas+print-js, 因为我打印预览的样式与界面样式虽然总体一致,但对于省略号内容,打印预览是需要显示出来的, 而html2canvas并无法做到这一点

print-js 使用注意事项

样式问题:

如果需要dom样式与网页中的保持一致,那么只需做如下设置

printJS({
  printable: 'printEmpDetail',
  type: 'html',
  documentTitle: '',
  // 继承原来所有样式(如果你打印预览的样式与页面样式一致,那么可以仅配置scanStyles为['*'],css和scanStyles都不需要指定)
  targetStyles: ['*']
})

如果打印的内容不需要样式, 那么只需要做如下设置

printJS({
  printable: 'printEmpDetail',
  type: 'html',
  documentTitle: '',
  // 不使用样式(这是是指不使用当前页面原有样式,要设置成false,防止页面样式和P7EmpDetailInfoPrint.css同时生效时,样式之间冲突)
  scanStyles: false
})

如果打印的内容需要单独设置样式, 那么只需要做如下设置

printJS({
  printable: 'printEmpDetail',
  type: 'html',
  documentTitle: '',
  // 不使用样式(这是是指不使用当前页面原有样式,要设置成false,防止页面样式和P7EmpDetailInfoPrint.css同时生效时,样式之间冲突)
  scanStyles: false,
  // 单独指定打印预览时的样式(注意这里使用的是css文件,如果打印预览中还使用了ui组件(如:element-ui),如果ui组件的样式未生效,则还需引入ui组件的样式)[支持数组]
  css: '/web/P7EmpDetailInfoPrint.css'
})

css属性请确保指定的是css文件,如果使用的scss且在开发环境,需要手动先将scss文件,编译为css文件,然后再通过css属性应用,如果打印预览需要ui框架的样式,那么需要通过cdn方式,将ui框架的样式引入

页尾出现表格时,表头被重复渲染了两次,导致表头样式出现问题

table {
  page-break-inside: avoid;
}

未加这个样式控制前的效果

image.png

加了该样式控制之后的效果

image.png

后续补充

问题一: 页尾出现表格时,表头被重复渲染了两次,导致表头样式出现问题, 这个问题, 单纯通过css,无法完全解决,需要通过js进行动态计算,要找到所有表头接近页面底部的表格,全部强制让其进入新页面

问题二: 换页时, 存在可能被分割为两半的元素,这个也需要通过js进行动态计算,找到所有接近页面底部的元素,全部强制让其进入新页面

这两个问题,是同一种解决方案, 解决方式参考:(但貌似都没写这些js是怎么插入的?执行时机是什么.所以,问题依然没解决)

实现前端页面局部转 pdf 及 打印 加分页防止内容截断

jsPDF 分页分割问题踩坑

vue 打印被截断的问题解决方案

page-break-after:always;解决window.print打印断页问题——已解决

参考文章以及相关文章

运用CSS打印样式进行排版设计

如何设置页面打印的CSS样式【浏览器打印】?以及禁止用户打印的两三种方法

使用print.js进行自定义打印(可加上样式)

vue 使用打印(print-js)