vue 中使用print.js导出pdf操作

1.print.js

// 打印类属性、方法定义
/* eslint-disable */
const Print = function (dom, options) {
 if (!(this instanceof Print)) return new Print(dom, options);

 this.options = this.extend({
  'noPrint': '.no-print'
 }, options);

 if ((typeof dom) === "string") {
  this.dom = document.querySelector(dom);
 } else {
  this.isDOM(dom)
  this.dom = this.isDOM(dom) ? dom : dom.$el;
 }

 this.init();
};
Print.prototype = {
 init: function () {
  var content = this.getStyle() + this.getHtml();
  this.writeIframe(content);
 },
 extend: function (obj, obj2) {
  for (var k in obj2) {
   obj[k] = obj2[k];
  }
  return obj;
 },

 getStyle: function () {
  var str = "",
   styles = document.querySelectorAll('style,link');
  for (var i = 0; i < styles.length; i++) {
   str += styles[i].outerHTML;
  }
  str += "<style>" + (this.options.noPrint ? this.options.noPrint : '.no-print') + "{display:none;}</style>";
  str += "<style>html,body,div,#preview-main,.report{width:100%!important;height: auto!important;font-size:14px}</style>";

  return str;
 },

 getHtml: function () {
  var inputs = document.querySelectorAll('input');
  var textareas = document.querySelectorAll('textarea');
  var selects = document.querySelectorAll('select');
  var canvass = document.querySelectorAll('canvas');

  for (var k = 0; k < inputs.length; k++) {
   if (inputs[k].type == "checkbox" || inputs[k].type == "radio") {
    if (inputs[k].checked == true) {
     inputs[k].setAttribute('checked', "checked")
    } else {
     inputs[k].removeAttribute('checked')
    }
   } else if (inputs[k].type == "text") {
    inputs[k].setAttribute('value', inputs[k].value)
   } else {
    inputs[k].setAttribute('value', inputs[k].value)
   }
  }

  for (var k2 = 0; k2 < textareas.length; k2++) {
   if (textareas[k2].type == 'textarea') {
    textareas[k2].innerHTML = textareas[k2].value
   }
  }

  for (var k3 = 0; k3 < selects.length; k3++) {
   if (selects[k3].type == 'select-one') {
    var child = selects[k3].children;
    for (var i in child) {
     if (child[i].tagName == 'OPTION') {
      if (child[i].selected == true) {
       child[i].setAttribute('selected', "selected")
      } else {
       child[i].removeAttribute('selected')
      }
     }
    }
   }
  }

  //canvass echars图表转为图片
  for (var k4 = 0; k4 < canvass.length; k4++) {
   var imageURL = canvass[k4].toDataURL("image/png");
   var img = document.createElement("img");
   img.src = imageURL;
   img.setAttribute('style', 'max-width: 100%;');
   img.className = 'isNeedRemove'
   // canvass[k4].style.display = 'none'
   // canvass[k4].parentNode.style.width = '100%'
   // canvass[k4].parentNode.style.textAlign = 'center'
   canvass[k4].parentNode.insertBefore(img,canvass[k4].nextElementSibling);
  }

  return this.dom.outerHTML;
 },

 writeIframe: function (content) {
  var w, doc, iframe = document.createElement('iframe'),
   f = document.body.appendChild(iframe);
  iframe.id = "myIframe";
  //iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";
  iframe.setAttribute('style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;');
  w = f.contentWindow || f.contentDocument;
  doc = f.contentDocument || f.contentWindow.document;
  doc.open();
  doc.write(content);
  doc.close();

  // 避免重复打印echarts
  var removes = document.querySelectorAll('.isNeedRemove');
  for (var k = 0; k < removes.length; k++) {
   removes[k].parentNode.removeChild(removes[k]);
  }

  var _this = this
  iframe.onload = function(){
   _this.toPrint(w);
   setTimeout(function () {
    document.body.removeChild(iframe)
   }, 100)
  }
 },

 toPrint: function (frameWindow) {
  try {
   setTimeout(function () {
    frameWindow.focus();
    try {
     if (!frameWindow.document.execCommand('print', false, null)) {
      frameWindow.print();
     }
    } catch (e) {
     frameWindow.print();
    }
    frameWindow.close();
   }, 10);
  } catch (err) {
   console.log('err', err);
  }
 },
 isDOM: (typeof HTMLElement === 'object') ?
  function (obj) {
   return obj instanceof HTMLElement;
  } :
  function (obj) {
   return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
  }
};
const MyPlugin = {}
MyPlugin.install = function (Vue, options) {
 // 4. 添加实例方法
 Vue.prototype.$print = Print
}
export default MyPlugin

自己页面的样式添加

str += "<style>html,body,div,#preview-main,.report{width:100%!important;height: auto!important;font-size:14px}</style>";

解决echarts图表多点击一次 就会多一张bug

img.className = 'isNeedRemove'

canvass[k4].parentNode.insertBefore(img,canvass[k4].nextElementSibling);

var removes = document.querySelectorAll('.isNeedRemove');

2.用法

//调用系统打印机
print () {
  this.$print(this.$refs.print) // 使用
},

题外话

1.在自己需要的页面引用打印页面 这边我打印页面时preview.vue页面

 <!-- 预览 -->
<Modal v-model="previewModal" fullscreen :mask-closable="false" :closable="false">
  <preview ref="print" :previewEditOldForm="previewEditForm"></preview>
  <div slot="footer" class="btn">
    <Button type="text" @click="closePreview">关闭</Button>
    <Button type="primary" @click="print">打印</Button>
  </div>
</Modal> 
import Preview from '../operation_report/Preview'
export default {
 components: {
     Preview
  }
}

获取别的页面的表单内容 初始化

export default {
 data() {
 return{
  previewEditForm: {},
 }
  }
}
// 父组件向子组件传值
 on: {
   click: () => {
     // 父组件向子组件传值
     this.previewEditForm = params.row;
     setTimeout(() => {
       this.$refs.print.queryById();
       this.$refs.print.eventOverviews();
       this.previewModal=true;
     }, 2000)
   }
 }

隐藏打印页面不需要的按钮

<style scoped>
  @media print {
    .btn{
      display: none;
    }
  }
</style>

4.打印内容有echarts时 内容不自适应 调整width

width: 210mm;

最终如下

补充知识:使用vue-cli脚手架 与 axios 请求数据 配置代理进行跨域访问数据问题

首先利用脚手架vue-cli 把项目搭建好 然后在 利用控制台 在项目中安装http-proxy-middleware中间件作为代理

控制台安装中间代理命令 如下:

npm install -S http-proxy-middleware

然后按照下图 一步步配置

配置结束 是不是 还是不行?

在这里 要关闭下项目 重新在控制台 npm run dev 重启项

目 就大功告成了

一点心得 体会 写得不好 还请大家多多包涵

以上这篇vue 中使用print.js导出pdf操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • vue导出html、word和pdf的实现代码

    导出的页面组件如下: <template> <div id="resumeId"> <resumeHtml ref="resume" @on-download="download"/> </div> </template> 1.导出html 方法: 1)获取要导出的组件页面的css把它设置成js变量一文本并通过export导出 2)获取要导出组件页面的html的dom标签代码,通过thi

  • vue实现在线预览pdf文件和下载(pdf.js)

    最近做项目遇到在线预览和下载pdf文件,试了多种pdf插件,例如jquery.media.js(ie无法直接浏览) 最后选择了pdf.js插件(兼容ie10及以上.谷歌.安卓,苹果) 强烈推荐改插件,以下介绍用法 (1)下载插件 下载路径: pdf.js (2)将下载构建后的插件放到文件中public(vue/cli 3.0) (3)在vue文件中直接使用,贴上完整代码 <template> <div class="wrap"> <iframe :src=

  • 解决vue-pdf查看pdf文件及打印乱码的问题

    前言 vue中简单使用vue-pdf预览pdf文件,解决打印预览乱码问题 vue-pdf 使用 安装 npm install --save vue-pdf 引入 import pdf from "vue-pdf 自定义封装pdf预览组件 <template> <el-dialog :visible.sync="pdfDialog" :close-on-click-modal="false" :show-close="false&

  • vue 中使用print.js导出pdf操作

    1.print.js // 打印类属性.方法定义 /* eslint-disable */ const Print = function (dom, options) { if (!(this instanceof Print)) return new Print(dom, options); this.options = this.extend({ 'noPrint': '.no-print' }, options); if ((typeof dom) === "string") {

  • vue中后端做Excel导出功能返回数据流前端的处理操作

    项目中有一个导出功能的实现,用博客来记录一下.因为需求对导出表格的数据格式和样式有要求,所以这个导出功能放到后端来做,而且后端返回的是数据流,所以需要处理成想要的表格并导出来. 先看下效果图: 页面效果: 点击 导出Excel 调用导出接口成功了: 后台返回的数据流,一堆看不懂的乱码: 接下来要处理这堆乱码,因为用到的地方多,所以在util.js文件里封装了一个公共方法并抛出: 虽然vue里有封装好的请求接口的方法,但这里要单独用axios,所以先在util.js里引入axios import

  • js节流防抖应用场景,以及在vue中节流防抖的具体实现操作

    故事背景: 项目有个需求是输入框在输入的时候进行搜索,展示下拉数据,但是没必要输入一个字都进行搜索,所以想到了在输入结束200毫秒后再进行搜索,从而引出来了 js的节流(throttle),防抖(debounce),在网上想找个现成的用下,但是好多都不对,于是就自己搞了. 先看看概念 函数防抖(debounce): 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时:典型的案例就是输入搜索:输入结束后n秒才进行搜索请求,n秒内又输入的内容,就重新计时. 函数节流(throttle)

  • JS导出PDF插件的方法(支持中文、图片使用路径)

    在WEB上想做一个导出PDF的功能,发现jsPDF比较多人推荐,遗憾的是不支持中文,最后找到pdfmake,很好地解决了此问题.它的效果可以先到http://pdfmake.org/playground.html查看.在使用过程中,还发现图片的插入是相对繁琐的一件事. 针对这些问题,本文的主要内容可分为三部分: •pdfmake的基本使用方法: •如何解决中文问题; •如何通过指定图片地址插入图片. pdfmake的基本使用方法 1.包含以下两个文件 <script src="build/

  • 如何在vue中使用pdfjs预览pdf文件

    目录 前言 在写项目的过程中,偶尔会有使用到pdf的文件,当我们想看pdf文件的时候,你的操作是不是先把pdf文件下载下来,通过电脑安装的专用于打开pdf的软件来查看pdf文件呢.如果有个需求说不要让用户安装软件呢,毕竟还是有很多用户不知道怎么安装软件或者这个东西需要什么东西才能打开嘛.ok,有了这样的需求那我们是不是也得去实现嘛,毕竟这理由咱也没法反驳啊. 思考 既然都提出来了,那就想想怎么使用咯.既然需要用到pdf.不知道有没有关于js能够操作的库文件来帮我呢?果断一百度,咱们今天的主角就来

  • Vue中接收二进制文件流实现pdf预览的方法

    后台Controller @RequestMapping("/getPDFStream") @ResponseBody public void getPDFStream(HttpServletRequest request,HttpServletResponse response) { try { request.setCharacterEncoding("utf-8"); } catch (UnsupportedEncodingException e) { log

  • vue中使用vue-print.js实现多页打印

    本文主要介绍了vue项目中使用print.js打印,解决多页,分页,打印预览样式修改等问题. 引入安装vue-print.js cnpm i vue-printjs --save-dev 解决打印多页只出现一页问题 由于打印插件存在问题,如果打印文件超出一页,只显示一页,所以我们需要修改print.js源文件,所以只能手动下载vue-print.js到本地,做一些修改,然后引入到项目中,不能使用npm安装 下载 print.js https://github.com/zxc19890923/pr

  • vue中的.$mount('#app')手动挂载操作

    在Vue构造函数时,需要配置一个el属性,如果没有没有el属性时,可以使用.$mount('#app')进行挂载. 配置了el属性: new Vue({ el:"#app", router }); 如果没有配置el属性,可以使用手动挂载$mount("#app") new Vue({ router }).$mount('#app'); var vm = new Vue({ router }); vm.$mount('#app'); 补充知识:Vue手动挂载组件$mo

  • 在vue中使用eslint,配合vscode的操作

    不管是多人合作还是个人项目,代码规范是很重要的.这样做不仅可以很大程度地避免基本语法错误,也保证了代码的可读性.这所谓工欲善其事,必先利其器,个人推荐 eslint+vscode 来写 vue,绝对有种飞一般的感觉. 每次保存,vscode就能标红不符合eslint规则的地方,同时还会做一些简单的自我修正.安装步骤如下: 首先安装eslint插件 安装并配置完成 ESLint 后,我们继续回到 VSCode 进行扩展设置,依次点击 文件 > 首选项 > 设置 打开 VSCode 配置文件,添加

  • 如何在vue中使用video.js播放m3u8格式的视频

    @[toc] 注意: "vue": "^2.6.11", "video.js": "^7.10.2", "videojs-contrib-hls": "^5.15.0", "mux.js": "^5.7.0" 一.安装 yarn add video.js yarn add videojs-contrib-hls // 这是播放hls流需要的插件 y

随机推荐