1. 程式人生 > >java實現二維碼生成及呼叫印表機列印

java實現二維碼生成及呼叫印表機列印

在開發二維碼列印的過程中走過幾次彎路,所以在這裡特意將其記錄下來留作備忘。一開始參考其他博主寫的文章,有介紹通過編寫JAVA後臺程式碼來獲取本地預設印表機的驅動實現列印。BUT!這樣就導致在本地開發測試時看似一切正常,一旦專案部署到linux環境下,就會完全失效了(JAVA後臺程式碼去獲取linux本地的印表機驅動)。還有介紹並提供編寫的外掛的(不甚瞭解這塊),鑑於時間要求比較苛刻,那就簡單的來吧。

需求:生成帶水印效果的二維碼圖片,可以批量預覽,並連線印表機批量列印。

開發思路:
1.編寫二維碼生成工具類,實現二維碼圖片的生成
2.提供二維碼列印前的預覽
3.通過隱藏的iframe實現列印(簡單粗暴)

以下是自己編寫的一個小案例,可以直接執行測試,並提供了code下載。如果有其它更好的實現方式,也希望大家多提出寶貴的意見。
一、專案結構
-

二、主要CODE
1.MyQRUtils.java 二維碼工具類

  1 package com.webprint.qr.tools;
  2  
  3 import java.awt.Color;
  4 import java.awt.Font;
  5 import java.awt.Graphics2D;
  6 import java.awt.image.BufferedImage;
  7 import java.io.File;
8 import java.io.IOException; 9 import java.io.OutputStream; 10 import java.util.Hashtable; 11 12 import javax.imageio.ImageIO; 13 14 import org.apache.commons.logging.Log; 15 import org.apache.commons.logging.LogFactory; 16 17 import com.google.zxing.BarcodeFormat; 18 import com.google.zxing.EncodeHintType;
19 import com.google.zxing.MultiFormatWriter; 20 import com.google.zxing.WriterException; 21 import com.google.zxing.common.BitMatrix; 22 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 23 24 public class MyQRUtils{ 25 26 private static final Log logger = LogFactory.getLog(MyQRUtils.class); 27 28 private static final int BLACK = 0xFF000000; 29 private static final int WHITE = 0xFFFFFFFF; 30 private static final int LogoPart = 4; 31 32 /** 33 * 生成二維碼前的配置資訊 34 * @param content 生成二維碼圖片內容 35 * @param width 二維碼圖片的寬度 36 * @param height 二維碼圖片的高度 37 * @return 38 */ 39 public static BitMatrix setBitMatrix(String content,int width,int height){ 40 Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>(); 41 hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); 42 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); //指定糾錯等級 43 BitMatrix bitMatrix=null; 44 try { 45 bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints); 46 } catch (WriterException e) { 47 logger.error("生成二維碼錯誤",e); 48 } 49 return bitMatrix; 50 } 51 52 /** 53 * 將LOGO圖片放在二維碼中間(水印效果) 54 * 將生成的圖片以流的形式輸出到頁面展示 55 * @param matrix BitMatrix 56 * @param format 圖片格式 57 * @param outStream 輸出流 58 * @param logoPath LOGO地址 59 * @param showBottomText 二維碼圖片底部需要顯示的問題 60 * @throws IOException 61 */ 62 public static void megerToFile(BitMatrix matrix,String format,OutputStream outStream,String logoPath,String showBottomText) throws IOException { 63 BufferedImage image = toBufferedImage(matrix); 64 Graphics2D gs = image.createGraphics(); 65 66 //1.加入LOGO水印效果 67 if(null != logoPath && !"".equals(logoPath)){ 68 //1.1 載入LOGO圖片 69 BufferedImage logoImg = ImageIO.read(new File(logoPath)); 70 //1.2 考慮到LOGO圖片貼到二維碼中,建議大小不要超過二維碼的1/5; 71 int width = image.getWidth() / LogoPart; 72 int height = image.getHeight() / LogoPart; 73 //1.3 LOGO居中顯示 74 int x = (image.getWidth() - width) / 2; 75 int y = (image.getHeight() - height) / 2; 76 gs.drawImage(logoImg, x, y, logoImg.getWidth(), logoImg.getHeight(), null); 77 logoImg.flush(); 78 } 79 //2.二維碼圖片底部插入文字 80 if(null != showBottomText && !"".equals(showBottomText)){ 81 //2.1 設定字型樣式 82 Font font = new Font("微軟雅黑", Font.PLAIN, 14); 83 gs.setColor(Color.BLACK); 84 gs.setFont(font); 85 //2.2 字型顯示位置 86 int x = (image.getWidth() - getWatermarkLength(showBottomText, gs))/2; 87 int y = image.getHeight()-2; 88 gs.drawString(showBottomText, x, y); 89 } 90 gs.dispose(); 91 ImageIO.write(image, format, outStream); 92 } 93 94 /** 95 * 將LOGO圖片放在二維碼中間(水印效果) 96 * 將生成的圖片生成到本地硬碟路徑下 97 * @param matrix BitMatrix 98 * @param format 圖片格式 99 * @param imagePath 圖片存放路徑 100 * @param logoPath LOGO地址 101 * @param showBottomText 二維碼圖片底部需要顯示的問題 102 * @throws IOException 103 */ 104 public static void megerToFile2(BitMatrix matrix,String format,String imagePath,String logoPath,String showBottomText) throws IOException { 105 BufferedImage image = toBufferedImage(matrix); 106 Graphics2D gs = image.createGraphics(); 107 108 //1.加入LOGO水印效果 109 if(null != logoPath && !"".equals(logoPath)){ 110 BufferedImage logoImg = ImageIO.read(new File(logoPath)); 111 int width = image.getWidth() / LogoPart; 112 int height = image.getHeight() / LogoPart; 113 int x = (image.getWidth() - width) / 2; 114 int y = (image.getHeight() - height) / 2; 115 gs.drawImage(logoImg, x, y, logoImg.getWidth(), logoImg.getHeight(), null); 116 logoImg.flush(); 117 } 118 119 //2.二維碼圖片底部插入文字 120 if(null != showBottomText && !"".equals(showBottomText)){ 121 //2.1 設定字型樣式 122 Font font = new Font("微軟雅黑", Font.PLAIN, 14); 123 gs.setColor(Color.BLACK); 124 gs.setFont(font); 125 //2.2 字型顯示位置 126 int x = (image.getWidth() - getWatermarkLength(showBottomText, gs))/2; 127 int y = image.getHeight()-2; 128 gs.drawString(showBottomText, x, y); 129 } 130 gs.dispose(); 131 ImageIO.write(image, format, new File(imagePath)); 132 } 133 134 /** 135 * 獲取水印字型的長度 136 * @param fontString 137 * @param gs 138 * @return 139 */ 140 public static int getWatermarkLength(String fontString,Graphics2D gs){ 141 return gs.getFontMetrics(gs.getFont()).charsWidth(fontString.toCharArray(),0,fontString.length()); 142 } 143 144 public static BufferedImage toBufferedImage(BitMatrix matrix){ 145 int width = matrix.getWidth(); 146 int height = matrix.getHeight(); 147 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); 148 149 for(int x=0;x<width;x++){ 150 for(int y=0;y<height;y++){ 151 image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE); 152 } 153 } 154 return image; 155 } 156 }

說明:二維碼實現方式有多種,此處程式碼可根據具體需求具體開發。

2.WebPrintController.java SpringMVC的controller層程式碼

  1 package com.webprint.qr.controller;
  2  
  3 import java.io.IOException;
  4 import java.io.OutputStream;
  5 import java.util.ArrayList;
  6 import java.util.HashMap;
  7 import java.util.List;
  8 import java.util.Map;
  9  
 10 import javax.servlet.http.HttpServletRequest;
 11 import javax.servlet.http.HttpServletResponse;
 12  
 13 import org.apache.commons.logging.Log;
 14 import org.apache.commons.logging.LogFactory;
 15 import org.springframework.stereotype.Controller;
 16 import org.springframework.ui.Model;
 17 import org.springframework.web.bind.annotation.RequestMapping;
 18  
 19 import com.google.zxing.common.BitMatrix;
 20 import com.webprint.qr.tools.MyQRUtils;
 21  
 22 @Controller("WebPrintController")
 23 @RequestMapping("/qrPrint")
 24 public class WebPrintController {
 25  
 26     private static final Log logger = LogFactory.getLog(MyQRUtils.class);
 27     
 28     /**
 29      * 二維碼預覽頁面
 30      * @param model
 31      * @return
 32      */
 33     @RequestMapping("/showList.do")
 34     public  String  showQRList(Model model){
 35         //模擬獲取資料庫資料
 36         List listData = new ArrayList();
 37         StringBuffer ids = new StringBuffer();
 38         String code = "print00";
 39         for (int i = 0; i < 3; i++) {
 40             Map<String,String> map = new HashMap<String,String>(); //模擬VO
 41             map.put("id",code+""+i);
 42             ids.append(code+""+i).append(",");
 43             listData.add(map);
 44         }
 45         model.addAttribute("showListData", listData);
 46         model.addAttribute("ids", ids);
 47         return "showQR";
 48     }
 49     
 50     /**
 51      * 二維碼列印頁面
 52      * 隱藏在iframe中
 53      * @param model
 54      * @return
 55      */
 56     @RequestMapping("/printEWM.do")
 57     public  String  printQRFrame(Model model,HttpServletRequest request){
 58         String ids = request.getParameter("ids");
 59         model.addAttribute("ids", ids);
 60         return "printFrameQR";
 61     }
 62     
 63     /**
 64      * 顯示二維碼圖片
 65      * @param request
 66      * @param response
 67      * @throws Exception
 68      */
 69     @RequestMapping("/showEWMImage.do")
 70     public void showImageByType(HttpServletRequest request,HttpServletResponse response){
 71         String id = request.getParameter("showID"); //ID
 72         
 73         //此處可從資料庫中獲取內容
 74         String content ="列印二維碼\n列印測試\nID:"+id;
 75         
 76         OutputStream outStream = null;
 77         try {
 78             outStream = response.getOutputStream();
 79             String format = "jpg";
 80             String bottomText = "一路不停"; //水印文字
 81             
 82             BitMatrix bitMatrix = MyQRUtils.setBitMatrix(content, 180 , 180);
 83             //暫時不使用LOGO圖片
 84             MyQRUtils.megerToFile(bitMatrix, format, outStream, null,bottomText);
 85             
 86         } catch (Exception e) {
 87             logger.error("二維碼生成失敗", e);
 88         }finally{
 89             try {
 90                 if(outStream!=null){
 91                     outStream.flush();
 92                     outStream.close();
 93                 }
 94             } catch (IOException e) {
 95                 logger.error("關閉資料流失敗", e);
 96             }
 97             
 98         }
 99     }
100     
101     
102 }

說明:二維碼圖片的展示及其列印以流的方式操作,這樣就無需將圖片儲存在伺服器上了。

3.index.jsp 首頁

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 3 <html>
 4   <head>
 5     <meta http-equiv="pragma" content="no-cache">
 6     <meta http-equiv="cache-control" content="no-cache">
 7     <meta http-equiv="expires" content="0"> 
 8     <%@include file="/include.jsp" %>
 9     <title></title>
10   </head>
11   <iframe id="iframePrintEWM" frameborder="0" width="0" height="0"></iframe>
12   <body>
13     <div> 1.二維碼預覽</br> 
14             2.二維碼列印 
15       </div></br> 
16     </br></br>
17     <hr>
18     </br>
19     <input type="button" id ="showQRList" name="showQRList" value="二維碼預覽" onclick="showQRList()"/>
20     <div id='divDialog'></div>
21     <div id='divPrintDialog'></div>
22   </body>
23   <script type="text/javascript">
24     var height = $("body").height();
25     var width = $("body").width();
26   
27     //二維碼預覽
28       function showQRList(){
29           var url ="${rootPath}/qrPrint/showList.do";
30           $("#divDialog").dialog({
31               title:"預覽",
32               width:260,
33               height:500,
34               top:(height-500)/2,
35               left:(width-260)/2,
36               href:url,
37               cache:false,
38               closed:false,
39               modal:true
40           });
41       }
42       
43       //二維碼列印
44       function printEWM(ids){
45         $('#divDialog').window('close');
46         var url = '${rootPath}/qrPrint/printEWM.do?ids='+ids;
47         $('#iframePrintEWM').attr("src", url);
48       }
49   </script>
50 </html>

說明:將iframe放在body標籤外,並將其寬高和border都設定為0,達到隱藏的效果。

4.showQR.jsp 二維碼預覽頁

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <html>
 3   <head>
 4       <%@include file="/include.jsp" %>
 5     <title>showQRList</title>
 6   </head>
 7   <body>
 8   <div >
 9     <div align="left" >
10         <a href="javascript:printEWM('${ids }');" class="easyui-linkbutton" iconCls="icon-printer" style="width: 95px">二維碼列印</a>
11     </div>
12 </div>
13 <div>
14 <c:forEach var="printID" items="${showListData}" varStatus="lis"> 
15 <table align="center" class="codetable"  cellpadding="0" style="float: left;border:1px solid #333333;">
16     <tr>
17         <td align="center">
18             <div id="bcTarget${lis.index }">
19                 <img src="${rootPath}/qrPrint/showEWMImage.do?showID=${printID.id}">
20             </div>
21         </td>
22     </tr>
23 </table>
24 </c:forEach>
25 </div>
26 </body>
27 </html>

說明:如果專案中不需要自定義預覽,此處程式碼可以去掉。

 

5.printFrameQR.jsp 隱藏的iframe頁,用於列印(非常簡單,非常強大)

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <html>
 3   <head>
 4       <%@include file="/include.jsp" %>
 5     <title>printFrameQR</title>
 6   </head>
 7   <body onload="this.focus();this.print()">
 8 <div>
 9 <c:forEach var="printID" items="${ids}" varStatus="lis"> 
10     <div id="bcTarget${lis.index }">
11         <img src="${rootPath}/qrPrint/showEWMImage.do?showID=${printID}">
12     </div></br>
13 </c:forEach>
14 </div>
15 </body>
16 </html>

說明:簡單粗暴的方式,列印的關鍵就在於body標籤中的 onload="this.focus();this.print()"

三、預覽效果 

 

注意對IE列印頁面的設定;

四、code下載部署說明

以上是週末自己編寫的小案例,供大家參考。
環境:myeclipse8.5 + tomcat6 + jdk7 +jQuery EasyUI + core-3.3.0.jar(google zxing)
地址:http://download.csdn.net/detail/onepersontz/9794722