vue html页面打印功能vue-print-nb

vue 项目中,HTML 页面打印功能. 在项目中, 有时需要打印页面的表格,

在网上找了一个打印组件 vue-print-nb
 
本博客源码: https://github.com/shengbid/vue-print, 这里面只放了打印组件的代码, 只需要这个功能的下载这个
https://github.com/shengbid/vue-demo  这个项目里平时博客写的一些功能的代码都放在里面, 有需要可以下载看看, 有帮助的话点个 star 哈
使用方式
安装 npm install vue-print-nb --save

在 main.js 文件中注册
import Print from 'vue-print-nb'

Vue.use(Print);

页面中使用, 给需要打印的容器加一个 id, 打印按钮传入这个 id
html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<div id="printMe" style="background:red;">
        <p>葫芦娃,葫芦娃</p>
        <p>一根藤上七朵花 </p>
        <p>小小树藤是我家 啦啦啦啦 </p>
        <p>叮当当咚咚当当 浇不大</p>
        <p> 叮当当咚咚当当 是我家</p>
        <p> 啦啦啦啦</p>
        <p>...</p>
        <div class="describle">
          <el-form :model="form" :rules="rules" ref="from" class="demo-ruleForm">
            <el-form-item label="姓名:" prop="name">
              <el-input v-model="form.name"></el-input>
            </el-form-item>
            <el-form-item label="描述:" prop="describle">
              <el-input
                :disabled="detail"
                type="textarea"
                :rows="4"
                :maxlength="2000"
                placeholder=""
                v-model="form.describle">
              </el-input>
            </el-form-item>
          </el-form>
        </div>
    </div>
 
    <button v-print="'#printMe'">Print local range</button>

  

点击打印按钮, 就可以打印页面了
   
 
在使用这个插件过程中遇到一个问题, 普通的 input 标签内容展示没问题,textarea 文本域这种内容就展示不出来, 检查了一下插件, 发现作者在给表单赋值的时候用的是 value 值, 这种赋值对于一些双标签的表单就无效, 需要修改一下
PS: 现在的新版本作者已经修复了这个问题, 使用新版本的同学可以忽略
 

 
这种直接改包的方法也不太好, 如果其他人下载你的代码, 也需要修改包, 所以, 最好把这个包拿出来, 放在文件中, 在 main.js 直接引用
 
main.js 引用  import Print from '@/utils/vue-print-nb/'
 
 
新增
最近有收到问题, 打印页面的标题是怎么设置的, 我自己试了一下, 发现使用之前的方法是 undefined, 去官网看了下, 作者又修改了这个组件, 现在变得更加可配置化了
 
 
现在传入的是一个对象,
 
打印内容比较多时, 使用 vue-print-nb 可能会出现排版问题,
这里补充一种先转换成图片在打印的方法:
 
<template>
  <div>
    <div id="printMe" ref="printContent">
      <ul class="content">
        <li> 轻轻的我走了,</li>
        <li> 轻轻的我走了,</li>
        <li> 轻轻的我走了,</li>
        <li> 轻轻的我走了,</li>
        <li> 轻轻的我走了,</li>
        <li> 轻轻的我走了,</li>
        <li> 轻轻的我走了,</li>
        <li> 轻轻的我走了,</li>
      </ul>
    </div>
    <el-button type="primary" @click="toImg"> 转图片打印 </el-button>
    <el-button v-print="printObj" type="primary"> 直接打印 </el-button>
    <img style="margin-top:20px;" :src="img" alt="">
  </div>
</template>

<script>
import html2canvas from
'html2canvas' // 转图片打印需要先安装 html2Canvas 和 print-js
import printJS from
'print-js'
export
default {
data() {
return {
img:
'',
printObj: {
id:
'printMe',
popTitle:
'打印',
extraCss:
'https://www.google.com,https://www.google.com',
extraHead:
'<meta http-equiv="Content-Language"content="zh-cn"/>'
}
}
},
watch: {
},

created() {
},
methods: {
toImg() { // 转图片打印
html2canvas(this.$refs.printContent, {
backgroundColor:
null,
useCORS:
true,
windowHeight: document.body.scrollHeight
}).then((canvas)
=> {
// let url = canvas.toDataURL('image/jpeg', 1.0)
const url = canvas.toDataURL()
this.img = url
printJS({
printable: url,
type:
'image',
documentTitle:
'打印图片'
})
console.log(url)
})
}
}
}
</script>

 

 
 
补充内容: 因为我自己有段时间没使用了, 对于现在版本的一些问题也没遇到, 最近有看到博友提了几个问题,
这两天有时间就看了下, 下面把一些自己总结的问题和解决方法附上, 可能图片比较多, 不过我也是希望尽可能详细描述原因而不只是给个解决方法.
相关 githup 源码也会尽快更新, 有帮助记得点歌 star 哦
 
PS: 因为这些问题是组件原本存在的, 修改需要改组件源码, 不要在 node_modlues 下直接修改, 把这个 vue-print-nb 安装包复制出来, 放在你自己的项目文件下,
一开始复制的时候可能没有 src 这个目录, 没什么关系, 运行一下就会自动生成的, 拿出来之后, 也要修改 mian.js 的引入方法, 引入 lib 下的 tag_textarea.umd 这个文件
 
 
 
一. 打印多一页空白页
 
现在使用很有可能会多一页空白页, 我自己看代码结合资料, 是因为创建的 iframe 有 height: 100% 的元素, 图片里的就是打印时生成的 iframe 元素
   
 
在页面看一下, 因为我这个页面设置了 HTML: height 100%, 你可以看下你的页面, 也可能是 body 100% 或者其他元素, 这个打印组件是把你所有引入的 css 样式 copy 过去, 所以也会继承你设置的样式
 
  
 
解决方法, 给 HTML 设置一个高度, 覆盖默认的 100%
 
  
 
再次打印, 我多增加了一些内容, 也没有多一页空白页, 这个高度设置不会影响你打印内容的真实高度, 如果你实际有两页, 这里也会是两页
  
   
 
这样, 打印多一页空白页就解决了, 这个方法是我这里测试有效, 不能保证适用所有场景, 不过多一页空白页, 大概率就是有元素高度设置的问题
 
二. 回调方法没有生效
 
回调方法是新版本增加的, 我自己试了下, 并不能生效, 在代码里看了下, 并没有调用传入的回调方法, 也没有返回东西, 在代码里加一下
 
 
 
组件引用:
  
 
页面打印
 
 
 
在这里更正一下, 修改文件, 因为我测试用的项目是有对 es5 语法进行转译的,tag_textarea.umd 是 es5 语法, 就可以使用, 但是我之后放到另一个 vue 项目, 引入报了 es5 的语法错误,
这里也非常感谢博友的评论提醒, 差点误导大家, 如果你的项目不支持 es5 语法, 引入 src 下的文件, 修改 print.js 和 printarea.js 这两个文件, 改动地方一样可以搜索一下代码, 我 githup 上
使用的是 src 下的代码, 有需要可以参考https://github.com/shengbid/vue-print,
 
三. 隐藏不需要打印的内容
如果打印的时候不需要打印全部内容, 可以再打印之前, 删除不需要打印的元素, 具体方法
 
在 print.js 文件里新增一个属性 ignoreClass, 用来隐藏不需要打印的元素
 
 
在 printarea.js 里也要增加, 再增加一个去除隐藏元素的方法
 
 
在组件使用时, 传入这个元素
 
 
打印效果

ps: 2021/9/11 更新内容

1. 增加表单打印内容, 在页面增加了一个 form 表单, 如果你直接打印,CheckBox 和 radio 可能不能显示, 可以设置一下打印属性, 勾选上背景图片, 就可以显示了

 

2. 增加 el-table 打印,el-table 默认单元格的宽度是 px, 这在打印时会出现显示不全问题

 
 
可以处理一下, 将宽度改为百分比
 
注意, 你需要先将 td 的宽度添加百分比, 详细写法可以看我 githup 的例子
处理过的打印预览
 
更新: 打印标题显示
如果打印时不想要标题, 在打印设置中取消勾选页眉和页脚. 这个是打印网页自带的, 代码中好像不能直接去掉.

 

 

结语: 我写的这些处理方法也并不是唯一的, 这个组件的原理其实就是将你页面的元素 copy 过去, 重新创建一个打印页面, 你完全可以在调用打印方法前对元素进行修改

 这两个对应的 githup 代码都已经更新了, 可以 clone 下来看看, 有用帮我点个 star 哈.   有问题留言, 有时间我会一起整理更新,

https://github.com/shengbid/vue-print

https://github.com/shengbid/vue-demo/tree/master/src/views/demo/print