【lodop】套打小結
小編最近完成了一個“套打”的工作,做個總結,以備後續參考。
一、套打是什麼
起初組長讓我做“工行信用卡套打”功能時,我還是比較懵的,什麼是套打,百度了一下,類似發票列印,把要列印的內容放到預留的空位上,執行列印。如圖,是我這次套打需要的模板:
二、方案選型
開始工作前,做了調研,可實行的方案:
1.“jasperreport + ireport”
2."lodop"
3."itext"
4."fineReport"
5."ActiveX控制元件"
在詳細說明我的選型方案之間,分享一些針對各個方案我花了好幾天時間找到的好的素材:
以及不錯的幾篇部落格,關於套打:
http://blog.csdn.net/qq_18875541/article/details/69392215
http://blog.csdn.net/smvcn/article/details/8672537 (本地列印jasper)
http://blog.csdn.net/gong0585/article/details/5319367 (套打模板佈局設計)
http://blog.csdn.net/u014704879/article/details/49613775
1.起初,我是確定使用“jasper+ireport”方式來做的,這個方式國外用的比較多,但是奈何學習成本比較高,學習資料少,那段時間晚上回家我都是在YouTuBe上搜索教學視訊學習,遇到問題能夠諮詢的人也比較少,最致命的一點,是工行的單子列印點實在是太密了,jasper列印的精度不能打到我的要求。2.嘗試Itext,基本上就是手動挖空,預留位置,實現套打,也不能滿足要求。
3.fineReport需要付費,如果涉及複雜的企業報表,使用這種比價好。
4.ActiveX,用於PDF的列印比較好,套打需要程式控制C端印表機,很難做到,而且目前各大瀏覽器開始放棄對ActiveX的維護。
5.lodop,最後確定使用lodop實現,能實現精準列印,國人開發的外掛,如果說2010年之前套打用外國人的外掛很必要,現在我們國人做的東西也不是吹出來的。
三、注意問題
1.套打之前需要1:1掃描“工行信用卡申請表”,自己把握不好就趕緊去列印店吧,不然上線了還會影響C端使用。
2.套打按鈕的資料許可權,一定要做好。
3.如何引導C端使用者,首次使用套打功能時,能夠按照提示,順利安裝成對應瀏覽器版本下的Lodop外掛版本。
4.c端門店印表機型號如果不確定,最好提前在程式中進行埋點獲取門店印表機型號,或者找業務人員去調查,做適配。
5.關於lodop水印問題,提前想好是先通過預覽視窗再列印,還是直接買lodop正版。
四、實現思路
這裡不展示,具體lodop的教程,詳情參考官網,由於最終會有大量入下程式碼出現:
LODOP=getLodop();
LODOP.PRINT_INITA(0,0,1500,900,"0");
LODOP.SET_PRINT_PAGESIZE(2,3780,2080,"");
LODOP.SET_SHOW_MODE("BKIMG_LEFT",0);
LODOP.SET_SHOW_MODE("BKIMG_TOP",0);
LODOP.SET_SHOW_MODE("BKIMG_WIDTH","378.09mm");
LODOP.SET_SHOW_MODE("BKIMG_HEIGHT","207.96mm");
LODOP.SET_SHOW_MODE("BKIMG_PRINT",true);
LODOP.ADD_PRINT_TEXT(168,46,133,20,custom);
LODOP.ADD_PRINT_TEXT(197,57,17,18,man);
LODOP.ADD_PRINT_TEXT(197,83,16,18,woman);
LODOP.ADD_PRINT_RECT(914,1455,65,21,0,1);
LODOP.ADD_PRINT_TEXT(195,256,80,20,birthYear);
LODOP.SET_PRINT_STYLEA(0,"LetterSpacing",9);
LODOP.ADD_PRINT_TEXT(195,327,42,20,birthMonth);
LODOP.SET_PRINT_STYLEA(0,"LetterSpacing",8);
LODOP.ADD_PRINT_TEXT(195,366,60,20,birthDay);
LODOP.SET_PRINT_STYLEA(0,"LetterSpacing",10)
LODOP.ADD_PRINT_TEXT(233,47,403,20,idNumber);
LODOP.SET_PRINT_STYLEA(0,"LetterSpacing",7);
LODOP.ADD_PRINT_TEXT(254,264,69,20,validdateEndYear);
LODOP.ADD_PRINT_TEXT(253,335,38,20,validdateEndMonth);
LODOP.SET_PRINT_STYLEA(0,"LetterSpacing",6);
LODOP.ADD_PRINT_TEXT(253,373,43,20,validdateEndDay);
我採取的方案是在目錄下新建好html模板,比如起名“vincent-print.html”,其中會在lodop的CreatePrintPage()函式中放入lodop生成程式碼,這裡我用一個套打“快遞單”(不涉及公司隱私)為例,<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<style>
*{
padding:0;
margin:0
}
@font-face {
font-family: 'HYZhongJianHeiJ', 'simhei';
src: url(hyjh.ttf), url(hei.ttf);
}
@page {
size: A4;
margin-left: 1cm;
margin-right: 1cm;
margin-top: 0cm;
margin-bottom: 0cm;
}
body {
font-family: 'HYZhongJianHeiJ';
}
@charset "utf-8";
html, body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, em, button {
margin: 0;
padding: 0
}
body {
line-height: 2em;
color: #333;
background-color: #fff;
}
img, fieldset {
border: none;
vertical-align: middle
}
table {
border-collapse: collapse
}
a {
color: #06c;
text-decoration: none;
cursor: pointer
}
</style>
</head>
<body>
<script language="javascript" src="LodopFuncs.js"></script>
<script language="javascript" type="text/javascript">
var LODOP; //宣告為全域性變數
function CreatePrintPage() {
var custom = document.getElementById("customName").innerHTML;
var idNumber = document.getElementById("idNumber").innerHTML;
var memberName = document.getElementById("memberName").innerHTML;
LODOP=getLodop();
LODOP.PRINT_INIT("套打EMS的模板");
LODOP.ADD_PRINT_SETUP_BKIMG("D:\\b_work\\lodop\\kuaidi.jpg");
LODOP.SET_SHOW_MODE("BKIMG_WIDTH","209.02mm");
LODOP.SET_SHOW_MODE("BKIMG_HEIGHT","112.98mm");
LODOP.SET_SHOW_MODE("BKIMG_PRINT",true);
LODOP.ADD_PRINT_TEXT(97,91,90,20,custom);
LODOP.ADD_PRINT_TEXT(97,246,90,20,idNumber);
LODOP.ADD_PRINT_TEXT(164,34,320,20,memberName);
};
</script>
進入<a href="javascript:;" onclick="javascript:CreatePrintPage();LODOP.PRINT_DESIGN();">模板設計</a><br><br>
進入<a href="javascript:;" onclick="javascript:CreatePrintPage();LODOP.PREVIEW();">模板的列印預覽</a>
<div hidden>
<p id="customName"><#if customName??>${customName}</#if></p>
<p id="memberName"><#if memberName??>${memberName}</#if></span></p>
<p id="idNumber"><#if idNumber??>${idNumber}</#if></span></p>
</div>
</body>
</html>
預留了一些變數,比如“customName”,"memberName","idNumber",之後在後臺查詢相關邏輯中,通過:Map<Object, Object> varsb = new HashMap<Object, Object>();
作為一個容器,存放我查詢出來的需要在套打單上顯示的欄位,之後通過類似方法:return XXXXUtil.generateHtml(TEMPLATE_NEST, varsb).getBytes("UTF-8");
寫一個工具類,將html頁面,連同varbs變數值,一同返給前臺去載入,再通過上述的<div>標籤中截取回傳的值,推送到預覽頁,最終實現列印,思路有了,工具類就不展示了,通過ServletContext來做的。五、列印展示
最終做到了精確套打的功能,而且適配各種主流瀏覽器。
如有疑惑,歡迎交流。