因为项目有个功能需要打印二维码,因为我比较喜欢使用html+css+js实现,所以首先想到的是jquery.qrcode.js插件,这个插件可以用canvas和table生成二维码,效果也不错,不过对中文支持有问题,这个插件默认使用canvas,所以使用IE的时候,需要指定参数render,只要参数值不是canvas就会用table生成。由于这个问题,我在github,fork了一个,做了如下的修改:
//true if support function canvasSupport() { return !!document.createElement('canvas').getContext; } return this.each(function(){ //if the browser not support canvas,then table. if(!canvasSupport()){ options.render = "table"; } var element = options.render == "canvas" ? createCanvas() : createTable(); $(element).appendTo(this); });
使用canvas有个缺点就是网页打印的时候显示不出来...这个问题好像已经有解决办法了,我没有去找,我直接用的table。不过打印似乎仍然有问题。
jquery.qrcode.js插件地址:https://github.com/jeromeetienne/jquery-qrcode
js有问题,所以只能通过zxing来输出二维码,写了如下的servlet代码:
@SuppressWarnings("serial") public class QrCodeServlet extends HttpServlet { private static final int BLACK = -16777216; private static final int WHITE = -1; private BufferedImage toBufferedImage(BitMatrix matrix) { int width = matrix.getWidth(); int height = matrix.getHeight(); BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE); } } return image; } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { String content = req.getParameter("m"); if(content==null||content.equals("")){ resp.setContentType("text/plain;charset=UTF-8"); resp.getOutputStream().write("二维码内容不能为空!".getBytes("utf-8")); resp.getOutputStream().close(); } int imgWidth = 110; int imgHeight = 110; String width = req.getParameter("w"); String height = req.getParameter("h"); if(width!=null&&!width.equals("")){ try { imgWidth = Integer.parseInt(width); } catch (Exception e) {} } if(height!=null&&!height.equals("")){ try { imgHeight = Integer.parseInt(height); } catch (Exception e) {} } BitMatrix byteMatrix; Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>(); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); byteMatrix = new MultiFormatWriter().encode( new String(content.getBytes("UTF-8"),"ISO-8859-1"), BarcodeFormat.QR_CODE, imgWidth, imgHeight, hints); BufferedImage image = toBufferedImage(byteMatrix); resp.setContentType("image/png"); ImageIO.write(image, "png", resp.getOutputStream()); } catch (Exception e) { } } }
由于zxing默认的编码为ISO-8859-1,所以使用其他编码的时候会出现乱码,即使执行其他的编码方式,还是有问题,如果转换为ISO-8859-1就没有乱码。
还有一个很重要的内容,就是使用zxing的时候必须导出png格式的二维码,导出jpg格式的时候,颜色就不是黑白的,很让人费解,希望有人能给出原因。
二维码效果图: