pom支持: <!-- 二維碼支持包 start--> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.2.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.2.0</version> </dependency> <!-- 二維碼支持包 end--> 工具類支持: package com.example.demo.dao.qrcode; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.WriterException; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import javax.imageio.ImageIO; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.Hashtable; /** * @author jin.tang * @Title: springbootdemo * @Package com.example.demo.dao.qrcode * @Description: java web二維碼生成器 * @date 2017/12/25 */ @Slf4j public class QRCodeUtil { /** * 方式一:流的方式直接生成web版本二維碼 * 默認的二維碼外觀(可設置高寬) * @param url 要生成二維碼的路徑 * @param response response對象 * @param width 二維碼寬度 * @param height 二維碼高度 * @throws IOException */ public static void getTwoDimension(String url, HttpServletResponse response, int width, int height) throws IOException { if (url != null && !"".equals(url)) { ServletOutputStream stream = null; try { stream = response.getOutputStream(); QRCodeWriter writer = new QRCodeWriter(); BitMatrix m = writer.encode(url, BarcodeFormat.QR_CODE, height, width); MatrixToImageWriter.writeToStream(m, "png", stream); } catch (WriterException e) { e.printStackTrace(); log.error("生成二維碼失敗!"); } finally { if (stream != null) { stream.flush(); stream.close(); } } } } /** * 方式二:返回ResponseEntity的方式顯示二維碼 * 可設置二維碼外觀顏色,logo圖片 * @param url 二維碼對於URL * @param width 二維碼寬 * @param height 二維碼高 * @param format 二維碼格式 * @param logPath logo圖片路徑 * @param needLogo 二維碼是否須要生成logo * @return * @throws WriterException * @throws IOException */ // 直接在頁面顯示 public static ResponseEntity<byte[]> getResponseEntity(String url, String logPath, boolean needLogo,String format,int width,int height)throws Exception { BufferedImage image = QRCodeUtil.createImage(url, logPath,needLogo,width,height); ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageIO.write(image, format, out);//將BufferedImage轉成out輸出流 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); return new ResponseEntity<byte[]>(out.toByteArray(), headers, HttpStatus.CREATED); } /** * 方式三:以流的形式直接顯示二維碼 * 可設置二維碼外觀顏色,logo圖片 */ public static void showQrcode(String url, String logPath,HttpServletResponse response, boolean needLog,String format,int width,int height)throws Exception { BufferedImage image = QRCodeUtil.createImage(url, logPath,needLog,width,height); boolean bl = ImageIO.write(image, format, response.getOutputStream()); System.out.println(" boolean is " + bl); } /** 方式四:生成二維碼文件存儲 * 可設置二維碼外觀顏色,logo圖片 * @param logPath * @param destPath 存儲路徑 * @param fileName 存儲文件名稱(不須要後綴) * @param needLog * @param format * @param width * @param height * @return * @throws Exception */ public static boolean SaveQrCode(String url, String logPath, boolean needLog,String format,int width,int height,String destPath, String fileName) throws Exception { boolean flag = false; BufferedImage image; try { image = QRCodeUtil.createImage(url, logPath,needLog,width,height); File file = new File(destPath); // 當文件夾不存在時,mkdirs會自動建立多層目錄,區別於mkdir.(mkdir若是父目錄不存在則會拋出異常) if (!file.exists() && !file.isDirectory()) { file.mkdirs(); } String fileUrl = fileName + "."+format; ImageIO.write(image, format, new File(destPath + "/" + fileUrl)); flag = true; } catch (Exception e) { e.printStackTrace(); } return flag; } /** * 生成二維碼圖片私有方法 */ private static BufferedImage createImage (String url, String imgPath,boolean needCompress, int width, int height) throws Exception { Hashtable hints = new Hashtable(); // 二維碼糾錯級別:由高到低 H、Q、M、L hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 二維碼邊界空白大小由大到小 四、三、二、1(默認爲4) hints.put(EncodeHintType.MARGIN, 1); BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, width, height, hints); int H = bitMatrix.getHeight(); int W = bitMatrix.getWidth(); int L = getFinderPatternWidth(bitMatrix) + 3; int[] pixels = new int[W * H]; // 二維碼角顏色,依次爲左上、左下、右上 Color redColor = new Color(182, 0, 5); int redColorInt = redColor.getRGB(); Color greenColor = new Color(0, 124, 54); int greenColorInt = greenColor.getRGB(); Color blueColor = new Color(0, 64, 152); int blueColorInt = blueColor.getRGB(); for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) { // 顏色漸變程度,RGB(158,255,158) int num1 = (int) (158 - (158.0 - 30.0) / bitMatrix.getHeight() * (y + 1)); int num2 = (int) (255 - (255.0 - 80.0) / bitMatrix.getHeight() * (y + 1)); int num3 = (int) (158 - (158.0 - 130.0) / bitMatrix.getHeight() * (y + 1)); Color color = new Color(num1, num2, num3); int colorInt = color.getRGB(); // 此處能夠修改二維碼的顏色,能夠分別制定二維碼和背景的顏色; pixels[y * W + x] = bitMatrix.get(x, y) ? colorInt : 0xffffff; } } BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); image.getRaster().setDataElements(0, 0, W, H, pixels); if (imgPath == null || "".equals(imgPath)) { return image; } // 插入圖片 QRCodeUtil.insertImage(image, imgPath, needCompress,width,height); return image; } private static int getFinderPatternWidth(BitMatrix matrix) { int W = matrix.getWidth(); int H = matrix.getHeight(); int length = 0; boolean flag = false; for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) { if (matrix.get(x, y) == true) { flag = true; length++; } else { if (flag != false) { return x; } } } } return length; } /** * 在二維碼中插入圖片 */ private static void insertImage(BufferedImage source, String imgPath, boolean needCompress,int wid,int hei) throws Exception { File file = new File(imgPath); if (!file.exists()) { System.err.println("" + imgPath + " 該文件不存在!"); return; } Image src = ImageIO.read(new File(imgPath)); int width = src.getWidth(null); int height = src.getHeight(null); if (needCompress) { // 壓縮LOGO if (width > wid) { width = wid; } if (height > hei) { height = hei; } Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 繪製縮小後的圖 Graphics g = tag.getGraphics(); g.drawImage(image, 0, 0, null); g.dispose(); src = image; } // 插入LOGO位置 Graphics2D graph = source.createGraphics(); int x = (wid - width) / 2; int y = (hei - height) / 2; /* * int x = QRCODE_SIZE - width - 20; int y = QRCODE_SIZE - height - 20; */ graph.drawImage(src, x, y, width, height, null); // logo邊框 /* * Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6); * graph.setStroke(new BasicStroke(3f)); graph.draw(shape); */ graph.dispose(); } controller中調用: package com.example.demo.controller; import com.example.demo.dao.qrcode.QRCodeUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author jin.tang * @Title: springbootdemo * @Package com.example.demo.controller * @Description: ${todo} * @date 2017/12/25 */ @Slf4j @Controller public class QRCodeController { /** * 得到二維碼 * @param request * @param response */ @RequestMapping(value = "phoneversion/getTwoDimension",method={RequestMethod.POST,RequestMethod.GET}) public void getTwoDimensionForIOSs(HttpServletRequest request, HttpServletResponse response){ try { QRCodeUtil.getTwoDimension("https://bbs.hupu.com/bxj", response, 300, 300); } catch (IOException e) { e.printStackTrace(); } } @RequestMapping("/downloadIOSAPPQRCode") public ResponseEntity<byte[]> downloadIOSAPPController(/*@RequestParam(required = true)String type*/) throws Exception{ // InputStream is = this.getClass().getClassLoader().getResourceAsStream("app.properties"); // Properties props = new Properties(); // props.load(is); // String appId = (String)props.get(type); // String url = "" + appId; return QRCodeUtil.getResponseEntity("https://www.zhibo8.cc", "F:\\logo.png",true,"png", 300, 300); } @RequestMapping("/showQrcode") public void showQrcode(HttpServletRequest request, HttpServletResponse response) throws Exception{ QRCodeUtil.showQrcode("https://www.zhibo8.cc", "",response,false,"png", 300, 300); } @RequestMapping("/SaveQrCode") public void SaveQrCode(HttpServletRequest request, HttpServletResponse response) throws Exception{ boolean flag=QRCodeUtil.SaveQrCode("https://www.zhibo8.cc", "",false,"png", 300, 300,"D:\\","qrcode"); log.info("flag=="+flag); } } 前端顯示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>首頁</title> </head> <body> <p>二維碼圖片1:</p> <div><img src="/phoneversion/getTwoDimension" alt="" /></div> <p>二維碼圖片2:</p> <img src="/downloadIOSAPPQRCode"/><a href="/downloadIOSAPPQRCode">下載</a> <p>二維碼圖片3:</p> <img src="/showQrcode"/><a href="/showQrcode">下載</a> </body> </html>}