在日常生活中,經常會使用手機掃各種二維碼,或進行手機支付,但對於二維碼是如何生成的,我做了小小的總結。
此處借用實際項目中業務進行說明:對每個重點部位(實體類:AppKeyPart)生成二維碼,並實現批量下載
前端實現(jsp+jquery)

1 <my:access key="keyPart.qrCodeDownload"><input type="button" class="button orange" value="批量下載二維碼" id="batchDownloadQrCode" /></my:access>

1 $(document).ready(function(){ 2 3 //批量下載二維碼 4 $("#batchDownloadQrCode").bind("click",function(){ 5 if($("input[name='id']:checked").length <= 0){ 6 $.dialog.alert("請先選擇一條或多條數據"); 7 return false; 8 } 9 var ids = ""; 10 $("input[name='id']:checked").each(function(){ 11 ids += $(this).val()+","; 12 }); 13 ids = ids.substring(0, ids.lastIndexOf(",")); 14 window.location.href("${base}/political/keyPart_downloadQrCode.action?ids="+ids); 15 }); 16 17 });
后端實現(java)
>>>實現類代碼

1 public void downloadQrCode(){ 2 String idstr = getRequest().getParameter("ids"); 3 String[] ids = idstr.split(","); 4 5 String userid = SessionManager.getSessionUser().getUserid(); 6 String rootPathText = "/home/tomcat/tempexcel/"; //服務器路徑 7 //String rootPathText = "D:\\shy_work\\"; //本機測試路徑 8 String realPath = rootPathText + userid + File.separatorChar;//臨時文件夾 9 10 for(String id : ids){ 11 KeyPart keyPart = keyPartService.getKeyPart(id); 12 13 AppKeyPart appKeyPart = new AppKeyPart(); 14 appKeyPart.setId(keyPart.getId()); 15 appKeyPart.setBh(keyPart.getBh()); 16 appKeyPart.setMc(keyPart.getMc()); 17 appKeyPart.setSsqy(keyPart.getSsqy()); 18 appKeyPart.setSzjq(keyPart.getSzjq()); 19 appKeyPart.setGdlx(keyPart.getGdlx()); 20 21 JSONObject json = new JSONObject(); 22 json.put("keyPart", appKeyPart); 23 String content = json.toJSONString(); 24 25 //創建文件路徑,以userid命名,保證互不影響 26 File file = new File(realPath); 27 if(!file.exists()){ 28 file.mkdir(); 29 } 30 31 String filePath = realPath + keyPart.getId()+ "_" +keyPart.getBh()+".png"; 32 try { 33 QrCodeGenerateUtil.createZxing(filePath, content, 900, "png"); 34 } catch (Exception e) { 35 e.printStackTrace(); 36 } 37 } 38 39 try{ 40 File files = new File(realPath); 41 if(!files.exists()){ 42 files.mkdir(); 43 } 44 File[] filelist = files.listFiles(); 45 String zipFileName = userid + ".zip"; 46 47 HttpServletResponse response = this.getResponse(); 48 response.setContentType("application/octet-stream");// 指明response的返回對象是文件流 49 response.setHeader("Content-Disposition", "attachment;filename=" + zipFileName);// 設置在下載框默認顯示的文件名 50 response.reset(); 51 52 ZipOutputStream zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream())); 53 zipos.setMethod(ZipOutputStream.DEFLATED);//設置壓縮方法(系統默認是DEFLATED) 54 55 for(File imageFile : filelist){ 56 putZipFiles(imageFile, zipos);//加入壓縮文件 57 imageFile.delete();//刪除已添加圖片 58 } 59 zipos.close();//關閉輸出流 60 files.delete(); 61 62 } catch (Exception e) { 63 e.printStackTrace(); 64 } 65 66 }

1 /** 2 * 將待壓縮的文件 加入壓縮文件中 3 * @param imageFile 4 * @param zos 5 * @throws IOException 6 * @author Jesse 7 * @date 2018年5月3日上午11:07:34 8 */ 9 public void putZipFiles(File imageFile,ZipOutputStream zos) throws IOException { 10 if(imageFile != null && imageFile.exists()){ 11 //加入壓縮文件中 12 zos.putNextEntry(new ZipEntry(imageFile.getName())); 13 14 InputStream is = null; 15 try { 16 is = new FileInputStream(imageFile); 17 byte[] buffer = new byte[1024 * 5]; 18 int len = -1; 19 while((len = is.read(buffer)) != -1) { 20 //把緩沖區的字節寫入到ZipEntry 21 zos.write(buffer, 0, len); 22 } 23 zos.closeEntry(); 24 zos.flush(); 25 26 }catch(Exception e) { 27 throw new RuntimeException(e); 28 }finally { 29 if(is != null){ 30 is.close(); 31 } 32 } 33 } 34 }
>>>工具類代碼

1 package cn.gentlesoft.commons.tools; 2 3 import java.awt.image.BufferedImage; 4 import java.io.File; 5 import java.io.IOException; 6 import java.io.OutputStream; 7 import java.util.HashMap; 8 import java.util.Map; 9 10 import javax.imageio.ImageIO; 11 12 import com.alibaba.fastjson.JSONObject; 13 import com.google.zxing.BarcodeFormat; 14 import com.google.zxing.Binarizer; 15 import com.google.zxing.BinaryBitmap; 16 import com.google.zxing.DecodeHintType; 17 import com.google.zxing.EncodeHintType; 18 import com.google.zxing.LuminanceSource; 19 import com.google.zxing.MultiFormatReader; 20 import com.google.zxing.MultiFormatWriter; 21 import com.google.zxing.NotFoundException; 22 import com.google.zxing.Result; 23 import com.google.zxing.client.j2se.BufferedImageLuminanceSource; 24 import com.google.zxing.client.j2se.MatrixToImageWriter; 25 import com.google.zxing.common.BitMatrix; 26 import com.google.zxing.common.HybridBinarizer; 27 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 28 29 /** 30 * 二維碼生成工具 31 * 32 * @author Jesse 33 * 34 */ 35 public class QrCodeGenerateUtil { 36 37 /** 38 * 生成包含字符串信息的二維碼圖片 39 * 40 * @param os 41 * @param content 42 * @param qrCodeSize 43 * @param imageFormat 44 * @throws Exception 45 */ 46 public static void createZxing(OutputStream os, String content, int qrCodeSize, String imageFormat) 47 throws Exception { 48 // 二維碼參數 49 Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(); 50 hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); 51 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);// 糾錯等級L,M,Q,H 52 hints.put(EncodeHintType.MARGIN, 2); // 邊距 53 // 創建比特矩陣(位矩陣)的QR碼編碼的字符串 54 BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, 55 hints); 56 MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, os); 57 System.out.println("輸出圖片成功。。。"); 58 } 59 60 /** 61 * 生成包含字符串信息的二維碼圖片 62 * 63 * @param path 64 * 二維碼圖片保存地址 65 * @param content 66 * 二維碼攜帶信息 67 * @param qrCodeSize 68 * 二維碼圖片大小 69 * @param imageFormat 70 * 二維碼圖片格式 71 * @throws Exception 72 */ 73 public static void createZxing(String path, String content, int qrCodeSize, String imageFormat) throws Exception { 74 Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(); 75 hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); 76 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);// 糾錯等級L,M,Q,H 77 hints.put(EncodeHintType.MARGIN, 2); // 邊距 78 // 創建比特矩陣(位矩陣)的QR碼編碼的字符串 79 BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, 80 hints); 81 File file = new File(path); 82 // 使用比特矩陣畫並保存圖像 83 MatrixToImageWriter.writeToFile(bitMatrix, imageFormat, file); 84 System.out.println("輸出圖片成功。。。"); 85 } 86 87 /** 88 * 讀取二維碼並輸出攜帶的信息 89 * 90 * @param filePath 91 * 二維碼圖片保存地址 92 */ 93 public static void readZxing(String filePath) { 94 BufferedImage image = null; 95 try { 96 image = ImageIO.read(new File(filePath)); 97 // 將圖像轉換成二進制位圖源 98 LuminanceSource source = new BufferedImageLuminanceSource(image); 99 Binarizer binarizer = new HybridBinarizer(source); 100 BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer); 101 Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>(); 102 hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); 103 Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 對圖像進行解碼 104 JSONObject content = JSONObject.parseObject(result.getText()); 105 System.out.println("圖片中內容: "); 106 System.out.println("group: " + content.toJSONString()); 107 108 System.out.println("圖片中格式: "); 109 System.out.println("encode: " + result.getBarcodeFormat()); 110 } catch (IOException e) { 111 e.printStackTrace(); 112 } catch (NotFoundException e) { 113 e.printStackTrace(); 114 } 115 } 116 117 }
雖然現在JDK8早已被使用,但由於實際項目使用的是JDK6和IE8瀏覽器,很多地方受到限制,因此本次使用的二維碼第三方源碼庫,是谷歌的zxing庫。core-2.2.java ,javase-2.2.jar
如果是maven項目,也可以在項目pom.xml文件里引入:

1 <dependency> 2 <groupId>com.google.zxing</groupId> 3 <artifactId>core</artifactId> 4 <version>2.2</version> 5 </dependency> 6 7 <dependency> 8 <groupId>com.google.zxing</groupId> 9 <artifactId>javase</artifactId> 10 <version>2.2</version> 11 </dependency>
到此實現了二維碼批量生成 壓縮 下載功能!
2018-05-05