vue项目使用Print.js插件实现PDF文件打印

简介: vue项目使用Print.js插件实现PDF文件打印

一,Print.js介绍

Print.js主要是为了帮助我们在应用程序中直接打印PDF文件,而不需要离开界面,也不需要使用嵌入。对于用户不需要打开或下载PDF文件的特殊情况,只需要打印即可。

例如,当用户请求打印在服务器端生成的报告时,这是有用的一种情况。这些报告以PDF文件的形式发回。打印这些文件之前无需打开这些文件。Print.js提供了一种在我们的应用程序中快速打印这些文件的方法。

PDF文件必须与您的应用程序所在的域相同。Print.js在打印文件之前使用iframe加载文件,因此,它受到同源策略的限制。这有助于防止跨站点脚本(XSS)攻击。

  • 原生js,不依赖其它库
  • 可指定打印(或不打印)区域
  • 支持css样式(内联、外联、嵌入)
  • 支持input(radio/checkbox/text)、select、textarea值获取

二,下载安装

Print.js下载地址:https://download.csdn.net/download/weixin_43025151/87606898

或者使用npm安装

npm install print-js --save

引入到自己的项目中:

import print from 'print-js'

三,配置项

Print.js将接受一个对象作为参数,您可以在其中配置一些选项:

四,实现思路与项目示例

实现思路:将目标区域的dom/css添加到空iframe中,打印该iframe。

1) pdf的打印
<button type="button" onclick="printJS('docs/printjs.pdf')">
        Print PDF
     </button>
2)base64
<button type="button" onclick="printJS({printable: base64, type: 'pdf', base64: true})">
    Print PDF with Message
  </button>
3)html的打印
<form method="post" action="#" id="printJS-form">
     ...
   </form>
   <button type="button" onclick="printJS('printJS-form', 'html')">
     Print Form
   </button>
4)图片的打印
<img src="images/print-01.jpg" />
   printJS('images/print-01-highres.jpg', 'image')
   
   //打印多张图片
    printJS({
      printable: ['images/print-01-highres.jpg', 'images/print-02-highres.jpg', 'images/print-03-highres.jpg'],
      type: 'image',
      header: 'Multiple Images',
      imageStyle: 'width:50%;margin-bottom:20px;'
     })
5)打印json
someJSONdata = [
        {
           name: 'John Doe',
           email: 'john@doe.com',
           phone: '111-111-1111'
        },
        {
           name: 'Barry Allen',
           email: 'barry@flash.com',
           phone: '222-222-2222'
        },
        {
           name: 'Cool Dude',
           email: 'cool@dude.com',
           phone: '333-333-3333'
        }
     ]
    <button type="button" onclick="printJS({printable: someJSONdata, properties: ['name', 'email', 'phone'], type: 'json'})">
        Print JSON Data
     </button>

整个vue文件:

<template>
  <div id="app">
    <div id="divPrint" class="mainbox print">
      <!-- <div style="font-size: 25px; margin-top: 80px" align="center">
        整改通知单
      </div> -->
      <div align="center" style="margin: 0; padding: 0; width: 100%">
        <table>
          <tr style="border: none">
            <td colspan="2">工程项目:xx</td>
            <td style="text-align: right; padding-left: 10px;" colspan="2">编号:xx</td>
          </tr>
          <tr style="border: none">
            <td colspan="2">整改单位:xx</td>
            <td style="text-align: right; padding-left: 10px;" colspan="2">编号:xx</td>
          </tr>
          <tr style="border: none">
            <td colspan="2">整改内容:xx</td>
            <td style="text-align: right; padding-left: 10px;" colspan="2">编号:xx</td>
          </tr>
        </table>
      </div>
    </div>
    <div style="margin-top: 20px; text-align: center">
      <button @click="print()">pdf打印</button>
    </div>
  </div>
</template>
<script>
import printJS from "print-js";
export default {
  name: "printing",
  data() {
    return {};
  },
  methods: {
    print() {
      printJS({
        printable: "divPrint", // 标签元素id
        type: "html", // 打印类型
        header: "整改通知单", // '表单名称',
        targetStyles: ["*"],
        style: "@page {margin:0 10mm};", // 可选-打印时去掉眉页眉尾
        ignoreElements: ["no-print"], // 接受打印父 html 元素时应忽略的 html id 数组。
        properties: null,
      });
    },
  },
};
</script>
<style lang="scss">
#app {
  width: 100%;
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  .mainbox {
    width: 100%;
    margin: 0 auto;
  }
}
</style>

点击打印按钮后,出现PDF预览。

五,分析:

经过多次实战演练:

如果要打印的样式比较复杂,并且有字体图标等,建议选择第一种;

如果打印表格数据,比如element表格,还可以按需勾选进行打印,选择第二种打印方式比较好。

再分享一个强制分页打印,每页只打印固定的内容:

只需要在要分页打印的末尾加上:

<div style="page-break-after:always"></div>

即可

代码如下:

<div id="printTable"
                   v-for="(arr, i) in saveListArray"
                   :key="i"
                   style="position: relative; background-color:rgb(236,230,232);margin-top:5px;"
                   :class="printWay == 3 ? 'printTableActive' : ''"
                   :style="{
                    width: containerWidth + 'mm',
                    height: containerHeight + 'mm',
                   }">
                <el-container v-for="(item, index) in arr"
                              :key="index">
                  <div id="printColor"
                       v-bind:style="{
                    width: Number(item.GoodInvoiceDetailWidth) + 'mm',
                    height: item.GoodInvoiceDetailHeight + 'mm',
                    'line-height': item.GoodInvoiceDetailHeight + 'mm',
                    left: Number(item.GoodInvoiceDetailCoordinateX) + Number(x) + 'mm',
                    top: Number(item.GoodInvoiceDetailCoordinateY) + Number(y) + 'mm',
                    color: item.GoodInvoiceDetailColour + '',
                    'font-size': item.GoodInvoiceDetailSize + 'mm',
                    'font-family': item.GoodInvoiceDetailFont + '',
                    'text-align': item.GoodInvoiceDetailPosition + '',
                    'border-top': item.GoodFramSize*0.1+0.1 + 'mm' + item.GoodFramSolidlineIf + item.borderTcolor,
                    'border-bottom': item.GoodFramSize*0.1+0.1 + 'mm' + item.GoodFramSolidlineIf + item.borderBcolor,
                    'border-left': item.GoodFramSize*0.1+0.1 + 'mm' + item.GoodFramSolidlineIf + item.borderLcolor,
                    'border-right': item.GoodFramSize*0.1+0.1 + 'mm' + item.GoodFramSolidlineIf + item.borderRcolor,
                    overflow: item.overflow,
                    }"
                       style=" display: inline-block;
                    text-align:left;
                    position: absolute;
                    cursor: move;">
                    <div v-if="item.GraphContent"><img :src="item.GraphContent"
                           style="width:100%;height:100%;margin-top:4px;"></div>
                    <div v-else
                         style="margin-right:3px;margin-left:3px;">{{ item.GoodInvoiceDetailName }}</div>
                  </div>
                </el-container>
                <div style="page-break-after:always"></div>
              </div>

下面展示两种图片:(一张没有加分页的,和加了分页的区别)

六,注意

不支持background-color背景色打印,试试用background-image代替,只在浏览器中预览打印,未实际打印过, 公司无公用打印机,低级浏览器兼容性待验证。

目录
相关文章
|
17天前
|
JavaScript 前端开发 内存技术
js文件的入口代码及需要入口代码的原因
js文件的入口代码及需要入口代码的原因
30 0
|
2月前
|
前端开发 JavaScript API
前端JS读取文件内容并展示到页面上
前端JavaScript使用FileReader API读取文件内容,支持文本类型文件。在文件读取成功后,可以通过onload事件处理函数获取文件内容,然后展示到页面上。
52 2
前端JS读取文件内容并展示到页面上
|
2月前
|
JavaScript 前端开发 数据安全/隐私保护
混淆指定js文件
【9月更文挑战第26天】JavaScript 混淆旨在保护代码知识产权、减小文件体积和提高安全性。方法包括变量名和函数名混淆、代码压缩、控制流平坦化及字符串加密。常用工具如 UglifyJS 和 JScrambler 可实现这些功能。然而,混淆可能带来兼容性和调试困难等问题,需谨慎使用并确保法律合规。
|
9天前
|
存储 JSON JavaScript
Vue.js开发中基于localStorage与sessionStorage的本地存储利器:Vue-ls插件使用详解
Vue.js开发中基于localStorage与sessionStorage的本地存储利器:Vue-ls插件使用详解
23 0
|
9天前
|
JavaScript 前端开发 应用服务中间件
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
72 0
|
2月前
|
移动开发 JavaScript 前端开发
js之操作文件| 12-5
js之操作文件| 12-5
|
JavaScript 前端开发
Bootstrap3.0学习第二十三轮(JavaScript插件——警告框)
详情请查看 http://aehyok.com/Blog/Detail/29.html   个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章链接:http://www.cnblogs.com/aehyok/p/3981965.html 感谢您的阅读,如果您对我的博客所讲述的内容有兴趣,那不妨点个推荐吧,谢谢支持:-O。
717 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
84 2
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
105 4
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
77 4