介绍一个最新的web打印组件

wdmsyf 2017-06-18 05:43:25

B/S应用系统的报表打印一直以来都是一个难题,以前常规的思路是通过在浏览器中安装ActiveX插件以获得直接驱动打印机的能力。
但是,随着浏览器的发展,越来越多的浏览器厂商禁止安装ActiveX,以避免因ActiveX组件导致的各种安全问题。
最近发现一个web打印组件叫做康虎云报表(一个打印组件而已,不知道为什么叫云报表???),比较完美地解决了在浏览器端不用ActiveX而获得与C/S系统一样的打印能力。
本报表系统不需要在浏览器安装任何插件,只需通过JavaScript即可实现报表精确打印以及打印过程免人工介入。

康虎云报表使用前提条件:
1、IE6以上版本、Chrome(谷歌浏览器)4.0以上版本、Firefox 4.0以上版本、Opera 11以上版本、Safari 5.0.2以上版本、iOS 4.2以上版本
或使用Chrome内核、Firefox内核的浏览器均可直接使用本打印系统;
2、在进行打印前,需要先设计好打印模板(模板设计器请见第五节);
3、打印数据必须Json的格式发送给打印服务器,并且数据必须满足指定的格式(见下文);

数据格式说明:
下面以一个跨境电商快递面单数据为例解释一下数据各项的含义;
{
"template": "waybill.fr3", /*打印模板文件名。除了指定模板文件以外,还支持把模板嵌入到数据文件中,以实现在服务器端灵活使用打印模板,格式如下:*/
/*"template": "base64:QTBBRTNEQTE3MkFFQjIzNEFERD<后面省略>" */

"ver": 4, /*数据模板文件版本*/
"Copies": 3, /*打印份数,支持指定打印份数*/
"Duplex": 1, /*是否双面打印,0:默认,不双面,1:垂直,2:水平,3:单面打印(simplex)*/
"Printer": "priPrinter", /*指定打印机,本系统支持在数据文件中指定打印机,也支持在打印模板中指定打印机*/
"PageNumbers": "", /*要打印的页码范围,同打印机的打印设置里的格式相同,例如:"1,2,3"表示打印前3页, “2-5”:表示打印第2到5页,“1,2,4-8”表示打印第1、2、4到8页*/
"Preview": 1, /*是否预览,跟主界面上选择“预览”效果相同,取值为0:不预览,1:预览*/

"Tables":[ /*数据表数组*/
{
"Name": "Table1", /*表名*/
"Cols": [ /*字段定义*/
{
"type": "str", /*字段类型,可选值:String,Str,Integer,Int,Smallint,Float,Long, Blob,*/
/*对于图片、PDF等使用Blob类型,并把值进行Base64编码,并加前缀:*/
/* "base64/pdf:" 字段值是PDF; "base64/jpg:" 字段值是jpg; "base64/png:" 字段值是png; "base64/gif:" 字段值是gif; */
"size": 255, /*字段长度*/
"name": "HAWB#", /*字段名称,必须与打印模板中的打印项名称相同*/
"required": false /*字段是否必填*/
},
{ "type": "int", "size": 0, "name": "NO", "required": false },
{ "type": "float", "size": 0, "name": "报关公司面单号", "required": false },
{ "type": "integer", "size": 0, "name": "公司内部单号", "required": false },
{ "type": "str", "size": 255, "name": "发件人", "required": false },
{ "type": "str", "size": 255, "name": "发件人地址", "required": false },
{ "type": "str", "size": 255, "name": "发件人电话", "required": false },
{ "type": "str", "size": 255, "name": "发货国家", "required": false },
<由于字数限制,这里省略N字>
{ "type": "blob", "size": 0, "name": "附件", "required": false }
],

"Data": [ /*数据行定义,每一行含义见上面的字段定义*/
{
"HAWB#": "860014010055",
"NO": 1,
"报关公司面单号": 200303900791,
"公司内部单号": 730293,
"发件人": "NAKAGAWA SUMIRE 2",
"发件人地址": " 991-199-113,Kameido,Koto-ku,Tokyo",
"发件人电话": "03-3999-3999",
"发货国家": "日本",
"收件人": "张三丰",
"收件人地址": "上海市闵行区虹梅南路1660弄蔷薇八村99号9999室",
"收件人电话": "182-1234-8888",
"收货人证件号码": null,
"收货省份": null,
"总计费重量": 3.2,
"总件数": 13,
"申报总价(CNY)": null,
"申报总价(JPY)": null,
"件数1": 10,
"品名1": "纸尿片",
"单价1(JPY)": null,
"单位1": null,
"申报总价1(CNY)": null,
"申报总价1(JPY)": null,
"件数2": null,
"品名2": null,
"单价2(JPY)": null,
"单位2": null,
"申报总价2(CNY)": null,
"申报总价2(JPY)": null,
"ID": 1,
"附件": "base64/pdf:JVBER<中间省略N字>lRU9GCg==",
},
{
"HAWB#": "860014010035",
"NO": 2,
"报关公司面单号": 200303900789,
"公司内部单号": 730291,
"发件人": "NAKAGAWA SUMIRE",
"发件人地址": " 991-199-113,Kameido,Koto-ku,Tokyo",
"发件人电话": "03-3999-3999",
"发货国家": "日本",
"收件人": "张无忌",
"收件人地址": "上海市闵行区虹梅南路1660弄蔷薇八村88号8888室",
"收件人电话": "182-1234-8888",
"收货人证件号码": null,
"收货省份": null,
"总计费重量": 3.2,
"总件数": 13,
"申报总价(CNY)": null,
"申报总价(JPY)": null,
"件数1": 10,
"品名1": "纸尿片",
"单价1(JPY)": null,
"单位1": null,
"申报总价1(CNY)": null,
"申报总价1(JPY)": null,
"件数2": null,
"品名2": null,
"单价2(JPY)": null,
"单位2": null,
"申报总价2(CNY)": null,
"申报总价2(JPY)": null,
"ID": 2,
"附件":"base64/gif:R0lGODlhrgC<中间省略N字>AQA7"
}
]
},
{
"Name": "Table2",
"Cols": [
{ "type": "int", "size": 0, "name": "NO", "required": false },
{ "type": "float", "size": 0, "name": "订单编号", "required": false },
{ "type": "integer", "size": 0, "name": "下单日期", "required": false },
{ "type": "str", "size": 255, "name": "下单平台", "required": false }
],
"Data": [
{
"NO": 1,
"订单编号": 200303900791,
"下单日期": "2017-01-20",
"下单平台": "天猫"
},
{
"NO": 2,
"订单编号": 200303900792,
"下单日期": "2017-01-20",
"下单平台": "京东"
}
]
}
]
}


康虎云报表有两种数据传输模式,一种是被较新浏览器(IE10以上版本,或Chrome、Firefox等),称之为模式1;另一种是为了兼容较旧浏览器(IE6致IE9)而设计的模式,称之为模式2。如果不是特别旧的浏览器,建议用模式1。下面是调用例子,代码主要都是标准的HTML和javascript。

调用示例:

<!-- 模式1 -->
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>康虎云报表系统测试</title>
</head>

<body>
<div style="width: 100%;text-align:center;">
<h2>康虎云报表系统</h2>
<h3>打印测试(模式1)</h3>
<div>
<input type="button" id="btnPrint" value="打印" onClick="doSend(_reportData);" />
</div>
</div>
<div id="output"></div>
</body>

<script type="text/javascript">
//定义数据脚本
var _reportData = '{"template":"waybill.fr3","Cols":[{"type":"str","size":255,"name":"HAWB#","required":false},<这里省略1000字> ]}';

//在浏览器控制台输出调试信息
console.log("reportData = " + _reportData);
</script>
<script language="javascript" type="text/javascript" src="cfprint.min.js"></script>
<script language="javascript" type="text/javascript" src="cfprint_ext.js"></script>
<script language="javascript" type="text/javascript">
/**下面四个参数必须放在myreport.js脚本后面,以覆盖myreport.js中的默认值**/
var _delay_send = 1000; //发送打印服务器前延时时长,-1则表示不自动打印
var _delay_close = 1000; //打印完成后关闭窗口的延时时长, -1则表示不关闭
var cfprint_addr = "127.0.0.1"; //打印服务器监听地址
var cfprint_port = 54321; //打印服务器监听端口
</script>
</html>

<!-- 模式2 -->
<?php
//如果有php运行环境,只需把该文件扩展名改成 .php,然后上传到web目录即可在真实服务器上测试
header("Access-Control-Allow-Origin: *");
?>

<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>康虎云报表系统测试</title>
<style type="text/css">
#output {font-size: 12px; background-color:#F0FFF0;}
</style>
</head>

<body>
<div style="width: 100%;text-align:center;">
<h2>康虎云报表系统(Ver 1.3.0)</h2>
<h3>打印测试(模式2)</h3>
<div style="line-height: 1.5;">
<div style="width: 70%; text-align: left;">
<b>一、首先按下列步骤设置:</b><br/>
1、运行打印服务器;<br/>
2、按“停止”按钮停止服务;<br/>
3、打开“设置”区;<br/>
4、在“常用参数-->服务模式”中,选择“模式2”;<br/>
5、按“启动”按钮启动服务。
</div>
<div style="width: 70%; text-align: left;">
<b>二、按本页的“打印”按钮开始打印。</b><br/>
</div><br/>
<input type="button" id="btnPrint" value="打印" /><br/><br/>

<div style="width: 70%; text-align: left; font-size: 12px;">
由于JavaScript在不同域名下访问会出现由来已久的跨域问题,所以正式部署到服务器使用时,要解决跨域问题。<br/>
对于IE8以上版本浏览器,只需增加一个reponse头:Access-Control-Allow-Origin即可,而对于php、jsp、asp/aspx等动态语言而言,增加一个response头是非常简单的事,例如:<br/>
<b>在php:</b><br/><span style="color: red;">
<?php <br/>
header("Access-Control-Allow-Origin: *");<br/>
?><br/>
</span>
<b>在jsp:</b><br/><span style="color: red;">
<% <br/>
response.setHeader("Access-Control-Allow-Origin", "*"); <br/>
%><br/>
</span>
<b>在asp.net中:</b><br/><span style="color: red;">
Response.AppendHeader("Access-Control-Allow-Origin", "*");
</span>,<br/>其他语言里,大家请自行搜索“ajax跨域”。而对于IE8以下的浏览器,大家可以自行搜索“IE6+Ajax+跨域”寻找解决办法吧,也可以联系我们帮助。
</div>
</div>
</div>
<div id="output"></div>
</body>

<!-- 引入模式2所需的javascript支持库 -->
<script type="text/javascript" src="cfprint_mode2.min.js" charset="UTF-8"></script>

<!-- 构造报表数据 -->
<script type="text/javascript">
var _reportData = '{"template":"waybill.fr3","ver":3, "Tables":[<由于字数限制,这里省略N字>]}';
if(window.console) console.log("reportData = " + _reportData);
</script>

<!-- 设置服务器参数 -->
<script language="javascript" type="text/javascript">
var cfprint_addr = "127.0.0.1"; //打印服务器监听地址
var cfprint_port = 54321; //打印服务器监听端口
var _url = "http://"+cfprint_addr+":"+cfprint_port;
</script>

<!-- 编写回调函数用以处理服务器返回的数据 -->
<script type="text/javascript">
/**
* 参数:
* readyState: XMLHttpRequest的状态
* httpStatus: 服务端返回的http状态
* responseText: 服务端返回的内容
*/
var callbackSuccess = function(readyState, httpStatus, responseText){
if (httpStatus === 200) {
//{"result": 1, "message": "打印完成"}
var response = CFPrint.parseJSON(responseText);
alert(response.message+", 状态码["+response.result+"]");
}else{
alert('打印失败,HTTP状态代码是:'+httpStatus);
}
}

/**
* 参数:
* message: 错误信息
*/
var callbackFailed = function(message){
alert('发送打印任务出错: ' + message);
}
</script>

<!-- 调用发送打印请求功能 -->
<script type="text/javascript">
(function(){
document.getElementById("btnPrint").onclick = function() {
CFPrint.outputid = "output"; //指定调试信息输出div的id
CFPrint.SendRequest(_url, _reportData, callbackSuccess, callbackFailed); //发送打印请求
};
})();
</script>
</html>

模板设计器重要!重要!!,好多朋友都找不到设计器入口
在主界面上,双击右下角的“设计”两个字,即可打开模板设计工具箱,在工具箱有三个按钮和一个大文本框。三个按钮的作用分别是:
设计:以大文本框中的json数据为数据源,打开模板设计器窗口;
预览:以大文本框中的json数据为数据源,预览当前所用模板的打印效果;
打印:以大文本框中的json数据为数据源,向打印机输出当前所用模板生成的报表;


...全文
482 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

5,006

社区成员

发帖
与我相关
我的任务
社区描述
解读Web 标准、分析和讨论实际问题、推动网络标准化发展和跨浏览器开发进程,解决各种兼容性问题。
社区管理员
  • 跨浏览器开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧