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

小编 2026-07-06 阅读:1520 评论:0
喜欢的朋友可以关注下,粉...

喜欢的朋友可以关注下,粉丝也缺。


不说废话了直接上代码

注意使用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】大家一起讨论技术。

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

喜欢的朋友可以关注下,粉丝也缺。



版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
标签列表