JAVA实现QRCode的二维码生成以及打印

2018-07-04 02:08:39来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

不说废话了直接上代码

注意使用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();
        }
    }

  

看着是不是很简单,完美的解决。

 

到这里已经完成了对文件的预览功能,如有需要可以加我Q群【308742428】大家一起讨论技术。

后面会不定时为大家更新文章,敬请期待。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Java开发微服务为什么一定要选spring cloud?

下一篇:JAVA数据结构之链表