浏览的的打印功能目前只有chrome做的最好,会生成a4纸大小的打印预览,而火狐会将打印预览变成电脑屏幕的100%;
所以最好用chrome来实现
使用场景:我的页面是基于table做的,如下图,需要两个功能 1.导出excel 2.直接点击打印按钮,要求可以调用浏览器的打印功能。
由于页面比较复杂,使用java后台生成表格需要配置的东西过多,比较麻烦,所以我就想到了用html页面直接生成excel,简单实用
关于java后台方法对excel的读取和导出请看 https://blog.youkuaiyun.com/lianzhang861/article/details/83092835,后台方法适合一些格式统一的表格,如后台管理系统中的用户列表啥的,复杂的页面建议使用下述前端方法实现
点击打印按钮,生成的打印预览
点击导出excel,生成的excel
实现方法:
1.html 由于最后要导出excel,excel对html中的table支持很好,且excel支持大部分的css,所以建议直接将要导出的页面用table标签来写,下面是我的例子
<html>
<head>
<%@include file="/common/jsp/meta.jsp" %>
<title>添加录入</title>
</head>
<body>
<article class="page-container" >
<div class="col-xs-12 col-sm-12 radius">
<div class="cl pd-5 bg-1 bk-gray mt-20">
<span>
<a href="javascript:;" id="download" class="btn btn-primary radius">
<i class="Hui-iconfont"></i>导出EXCEL
</a>
</span>
<span>
<a href="javascript:;" onclick="printout()" class="btn btn-primary radius">
<i class="Hui-iconfont"></i>打印
</a>
</span>
</div>
</div>
<div id="printContent">
<style>
.page-container{
width:800px;margin:0 auto;
padding:30px;
}
#printContent{
margin-top:20px;
}
table{
border-collapse: collapse;
width:100%;
}
table td{
font-size:14px;padding:10px;
}
.punishTable tfoot td{
font-size:16px;font-weight:bold;
}
.punishTable td{
text-align: center;
border:1px solid #666;align:center;
font-size:14px;height:60px;
}
</style>
<!--想要没有页眉页脚就加这段css-->
<style media="print">
@page{
size:210mm 290 mm;
margin:0mm auto;
}
</style>
<%--<input type="hidden" value="${assessPunish.ID}" name="ID">--%>
<div class="row table">
<table class="headTable">
<tr>
<td colspan="6" style="height:70px;font-size:20px;font-weight: bold;text-align: center;">
${assessPunish.regionGroupName}考核扣罚表
</td>
</tr>
<tr>
<td colspan="6" height="50" align="left" style="text-indent: 2em">依照【移集团 合同[${assessPunish.CONTRACT_NO}] 号】《合同名称》</td>
</tr>
<tr>
<td colspan="6" height="50" align="left">
现由地市业务支撑中心对维修公司服务的移动公司营业设备配件维修工作进行认定,考核扣罚结果如下:
</td>
</tr>
<tr>
<td colspan="2" align="left" height="60">
地市:${assessPunish.regionGroupName}
</td>
<td colspan="4" align="left">
维修时间段:${assessPunish.REPAIR_DATE}
</td>
</tr>
</table>
<table class="punishTable">
<thead>
</thead>
<thead>
<tr>
<td>认定大项</td>
<td>描述</td>
<td>单位</td>
<td>数量</td>
<td width="60">单价</td>
<td width="100">小计</td>
</tr>
</thead>
<tbody id="punishContent">
</tbody>
<tfoot>
<tr>
<td colspan="5">
合计扣罚(不含增值税)
</td>
<td class="sum">${assessPunish.TOTAL}</td>
</tr>
</tfoot>
</table>
<table class="headTable">
<tr>
<td colspan="2" align="left" height="200">
业务支撑中心主管签字:
</td>
<td colspan="4" align="left">
维修公司主管签字:
</td>
</tr>
<tr>
<td colspan="2" align="left" height="200">
业务支撑中心经理签字:
</td>
<td colspan="4" align="left">
维修公司分管经理签字:
</td>
</tr>
</table>
</div>
</div>
<div class="row cl text-c">
<input onClick="removeIframe();" class="btn btn-primary radius ml-10" type="button" value=" 关闭 ">
</div>
</article>
注意:因为打印和导出表格都是要展示页面主题内容,而一般页面上还有导航栏,按钮啥的,所以要将没用的元素剔除,只留需要打印的内容 在元素 .printContent中
看下面就知道是将 printContent中的内容重新生成一个html,所以其css需要写在printContent中,否则新页面将没有样式
另外打印预览时会自动出现页眉页脚,不需要的话加一段css就可以解决
<style media="print">
@page{
size:210mm 290 mm;
margin:0mm auto;
}
</style>
2.调用浏览器打印接口js
//按打印按钮调用浏览器打印接口
function printout() {
// debugger;
var newWindow;
//打开一个新的窗口
newWindow = window.open();
// 是新窗口获得焦点
newWindow.focus();
//保存写入内容
var newContent = "<html><head><meta charset='utf-8'/><title></title></head><body>"
newContent += document.getElementById("printContent").outerHTML;
newContent += "</body></html>"
// 将HTML代码写入新窗口中
newWindow.document.write(newContent);
newWindow.print();
// close layout stream
newWindow.document.close();
//关闭打开的临时窗口
newWindow.close();
return false;
};
原理就是用window.print()将制定去内容渲染到一个新窗口
3.导出Excel 的 js
// 使用outerHTML属性获取整个table元素的HTML代码(包括<table>标签),然后包装成一个完整的HTML文档,设置charset为urf-8以防止中文乱码
var html = "<html><head><meta charset='utf-8' /></head><body>" + document.getElementById("printContent").outerHTML + "</body></html>";
// 实例化一个Blob对象,其构造函数的第一个参数是包含文件内容的数组,第二个参数是包含文件类型属性的对象
var blob = new Blob([html], {
type: "application/vnd.ms-excel"
});
var a = document.getElementById("download");
// 利用URL.createObjectURL()方法为a元素生成blob URL
a.href = URL.createObjectURL(blob);
// 设置文件名,目前只有Chrome和FireFox支持此属性
a.download = "公司考核扣罚表.xls";
原理:
(1).blob对象本质上是js中的一个对象,里面可以储存大量的二进制编码格式的数据。创建blob对象本质上和创建一个其他对象的方式是一样的,都是使用Blob() 的构造函数来进行创建。 构造函数接受两个参数:
第一个参数为一个数据序列,可以是任意格式的值。
第二个参数是一个包含两个属性的对象{ type: MIME的类型, endings: 决定第一个参数的数据格式,可以取值为 "transparent" 或者 "native"(transparent的话不变,是默认值,native 的话按操作系统转换) 。 }
也就是说将新创建的html转换成了blob对象,type为表格
(2).URL.createObjectURL()方法会根据传入的参数创建一个指向该参数对象的URL. 这个URL的生命仅存在于它被创建的这个文档里. 新的对象URL指向执行的File对象或者是Blob对象.
语法: objectURL = URL.createObjectURL(blob || file);
参数:
File对象或者Blob对象
这里大概说下File对象和Blob对象:
File对象,就是一个文件,比如我用input type="file"标签来上传文件,那么里面的每个文件都是一个File对象.
Blob对象,就是二进制数据,比如通过new Blob()创建的对象就是Blob对象.又比如,在XMLHttpRequest里,如果指定responseType为blob,那么得到的返回值也是一个blob对象.
总之,URL.createObjectURL()中可以传blob对象,也可以传file对象,然后生成一个指向文件的url,将此url赋给a的href,相当于浏览器顺着这个url找到文件,而此文件是个表格,就会直接下载表格而不是打开页面
同理,input上传图片,得到file对象,用URL.createObjectURL()生成文件的url,赋值给img的src,就能预览上传的图片,详情请看 https://blog.youkuaiyun.com/lianzhang861/article/details/80283120
*复制下面html并打开就可以先体验一下大体功能
<!DOCTYPE >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body link="blue" vlink="purple">
<table id="print-content" border="1" cellpadding="0" cellspacing="0" style='border-collapse:collapse;table-layout:fixed;'>
<style type="text/css">
#red{
color:red
}
</style>
<colgroup>
<col width="80 ">
<col width="80 ">
<col width="150 ">
<col width="80 ">
<col width="150 ">
<col width="80 ">
<col width="80 ">
</colgroup>
<tr height="20" style="text-align: center;font-size:18px">
<td colspan="7">会签单</td>
</tr>
<tr height="20" style="text-align: center;font-size:14px">
<td></td>
<td colspan="2">流转</td>
<td></td>
<td colspan="3">会议</td>
</tr>
<tr height="20" style="text-align: center;font-size:14px">
<td>名称</td>
<td colspan="2">自动获取</td>
<td>编号</td>
<td colspan="3">自动获取</td>
</tr>
<tr height="20" style="text-align: center;font-size:14px">
<td>主持</td>
<td colspan="2">自动获取</td>
<td>类型</td>
<td colspan="3">自动获取</td>
</tr>
<tr height="20" style="text-align: center;font-size:14px">
<td>人</td>
<td colspan="2">自动获取</td>
<td>日期</td>
<td colspan="3">自动获取</td>
</tr>
<tr height="100" style="text-align: center;font-size:14px">
<td rowspan="5">内容</td>
<td colspan="6" rowspan="5" id="red">自动获取</td>
</tr>
<tr/>
<tr/>
<tr/>
<tr/>
<tr height="20" style="text-align: center;font-size:14px">
<td>备注</td>
<td colspan="6">自动获取</td>
</tr>
<tr height="24" style="text-align: center;font-size:16px">
<td colspan="7">意见</td>
</tr>
<tr height="24" style="text-align: center;font-size:14px">
<td>序号</td>
<td>人</td>
<td>部门</td>
<td>意见</td>
<td>时间</td>
<td>节点</td>
<td>状态</td>
</tr>
<tr height="20" style="text-align: center;font-size:14px">
<td>1</td>
<td>顾</td>
<td>办公室</td>
<td>同意!</td>
<td>2018/5/14 15:21</td>
<td></td>
<td>已提交</td>
</tr>
</table>
<!-- 下载方法1.超链接_导出文件-->
<a id="print-click">超链接_导出表格</a>
<input type="button" onclick="printout()" value="打印"></input>
<script>
// 使用outerHTML属性获取整个table元素的HTML代码(包括<table>标签),然后包装成一个完整的HTML文档,设置charset为urf-8以防止中文乱码
var html = "<html><head><meta charset='utf-8' /></head><body>" + document.getElementById("print-content").outerHTML + "</body></html>";
// 实例化一个Blob对象,其构造函数的第一个参数是包含文件内容的数组,第二个参数是包含文件类型属性的对象
var blob = new Blob([html], {
type: "application/vnd.ms-excel"
});
var a = document.getElementById("print-click");
// 利用URL.createObjectURL()方法为a元素生成blob URL
a.href = URL.createObjectURL(blob);
// 设置文件名,目前只有Chrome和FireFox支持此属性
a.download = "会签单.xls";
//打印具体实现代码
function printout() {
debugger;
var newWindow;
//打开一个新的窗口
newWindow = window.open();
// 是新窗口获得焦点
newWindow.focus();
//保存写入内容
var newContent = "<html><head><meta charset='utf-8'/><title>打印</title></head><body>"
newContent += document.getElementById("print-content").outerHTML;
newContent += "</body></html>"
// 将HTML代码写入新窗口中
newWindow.document.write(newContent);
newWindow.print();
// close layout stream
newWindow.document.close();
//关闭打开的临时窗口
newWindow.close();
return false;
};
</script>
</body>
</html>