vue使用printJs实现前端打印,以及打印分页实现

            <div id="content_views" class="htmledit_views">
                <p>在web端可以直接使用原生调用方法调用打印,但是往往需要单独把需要打印的东西拎出来画一个单独的html,而使用printJs则可选中你需要打印的<a href="https://so.csdn.net/so/search?q=%E4%BB%A3%E7%A0%81%E5%9D%97&amp;spm=1001.2101.3001.7020" target="_blank" class="hl hl-1" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;dest&quot;:&quot;https://so.csdn.net/so/search?q=%E4%BB%A3%E7%A0%81%E5%9D%97&amp;spm=1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;searchword\&quot;:\&quot;代码块\&quot;}&quot;}" data-tit="代码块" data-pretit="代码块">代码块</a>,进行页面局部打印</p> 

我的需求为将表格打印出来,并且超过分页数进行分页展示

以下内容参考了其他博主的实现方法,仅供参考

实现打印

1.可以直接使用以下代码,在项目中生成一个js文件,并在main.js中全局引用,以下代码为Vue使用PrintJS实现页面打印功能_this.$print_呆小杰的博客-CSDN博客

呆小杰博主修改后的代码,也可以使用npm下载引用


 
 
  1. /**
  2. * 打印类属性、方法定义,需要先在插件中引入
  3. * 使用示例: 1. 先在mian.js中引入
  4. * 2. 函数中调用this.$print(this.$refs.xxxx)
  5. */
  6. /* eslint-disable */
  7. const Print = function ( dom, options) {
  8. if (!( this instanceof Print)) return new Print(dom, options);
  9. this. options = this. extend({
  10. 'noPrint': '.no-print'
  11. }, options);
  12. if (( typeof dom) === "string") {
  13. this. dom = document. querySelector(dom);
  14. } else {
  15. this. isDOM(dom)
  16. this. dom = this. isDOM(dom) ? dom : dom. $el;
  17. }
  18. this. init();
  19. };
  20. Print. prototype = {
  21. init: function ( ) {
  22. var content = this. getStyle() + this. getHtml();
  23. this. writeIframe(content);
  24. },
  25. extend: function ( obj, obj2) {
  26. for ( var k in obj2) {
  27. obj[k] = obj2[k];
  28. }
  29. return obj;
  30. },
  31. getStyle: function ( ) {
  32. var str = "",
  33. styles = document. querySelectorAll( 'style,link');
  34. for ( var i = 0; i < styles. length; i++) {
  35. str += styles[i]. outerHTML;
  36. }
  37. str += "<style>" + ( this. options. noPrint ? this. options. noPrint : '.no-print') + "{display:none;}</style>";
  38. //str += "<style>html,body,div{height: auto!important;font-size:14px}</style>";
  39. //这边样式要谨慎使用,会覆盖样式表中设置的样式 -->按照自己的业务需求拼接,会覆盖外面H5原先的样式
  40. str += "<style>html,body,div{font-size:14px}</style>";
  41. return str;
  42. },
  43. getHtml: function ( ) {
  44. var inputs = document. querySelectorAll( 'input');
  45. var textareas = document. querySelectorAll( 'textarea');
  46. var selects = document. querySelectorAll( 'select');
  47. for ( var k = 0; k < inputs. length; k++) {
  48. if (inputs[k]. type == "checkbox" || inputs[k]. type == "radio") {
  49. if (inputs[k]. checked == true) {
  50. inputs[k]. setAttribute( 'checked', "checked")
  51. } else {
  52. inputs[k]. removeAttribute( 'checked')
  53. }
  54. } else if (inputs[k]. type == "text") {
  55. inputs[k]. setAttribute( 'value', inputs[k]. value)
  56. } else {
  57. inputs[k]. setAttribute( 'value', inputs[k]. value)
  58. }
  59. }
  60. for ( var k2 = 0; k2 < textareas. length; k2++) {
  61. if (textareas[k2]. type == 'textarea') {
  62. textareas[k2]. innerHTML = textareas[k2]. value
  63. }
  64. }
  65. for ( var k3 = 0; k3 < selects. length; k3++) {
  66. if (selects[k3]. type == 'select-one') {
  67. var child = selects[k3]. children;
  68. for ( var i in child) {
  69. if (child[i]. tagName == 'OPTION') {
  70. if (child[i]. selected == true) {
  71. child[i]. setAttribute( 'selected', "selected")
  72. } else {
  73. child[i]. removeAttribute( 'selected')
  74. }
  75. }
  76. }
  77. }
  78. }
  79. return this. dom. outerHTML;
  80. },
  81. writeIframe: function ( content) {
  82. var w, doc, iframe = document. createElement( 'iframe'),
  83. f = document. body. appendChild(iframe);
  84. iframe. id = "myIframe";
  85. //iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";
  86. iframe. setAttribute( 'style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;');
  87. w = f. contentWindow || f. contentDocument;
  88. doc = f. contentDocument || f. contentWindow. document;
  89. doc. open();
  90. doc. write(content);
  91. doc. close();
  92. var _this = this
  93. iframe. onload = function( ){
  94. _this. toPrint(w);
  95. setTimeout( function ( ) {
  96. document. body. removeChild(iframe)
  97. }, 100)
  98. }
  99. },
  100. toPrint: function ( frameWindow) {
  101. try {
  102. setTimeout( function ( ) {
  103. frameWindow. focus();
  104. try {
  105. if (!frameWindow. document. execCommand( 'print', false, null)) {
  106. frameWindow. print();
  107. }
  108. } catch (e) {
  109. frameWindow. print();
  110. }
  111. frameWindow. close();
  112. }, 10);
  113. } catch (err) {
  114. console. log( 'err', err);
  115. }
  116. },
  117. isDOM: ( typeof HTMLElement === 'object') ?
  118. function ( obj) {
  119. return obj instanceof HTMLElement;
  120. } :
  121. function ( obj) {
  122. return obj && typeof obj === 'object' && obj. nodeType === 1 && typeof obj. nodeName === 'string';
  123. }
  124. };
  125. const MyPlugin = {}
  126. MyPlugin. install = function ( Vue, options) {
  127. // 4. 添加实例方法
  128. Vue. prototype. $print = Print
  129. }
  130. export default MyPlugin

根据博主提供的方法进行编写

绑定ref,使用this.$print(this.$refs.xxx)使用,可以将这个代码块中你需要的元素打印出来,

  • 不需要打印的元素加上 class="no-print",那么打印时就会将设置了此类名的元素忽略

这块可以参考博主改装后的js

实现分页

我这边使用的是el-dialog中绘制我需要的打印预览显示,有不需要预览页面展示的可以把元素从代码上隐藏,至于方式可以自己探索例如position:absolute,top:100000px,或者其他假删除方式,不要用v-if等真删除,节点删除后ref获取不到无法打印.


 
 
  1. getPrintDataInfo( data) {
  2. const arrCopy = JSON. parse( JSON. stringify(data))
  3. arrCopy. forEach( (items, indexs) => {
  4. items. printTime = this.$moment(). format( 'YYYY-MM-DD HH:ss:mm') //这里是我的需要的打印时间
  5. if (items. list. length % this. page. size === 0) {
  6. this. totalPage = items. list. length / this. page. size //this.page.size是我列表的分页显示条数,这边使用为打印时一个页面的条数
  7. } else {
  8. this. totalPage = parseInt(items. list. length / this. page. size) + 1
  9. }
  10. for ( let i = 1; i <= this. totalPage; i++) {
  11. const obj = JSON. parse( JSON. stringify(items))
  12. obj. list = this. getTableDataByPaging(i, this. page. size, items. list). data
  13. obj. currentPage = this. getTableDataByPaging(i, this. page. size, items. list). page
  14. this. dataList. push(obj)
  15. }
  16. })
  17. },
  18. // 打印清单分页数据处理
  19. getTableDataByPaging( page = 1, pageSize = 10, totalData = []) {
  20. const { length } = totalData
  21. const tableData = {
  22. data: [],
  23. page,
  24. pageSize,
  25. length
  26. }
  27. if (pageSize >= length) { // pageSize大于等于总数据长度,说明只有1页数据或没有数据
  28. tableData. data = totalData
  29. tableData. page = 1 // 直接取第一页
  30. } else { // pageSize小于总数据长度,数据多余1页
  31. const num = pageSize * (page - 1) // 计算当前页(不含)之前的所有数据总条数
  32. if (num < length) { // 如果当前页之前所有数据总条数小于(不能等于)总的数据集长度,则说明当前页码没有超出最大页码
  33. const startIndex = num // 当前页第一条数据在总数据集中的索引
  34. const endIndex = num + pageSize - 1 // 当前页最后一条数据索引
  35. tableData. data = totalData. filter( (_, index) => index >= startIndex && index <= endIndex) // 当前页数据条数小于每页最大条数时,也按最大条数范围筛取数据
  36. } else { // 当前页码超出最大页码,则计算实际最后一页的page,自动返回最后一页数据
  37. const size = parseInt(length / pageSize) // 取商
  38. const rest = length % pageSize // 取余数
  39. if (rest > 0) { // 余数大于0,说明实际最后一页数据不足pageSize,应该取size+1为最后一条的页码
  40. tableData. page = size + 1 // 当前页码重置,取size+1
  41. tableData. data = totalData. filter( (_, index) => index >= (pageSize * size) && index <= length)
  42. } else if (rest === 0) { // 余数等于0,最后一页数据条数正好是pageSize
  43. tableData. page = size // 当前页码重置,取size
  44. tableData. data = totalData. filter( (_, index) => index >= (pageSize * (size - 1)) && index <= length)
  45. } // 注:余数不可能小于0
  46. }
  47. }
  48. return tableData
  49. },

在页面上v-for循环


 
 
  1. <div ref= "printLend" class= "pitchman-box ">
  2. <div v-for="(item,indexs) in dataList" :key="indexs" class="printClass" style="page-break-after: always;">
  3. <el-row>
  4. <h2>{{ item.title }} </h2>
  5. </el-row>
  6. <el-row class="print_info">
  7. <el-col :span="6"> <span>借出人: </span>{{ item.name }} </el-col>
  8. <el-col :span="6"> <span>联系方式: </span>{{ item.phone }} </el-col>
  9. <el-col :span="6"> <span>借出时间: </span>{{ item.lendTime }} </el-col>
  10. <el-col :span="6"> <span>押金: </span>{{ item.price }} </el-col>
  11. </el-row>
  12. <table border="1" width="100%" height="100%" cellspacing="0" cellpadding="0">
  13. <thead>
  14. <!--表头,这里就是正常的表格循环-->
  15. <th>序号 </th>
  16. </thead>
  17. <tbody align="center">
  18. <tr v-for="(items,index) in item.list" :key="index">
  19. <td>{{ index +1 }} </td>
  20. </tr>
  21. </tbody>
  22. </table>
  23. <el-row class="logistics-bottom">
  24. <el-col style="text-align: left;" :span="12">打印时间:{{ item.printTime }} </el-col>
  25. <el-col style="text-align: right;" :span="12">第{{ item.currentPage }}页,共{{ totalPage }}页 </el-col>
  26. </el-row>
  27. <!-- <div style="page-break-after: always;" /> -->
  28. </div>

style="page-break-after: always;"在你需要分下一页打印页的地方加上这个样式属性

 

这是我的最终预览效果,打印 A4纸上效果也很完美,一个标题就是一张纸

值得注意的是,并不建议给整个你需要的打印元素设置高度超出隐藏显示滚动条.样式方面可以自己斟酌怎么实现.一般打印出来的效果不会有太大出入

 大体代码实现就是这样,如果有错误欢迎指正,有更好的实现方法也可以交流一下,表格预览时有更好办法可以实现流体高度也请赐教,感谢!!!

Vue.js是一种流行的JavaScript框架,它可以帮助开发人员构建交互式Web应用程序。而print.js是一个简单的JavaScript库,它可以帮助我们轻松地打印HTML元素。本文将介绍如何在Vue.js应用程序中使用print.js实现分页打印。 步骤一:安装print.js 首先,我们需要安装print.js库。可以使用npm来安装: ``` npm install print-js ``` 步骤二:创建一个组件 接下来,我们需要创建一个Vue组件,用于显示我们要打印的内容。在这个例子中,我们将创建一个简单的表格来演示打印。 ```html <template> <div> <table> <thead> <tr> <th>ID</th> <th>Name</th> <th>Age</th> </tr> </thead> <tbody> <tr v-for="person in people" :key="person.id"> <td>{{ person.id }}</td> <td>{{ person.name }}</td> <td>{{ person.age }}</td> </tr> </tbody> </table> <button @click="printTable">Print</button> </div> </template> <script> import printJS from "print-js"; export default { data() { return { people: [ { id: 1, name: "Alice", age: 25 }, { id: 2, name: "Bob", age: 30 }, { id: 3, name: "Charlie", age: 35 }, { id: 4, name: "David", age: 40 }, { id: 5, name: "Eve", age: 45 }, ], }; }, methods: { printTable() { printJS({ printable: "table", type: "html", css: "/path/to/style.css", scanStyles: true, }); }, }, }; </script> ``` 在组件中,我们定义了一个表格来显示数据。我们还定义了一个按钮,当用户点击按钮时,我们将调用printTable方法来打印表格。 步骤三:使用print.js打印printTable方法中,我们使用print.js库来打印表格。我们需要传递以下参数给printJS方法: - printable:要打印的元素的ID或HTML字符串。 - type:要打印的内容的类型,可以是html、image、pdf或json。 - css:打印时要使用的样式表的URL或路径。 - scanStyles:是否扫描打印内容中的样式。 在本例中,我们将表格的ID传递给printable参数,将type设置为html,将样式表的路径传递给css参数,并将scanStyles设置为true。 完成后,我们就可以点击按钮来打印表格了。print.js将会自动分页打印所有内容。 总结 在本文中,我们介绍了如何在Vue.js应用程序中使用print.js实现分页打印。我们创建了一个简单的表格来演示打印。我们使用npm来安装print.js,然后在Vue组件中使用它来打印表格。当然,print.js还有许多其他的功能,可以满足我们的各种打印需求。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值