1. 程式人生 > >JAVA實現QRCode的二維碼生成以及列印(轉)

JAVA實現QRCode的二維碼生成以及列印(轉)

不說廢話了直接上程式碼

注意使用QRCode是需要zxing的核心jar包,這裡給大家提供下載地址

https://download.csdn.net/download/dsn727455218/10515340

下載

1.二維碼的工具類

 

public class QR_Code {
    private static int BLACK = 0x000000;
    private static int WHITE = 0xFFFFFF;
  
    /**
     * 1.建立最原始的二維碼圖片
     *
     * @param info
     * @return
     */
private BufferedImage createCodeImage(CodeModel info) { String contents = info.getContents();//獲取正文 int width = info.getWidth();//寬度 int height = info.getHeight();//高度 Map<EncodeHintType, Object> hint = new HashMap<>(); hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
//設定二維碼的糾錯級別【級別分別為M L H Q ,H糾錯能力級別最高,約可糾錯30%的資料碼字】 hint.put(EncodeHintType.CHARACTER_SET, info.getCharacter_set());//設定二維碼編碼方式【UTF-8】 hint.put(EncodeHintType.MARGIN, 0); MultiFormatWriter writer = new MultiFormatWriter(); BufferedImage img = null; try {
//構建二維碼圖片 //QR_CODE 一種矩陣二維碼 BitMatrix bm = writer.encode(contents, BarcodeFormat.QR_CODE, width, height + 5, hint); int[] locationTopLeft = bm.getTopLeftOnBit(); int[] locationBottomRight = bm.getBottomRightOnBit(); info.setBottomStart(new int[] { locationTopLeft[0], locationBottomRight[1] }); info.setBottomEnd(locationBottomRight); int w = bm.getWidth(); int h = bm.getHeight(); img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { img.setRGB(x, y, bm.get(x, y) ? BLACK : WHITE); } } } catch (WriterException e) { e.printStackTrace(); } return img; } /** * 2.為二維碼增加logo和二維碼下文字 logo--可以為null 文字--可以為null或者空字串"" * * @param info * @param output */ private void dealLogoAndDesc(CodeModel info, OutputStream output) { //獲取原始二維碼圖片 BufferedImage bm = createCodeImage(info); //獲取Logo圖片 File logoFile = info.getLogoFile(); int width = bm.getWidth(); int height = bm.getHeight(); Graphics g = bm.getGraphics(); //處理logo if (logoFile != null && logoFile.exists()) { try { BufferedImage logoImg = ImageIO.read(logoFile); int logoWidth = logoImg.getWidth(); int logoHeight = logoImg.getHeight(); float ratio = info.getLogoRatio();//獲取Logo所佔二維碼比例大小 if (ratio > 0) { logoWidth = logoWidth > width * ratio ? (int) (width * ratio) : logoWidth; logoHeight = logoHeight > height * ratio ? (int) (height * ratio) : logoHeight; } int x = (width - logoWidth) / 2; int y = (height - logoHeight) / 2; //根據logo 起始位置 和 寬高 在二維碼圖片上畫出logo g.drawImage(logoImg, x, y, logoWidth, logoHeight, null); } catch (Exception e) { e.printStackTrace(); } } //處理二維碼下文字 String desc = info.getDesc(); if (!"".equals(desc)) { try { //設定文字字型 int whiteWidth = info.getHeight() - info.getBottomEnd()[1]; Font font = new Font("宋體", Font.PLAIN, info.getFontSize()); int fontHeight = g.getFontMetrics(font).getHeight(); //計算需要多少行 int lineNum = 1; int currentLineLen = 0; for (int i = 0; i < desc.length(); i++) { char c = desc.charAt(i); int charWidth = g.getFontMetrics(font).charWidth(c); if (currentLineLen + charWidth > width) { lineNum++; currentLineLen = 0; continue; } currentLineLen += charWidth; } int totalFontHeight = fontHeight * lineNum; int wordTopMargin = 4; BufferedImage bm1 = new BufferedImage(width, height + totalFontHeight + wordTopMargin - whiteWidth, BufferedImage.TYPE_INT_RGB); Graphics g1 = bm1.getGraphics(); if (totalFontHeight + wordTopMargin - whiteWidth > 0) { g1.setColor(Color.WHITE); g1.fillRect(0, height, width, totalFontHeight + wordTopMargin - whiteWidth); } g1.setColor(new Color(BLACK)); g1.setFont(font); int startX = (78 - (12 * desc.length())) / 2; g1.drawImage(bm, 0, 0, null); width = info.getBottomEnd()[0] - info.getBottomStart()[0]; height = info.getBottomEnd()[1] + 1; currentLineLen = 0; int currentLineIndex = 0; int baseLo = g1.getFontMetrics().getAscent(); for (int i = 0; i < desc.length(); i++) { String c = desc.substring(i, i + 1); int charWidth = g.getFontMetrics(font).stringWidth(c); if (currentLineLen + charWidth > width) { currentLineIndex++; currentLineLen = 0; g1.drawString(c, currentLineLen + startX - 5, -5 + height + baseLo + fontHeight * (currentLineIndex) + wordTopMargin); currentLineLen = charWidth; continue; } g1.drawString(c, currentLineLen + startX - 5, -5 + height + baseLo + fontHeight * (currentLineIndex) + wordTopMargin); currentLineLen += charWidth; } //處理二維碼下日期 String date = info.getDate(); g1.drawString(date, 5, 6 + height + baseLo + fontHeight * (currentLineIndex) + wordTopMargin); g1.dispose(); bm = bm1; } catch (Exception e) { e.printStackTrace(); } } try { ImageIO.write(bm, info.getFormat(), output); } catch (Exception e) { e.printStackTrace(); } } /** * 3.建立 帶logo和文字的二維碼 * * @param info * @param file */ public void createCodeImage(CodeModel info, File file) { File parent = file.getParentFile(); if (!parent.exists()) parent.mkdirs(); OutputStream output = null; try { output = new BufferedOutputStream(new FileOutputStream(file)); dealLogoAndDesc(info, output); output.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { output.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 3.建立 帶logo和文字的二維碼 * * @param info * @param filePath */ public void createCodeImage(CodeModel info, String filePath) { createCodeImage(info, new File(filePath)); } /** * 4.建立 帶logo和文字的二維碼 * * @param filePath */ public void createCodeImage(String contents, String filePath) { CodeModel codeModel = new CodeModel(); codeModel.setContents(contents); createCodeImage(codeModel, new File(filePath)); } /** * 5.讀取 二維碼 獲取二維碼中正文 * * @param input * @return */ public String decode(InputStream input) { Map<DecodeHintType, Object> hint = new HashMap<DecodeHintType, Object>(); hint.put(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE); String result = ""; try { BufferedImage img = ImageIO.read(input); int[] pixels = img.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth()); LuminanceSource source = new RGBLuminanceSource(img.getWidth(), img.getHeight(), pixels); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); QRCodeReader reader = new QRCodeReader(); Result r = reader.decode(bitmap, hint); result = r.getText(); } catch (Exception e) { result = "讀取錯誤"; } return result; } public static void main(String[] args) { String imgname = String.valueOf(System.currentTimeMillis()) + ".png"; CodeModel info = new CodeModel(); info.setContents("客戶:倍特 品牌:倍特 型號:XH001 日期:2018-06-19 檢驗員:易工"); info.setWidth(68); info.setHeight(68); info.setFontSize(12); info.setLogoFile(new File("F:\\軟體安全下載目錄\\personnelManage\\" + imgname)); info.setDesc("玫瑰之約"); info.setDate("2018-06-19"); info.setLogoFile(null); QR_Code code = new QR_Code(); } }

2.二維碼實體類

public class CodeModel {
  
    /**
     * @return the date
     */
    public String getDate() {
        return date;
    }
  
    /**
     * @param date
     *            the date to set
     */
    public void setDate(String date) {
        this.date = date;
    }
  
    /**
     * @return the contents
     */
    public String getContents() {
        return contents;
    }
  
    /**
     * @param contents
     *            the contents to set
     */
    public void setContents(String contents) {
        this.contents = contents;
    }
  
    /**
     * @return the width
     */
    public int getWidth() {
        return width;
    }
  
    /**
     * @param width
     *            the width to set
     */
    public void setWidth(int width) {
        this.width = width;
    }
  
    /**
     * @return the height
     */
    public int getHeight() {
        return height;
    }
  
    /**
     * @param height
     *            the height to set
     */
    public void setHeight(int height) {
        this.height = height;
    }
  
    /**
     * @return the format
     */
    public String getFormat() {
        return format;
    }
  
    /**
     * @param format
     *            the format to set
     */
    public void setFormat(String format) {
        this.format = format;
    }
  
    /**
     * @return the character_set
     */
    public String getCharacter_set() {
        return character_set;
    }
  
    /**
     * @param character_set
     *            the character_set to set
     */
    public void setCharacter_set(String character_set) {
        this.character_set = character_set;
    }
  
    /**
     * @return the fontSize
     */
    public int getFontSize() {
        return fontSize;
    }
  
    /**
     * @param fontSize
     *            the fontSize to set
     */
    public void setFontSize(int fontSize) {
        this.fontSize = fontSize;
    }
  
    /**
     * @return the logoFile
     */
    public File getLogoFile() {
        return logoFile;
    }
  
    /**
     * @param logoFile
     *            the logoFile to set
     */
    public void setLogoFile(File logoFile) {
        this.logoFile = logoFile;
    }
  
    /**
     * @return the logoRatio
     */
    public float getLogoRatio() {
        return logoRatio;
    }
  
    /**
     * @param logoRatio
     *            the logoRatio to set
     */
    public void setLogoRatio(float logoRatio) {
        this.logoRatio = logoRatio;
    }
  
    /**
     * @return the desc
     */
    public String getDesc() {
        return desc;
    }
  
    /**
     * @param desc
     *            the desc to set
     */
    public void setDesc(String desc) {
        this.desc = desc;
    }
  
    /**
     * @return the whiteWidth
     */
    public int getWhiteWidth() {
        return whiteWidth;
    }
  
    /**
     * @param whiteWidth
     *            the whiteWidth to set
     */
    public void setWhiteWidth(int whiteWidth) {
        this.whiteWidth = whiteWidth;
    }
  
    /**
     * @return the bottomStart
     */
    public int[] getBottomStart() {
        return bottomStart;
    }
  
    /**
     * @param bottomStart
     *            the bottomStart to set
     */
    public void setBottomStart(int[] bottomStart) {
        this.bottomStart = bottomStart;
    }
  
    /**
     * @return the bottomEnd
     */
    public int[] getBottomEnd() {
        return bottomEnd;
    }
  
    /**
     * @param bottomEnd
     *            the bottomEnd to set
     */
    public void setBottomEnd(int[] bottomEnd) {
        this.bottomEnd = bottomEnd;
    }
  
    /**
     * 正文
     */
    private String contents;
    /**
     * 二維碼寬度
     */
    private int width = 400;
    /**
     * 二維碼高度
     */
    private int height = 400;
    /**
     * 圖片格式
     */
    private String format = "png";
    /**
     * 編碼方式
     */
    private String character_set = "utf-8";
    /**
     * 字型大小
     */
    private int fontSize = 12;
    /**
     * logo
     */
    private File logoFile;
    /**
     * logo所佔二維碼比例
     */
    private float logoRatio = 0.20f;
    /**
     * 二維碼下文字
     */
    private String desc;
    /**
     * 下方日期
     */
    private String date;
    private int whiteWidth;//白邊的寬度
    private int[] bottomStart;//二維碼最下邊的開始座標
    private int[] bottomEnd;//二維碼最下邊的結束座標
  
}

3.action中呼叫

@ResponseBody
    @RequestMapping(value = "/addqrcode")
    public String addqrcode(HttpServletRequest request, String msg) throws Exception {
        String realPath = request.getSession().getServletContext().getRealPath("/") + "\\qrcode\\";
        msg = String.valueOf(System.currentTimeMillis()) + ".png";
        CodeModel info = new CodeModel();
        info.setContents("客戶:" + request.getParameter("customer") + " 品牌:" + request.getParameter("brand") + " 型號:"
                + request.getParameter("model") + " 日期:" + request.getParameter("addtime") + " 檢驗員:"
                + request.getParameter("testpersion"));
        info.setWidth(68);
        info.setHeight(68);
        info.setFontSize(12);
        info.setLogoFile(new File(realPath + msg));
        info.setDesc(request.getParameter("brand"));
        info.setDate(request.getParameter("addtime"));
        info.setLogoFile(null);
        QR_Code code = new QR_Code();
        code.createCodeImage(info, realPath + msg);
        return msg;
    }

以上方法就可以實現帶logo,以及下方顯示文字的二維碼。不需要logo,引數可以傳null。

接來下說說二維碼的列印,根據實際需要可以自定義設定二維碼的尺寸,以及圖片的格式

4.列印方法

需要注意的是:一是生成儲存二維碼的地址,二是印表機驅動必須啟動

/**
     * 列印二維碼
     *
     * @param fileName
     * @param count
     */
    @ResponseBody
    @RequestMapping(value = "/printImage")
    public static void printImage(String fileName, int count, HttpServletRequest request) {
        String realPath = request.getSession().getServletContext().getRealPath("/") + "\\qrcode\\";
        try {
            DocFlavor dof = null;
  
            if (fileName.endsWith(".gif")) {
                dof = DocFlavor.INPUT_STREAM.GIF;
            } else if (fileName.endsWith(".jpg")) {
                dof = DocFlavor.INPUT_STREAM.JPEG;
            } else if (fileName.endsWith(".png")) {
                dof = DocFlavor.INPUT_STREAM.PNG;
            }
            // 獲取預設印表機 
            PrintService ps = PrintServiceLookup.lookupDefaultPrintService();
  
            PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
            //          pras.add(OrientationRequested.PORTRAIT); 
            //          pras.add(PrintQuality.HIGH); 
            pras.add(new Copies(count));
            pras.add(MediaSizeName.ISO_A10); // 設定列印的紙張 
  
            DocAttributeSet das = new HashDocAttributeSet();
            das.add(new MediaPrintableArea(0, 0, 1, 1, MediaPrintableArea.INCH));
            FileInputStream fin = new FileInputStream(realPath + fileName);
            Doc doc = new SimpleDoc(fin, dof, das);
            DocPrintJob job = ps.createPrintJob();
  
            job.print(doc, pras);
            fin.close();
        } catch (IOException ie) {
            ie.printStackTrace();
        } catch (PrintException pe) {
            pe.printStackTrace();
        }
    }

看著是不是很簡單,完美的解決。