1、前言

  前端打印pdf就是使用原生的window.print()方法实现,这里有几个问题你会遇到。

  • 打印纸张大小,不同纸张大小,你需要相应调整表格宽度和最大分页高度
  • 分页时机,不适当的话会导致表格跨页分断
  • 背景色打印,这个是不能设置的,但是通过css属性可以实现
  • 打印时的css设置

前端环境:vue+element ui

2、代码实例

<template><div><div id="toolBox"><div class="toolBox"><el-button type="primary" plain size="small" style="margin-top: 20px;width: 130px;" @click="saveAsPdf">打印PDF</el-button></div></div><div :id="tableConfig.pdfId" :class="tableConfig.pdfClass" v-for="(tableConfig,configIndex) in tableConfigList":key="configIndex"><div class="thisPage"><h1 style="text-align: center">window.print方法demo</h1></div><div class="thisPage" v-for="(data,index) in dataList" :key="index" :style="tableConfig.tableStyle"><el-table :data="data" :header-cell-style="tableHeader" border><el-table-column column-key="col1_" prop="col1_" label="第一列"></el-table-column><el-table-column column-key="col2_" prop="col2_" label="第二列"></el-table-column><el-table-column column-key="col3_" prop="col3_" label="第三列"></el-table-column><el-table-column column-key="col4_" prop="col4_" label="第四列"></el-table-column><el-table-column column-key="col5_" prop="col5_" label="第五列"></el-table-column></el-table><el-divider></el-divider></div></div></div>
</template><script>export default {name: 'windowPrint',data() {return {data: {col1_: '',col2_: '',col3_: '',col4_: '',col5_: ''},dataList: [],tableHeader: {'color': 'aliceblue','background-color': 'slateblue'},tableConfigList: [{pdfId: 'comment_report',pdfClass: '',tableStyle: `'100%'`}, {pdfId: 'print_report',pdfClass: 'comment_hide',tableStyle: `width:1100px;`}]}}, methods: {getData() {let keys = Object.keys(this.data);let size = 35;for (let i = 0; i < size; i++) {this.dataList[i] = new Array();for (let j = 0; j < i; j++) {let tempData = {};keys.forEach(key => {tempData[key] = key + i + j;})this.dataList[i][j] = tempData;}}this.dataList[size] = [];},saveAsPdf() {let commentReport = document.getElementById("comment_report");let printReport = document.getElementById("print_report");let toolBox = document.getElementById("toolBox")toolBox.className = "print_hide";commentReport.className = "print_hide";printReport.className = "print_content";let thisPage = printReport.querySelectorAll('.thisPage');let curHeight = 0;let a3PageHeight = 1558;for (let item of thisPage) {let contentHeight = parseInt(window.getComputedStyle(item).height)if ((curHeight + contentHeight) > a3PageHeight) {console.log("a page")item.style.pageBreakBefore = "always";// 清空curHeight = 0;}if(contentHeight<a3PageHeight){curHeight += contentHeight}else {curHeight = contentHeight % a3PageHeight}console.log("item", contentHeight, curHeight);}setTimeout(() => {window.print();toolBox.className = "toolBox";printReport.className = "comment_hide";}, 1000)}},created() {this.getData();}}
</script><style scoped>.toolBox {position: fixed;top: 0;right: 0;width: 100%;height: 50px;line-height: 50px;text-align: right;background: rgba(0, 0, 0, 0.3);box-shadow: 2px 2px 3px #e4e4e4;z-index: 9999;}.toolBox .el-button {margin: 0;transform: translate(-50%, -40%);}@page {size: A3;margin: 0;}.comment_hide {display: none;}@media print {.print_hide {display: none;}.print_content {margin-top: 20px !important;-webkit-print-color-adjust: exact;-moz-print-color-adjust: exact;-ms-print-color-adjust: exact;print-color-adjust: exact;}}
</style>

3、代码解析

  • 背景色打印

需要打印的内容包含在这个css属性里面的class即可

-webkit-print-color-adjust: exact;
-moz-print-color-adjust: exact;
-ms-print-color-adjust: exact;
print-color-adjust: exact;
  • 打印时的css设置
    @media print{}这个css里面的属性会在打印时才会运行渲染

  • 打印纸张大小

   @page {size: A3;margin: 0;}

在@page里面可以设置纸张大小,这里设置的是A3大小,至于宽高,网页打印的宽高好像是跟屏幕有关,这里设置宽1100px刚好更我屏幕打印时的宽度相当,每页高度这里选用1558px,高度好像相对稳定。

  • 分页时机
    这里分页是根据你的控件高度计算而知的,当累计高度高于分页高度则将当前控件前插入分页符,设置方法如下:
item.style.pageBreakBefore = "always";

通过设置style为page-break-before:always实现
ps:网上全是page-break-after:always实现的,难道page-break-before不香么

  • html结构
    1、这里是通过tableConfigList这个配置变量,控制两个大的div的id、class和table的宽度
    2、每个需要分页的控件都用class="thisPage"标记,便于查找
    3、绘制两次需要网页内容,一次是用于用户看的,一次是用于打印的隐藏内容,打印的时候,设置隐藏用户看的,显示打印的内容,实现直接打印,而不影响用于观感

  • 解析saveAsPdf方法

     saveAsPdf() {let commentReport = document.getElementById("comment_report");let printReport = document.getElementById("print_report");let toolBox = document.getElementById("toolBox")toolBox.className = "print_hide";commentReport.className = "print_hide";printReport.className = "print_content";let thisPage = printReport.querySelectorAll('.thisPage');let curHeight = 0;let a3PageHeight = 1558;for (let item of thisPage) {let contentHeight = parseInt(window.getComputedStyle(item).height)if ((curHeight + contentHeight) > a3PageHeight) {console.log("a page")item.style.pageBreakBefore = "always";// 清空curHeight = 0;}if(contentHeight<a3PageHeight){curHeight += contentHeight}else {curHeight = contentHeight % a3PageHeight}console.log("item", contentHeight, curHeight);}setTimeout(() => {window.print();toolBox.className = "toolBox";printReport.className = "comment_hide";}, 1000)}

1、获取用于显示的report内容和用于打印的report内容
2、将toolBox、commentReport、printReport对应class的html元素,设置class为print时的才会渲染的class
3、控制page-break-before:always属性的设置,当加上当前元素,超过页高度,则当前元素设置style为page-break-before:always,提示print方法这里要分页
4、处理单页超过打印纸张大小问题,这里超过了,没有去处理,只处理了超过后下一个元素加上不超过纸张高度下,追加上下一个元素
5、最后要设置延时,不然会渲染不足。


demo地址:https://github.com/Hitvz/pdfoutput
参考博客:vue+element打印页面功能

window.print打印pdf相关推荐

  1. window.print打印部分无法显示

    1.window.print单选框无法显示 $("body").attr("style","-webkit-print-color-adjust: e ...

  2. window.print()打印网页局部内容

    用window.print()打印网页局部内容 今天客户让添加个打印证照功能,直接用window.print()打印的是整个页面,而用以下方法就可以只打印证明了 <!--window.print ...

  3. 关于window.print打印分页功能

    平常window.print分页一般打印时用到page-break-after:always; 打印的样式设置在 <style type="text/css" media=& ...

  4. 使用window.print()打印局部页面,ifrme打印ie报错

    问题: 使用window.print();打印页面,将不需要的数据隐藏,将需要的数据显示,打印完成之后将刚才隐藏的数据还原,显示的数据隐藏, 谷歌浏览器.部分ie能一气呵成,  火狐浏览器以及少数ie ...

  5. js的window.print()打印背景图片,打印背景图片无法显示

    js的window.print()打印背景图片 题目描述 js的window,print()打印背景图片给body加了图片地址之后,非要设置浏览器打印选项里面设置背景图形打印才行,怎么通过js去设置默 ...

  6. js window.print() 打印图片,图片有时候不显示

    window.print() 打印网络资源图片不显示 解决方法 等待网络资源图片加载完成后,在打印 $(doc).find('.qrcode-down').load(function () {ifra ...

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

    今天用户提出一个关于window.print()打印的问题: 如下图所示:在打印断页的部分,会出现数据打印不全的情况.打印预览与实际打印的情况还有有所区别. 注意一点:如果想要实现window.pri ...

  8. window.print()打印网页中指定内容

    <!DOCTYPE html> <html><head><meta charset=" utf-8"><meta name=& ...

  9. 指定window.print 打印区域

    第一种方法:指定不打印区域 使用CSS,定义一个.noprint的class,将不打印的内容放入这个class内. 细如下: ? 1 2 3 <style media=print type=&q ...

  10. window.print打印指定区域

    doPrint() {// let originHtml = window.document.body.innerHTML;//需要打印的元素let printHtml = document.getE ...

最新文章

  1. VC6.0使用中遇到的一些问题
  2. 【OpenCV】直方图应用:直方图均衡化,直方图匹配,对比直方图
  3. 引导界面图标好大_游戏里那些图标和界面,原来是这么设计出来的?
  4. python交互式绘图比较_python – 基于Tkinter和matplotlib的交互式绘图
  5. python asyncio_Python 中的异步编程:Asyncio
  6. Linux内核源代码分析——vmstat核心代码注释
  7. tolua#是Unity静态绑定lua的一个解决方案
  8. C++语言基础 例程 派生类的声明与构成
  9. 解析文本文件 r 与 rb 模式的区别(Python)
  10. 解决initializing java tooling(1%)
  11. EditRocket for Mac(源代码编辑器)v4.5.10
  12. ixgbe驱动不支持三方兼容光模块SFP+SFP+或者QSFP的解决方案
  13. PFC2D学习笔记——geometry的使用
  14. cAdvisor资源监控工具入门
  15. 理解FPS游戏中的矩阵方框透视自瞄
  16. java中符号常量_Java中符号常量
  17. 通过检查table_locks_waited和table_locks_immediate状态变量来分析系统上的表锁定争夺
  18. 钉钉一行代码_利用Python快速搭建钉钉和邮件数据推送系统
  19. week10 day1 JavaScript
  20. 数智经济转型下如何抢占文创发展新机遇?中国移动咪咕聚焦新一代年轻人需求

热门文章

  1. 超高分辨率大屏拼接工作站硬件选型
  2. 网易云那些触动人心的经典热评
  3. 传统的期货交易方式为计算机撮合成交,[期货知识]期货价格是怎么形成的-计算机撮合成交 - 南方财富网...
  4. 安卓手机怎样安装apk应用
  5. shell的课程大纲
  6. Linux系统管理命令(1)accton的使用
  7. ecshop 模板支持php,ecshop模板文件不支持php语句解决办法
  8. python opencv生成背景透明图标
  9. 【解局】瑞幸向上,盒马向下
  10. zabbix 参数 脚本_zabbix 自定义脚本短信报警