vue print.js打印支持Echarts图表操作

本文介绍了在Vue项目中如何解决Echarts图表打印问题和页面分页,通过`print.js`实现打印功能,包括隐藏指定元素、处理输入元素值、将canvas图表转换为图片等。同时,文章提供了详细的代码示例和步骤,帮助开发者优化打印预览效果,确保每个页面内容完整。
摘要由CSDN通过智能技术生成

print.js

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// 打印类属性、方法定义
/* 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.notPrint ? this.options.notPrint : '.no-print') + "{display:none;}</style>";
 str += "<style>.results{width:100%!important;} .result .title{width:100%;}</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);
 }
 //做分页
 //style="page-break-after: always"
 var pages = document.querySelectorAll('.result');
 for (var k5 = 0; k5 < pages.length; k5++) {
  pages[k5].setAttribute('style', 'page-break-after: always');
 }
 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:' + document.querySelector('.results').clientWidth + 'px;height:0;top:-10px;left:-10px;');
 w = f.contentWindow || f.contentDocument;
 doc = f.contentDocument || f.contentWindow.document;
 doc.open();
 doc.write(content);
 doc.close();
  
 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
用法

this.$print(this.$refs.print,{'notPrint':'.el-button, .el-select'})

我这里取消显示了一些按钮和选择框,

页面是这样

打印出来是这样

可以看到页面是27,我在print.js加了

1
2
3
4
var pages = document.querySelectorAll('.result');
 for (var k5 = 0; k5 < pages.length; k5++) {
  pages[k5].setAttribute('style', 'page-break-after: always');
 }
用来分页,避免每块显示不完整被分割。

补充知识:vue项目中遇到的打印,以及处理重新排版后不显示echarts图片问题。

1. 项目中用到的打印

页面:

css: 控制好宽度一般A4 我调试的是794px多了放不下,小了填不满。当时多页打印的时候,一定要控制好每一个页面内容显示的高度不要超过一个页面,当然根据自己项目来。

由于我的项目是每一个页面固定一个页尾部,所以当显示的时候正常排版显示。但是一旦点击了打印预览需要修改这个区域的css让他固定在每一个页面的底部。

js代码,点击打印后执行(如果右键点击打印就会乱,所以给一个打印预览按钮让用户直接点):打印前先给要打印区域排版,这样预览打印的时候就不会乱,只打印要打印的内容。然后延迟调用系统的打印预览后即便用户没有打印,页面已经排好版了 这个时候右键打印也是可以的了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
print(){
  var that = this;
  $('.operatorBox').css({ //从新绘制这块区域让它固定在每一个页面底部
   'position':'fixed',
   'bottom':'15px'
  })//此方法仅限单页
  var div_print = document.getElementById('print-area');
  var newstr = div_print.innerHTML;
  var oldstr = document.body.innerHTML;
  document.body.innerHTML = newstr;
  // that.showCharts()
  // console.log(this.imgBase)
  // 吧charts图表弄成图片,在挨边替换空白图表
  /* Object.keys(this.imgBase).forEach(function(key){
   document.getElementById(key).innerHTML="<img style='width:100%' src="+that.imgBase[key]+">"
  }); */
 
  setTimeout(function(){
   window.print(); 
   alert('如未打印,请右键选择打印!')
   // window.location.reload();
   // document.body.innerHTML = oldstr;
  },1000)
 }
效果:

取消打印后页面排版已经改变了:

2. echarts打印,echarts如果是直接打印没问题,但是大多数情况是需要重新排列要打印的(就是不直接打印页面显示的,需要自定义打印内容),自定义打印的时候需要拿到要打印的html从新排版,但是这个时候拿不到echarts生成的图的,会显示空白。

所以解决方案是利用echarts的转成图片功能,提前把canvas图表转成图片,记录下来然后在从新排列的时候从新替换,或者是当echarts生成图片的时候立马换掉(这样处理显示效果不好)。

下面我的处理是把得到的图片全部按照echarts的id记录到一个对象里面,到时候在统一获取:

以上这篇vue print.js打印支持Echarts图表操作就是小编分享给大家的全部内容了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值