生成二维码、导出为表格例子

目的

        因为业务需求,需要做一个生成二维码,并且导出为表格,在此举例,具体根据自己需求举一反三或者给予灵感。这个是通过谷歌的一个生成二维码的jar包,生成二维码,简单易懂,导入依赖即可用。不过下文是基于自己的理解,如果有不对的地方指出一下。

代码

第一步:    导入依赖

<!--二维码-->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <scope>provided</scope>
</dependency>
<!--这个是解析二维码的依赖-->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.3.0</version>
</dependency>

第二步: 创建工具类

package com.hanlong.guns.core.util;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class QRCodeUtil {
    private static final String CHARSET = "utf-8";
    private static final String FORMAT_NAME = "JPG";
    // 二维码尺寸
    private static final int QRCODE_WIDTH = 300;
    private static final int QRCODE_HEIGHT = 300;
    private static final int QRCODE_SIZE = 300;
    // LOGO宽度
    private static final int WIDTH = 60;
    // LOGO高度
    private static final int HEIGHT = 60;

    private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//二维码的纠错程度
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);//指定适用的字符编码
        hints.put(EncodeHintType.MARGIN, 3);//二维码的白边,如果要展示二维码内容,建议留着
        //生成二维码
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_WIDTH, QRCODE_HEIGHT,hints);

        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        //生成二维码的辅助类
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //按照指定大小将二维码生成在图像image中
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        //不嵌入图像直接返回
        if (imgPath == null || "".equals(imgPath)) {
            return image;
        }
        // 插入图片
        QRCodeUtil.insertImage(image, imgPath, needCompress);
        return image;
    }

    private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) 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);
        // 按照指定的大小压缩压缩LOGO
        if (needCompress) {
            if (width > WIDTH) {
                width = WIDTH;
            }
            if (height > HEIGHT) {
                height = HEIGHT;
            }
            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 = (QRCODE_SIZE - width) / 2;
        int y = (QRCODE_SIZE - height) / 2;
        graph.drawImage(src, x, y, width, height, null);
        Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }
    //二维码编码处理
    public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
        BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
        //若目标存储位置不存在,则新建生成位置
        mkdirs(destPath);
        ImageIO.write(image, FORMAT_NAME, new File(destPath));
    }
    //不传递存储路径调用
    public static BufferedImage encode(String content, String imgPath, boolean needCompress) throws Exception {
        BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
        return image;
    }
    //创建文件夹
    public static void mkdirs(String destPath) {
        File file = new File(destPath);
        // 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
        if (!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
    }
    //不对嵌入图片进行压缩
    public static void encode(String content, String imgPath, String destPath) throws Exception {
        QRCodeUtil.encode(content, imgPath, destPath, false);
    }
    //不嵌入图片
    public static void encode(String content, String destPath) throws Exception {
        QRCodeUtil.encode(content, null, destPath, false);
    }

    public static void encode(String content, String imgPath, OutputStream output, boolean needCompress)
            throws Exception {
        BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
        ImageIO.write(image, FORMAT_NAME, output);
    }

    public static void encode(String content, OutputStream output) throws Exception {
        QRCodeUtil.encode(content, null, output, false);
    }
    //对文件进行解码操作
    public static String decode(File file) throws Exception {
        BufferedImage image;
        image = ImageIO.read(file);
        if (image == null) {
            return null;
        }
        //解析二维码的辅助类
        BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
        Result result;
        Hashtable hints = new Hashtable();
        hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
        result = new MultiFormatReader().decode(bitmap, hints);
        String resultStr = result.getText();
        return resultStr;
    }

    public static String decode(String path) throws Exception {
        return QRCodeUtil.decode(new File(path));
    }


    /**
     * 给二维码下方附加说明文字
     *
     * @param pressText 文字
     * @param newImg    带文字的图片
     * @param image     需要添加文字的图片
     * @为图片添加文字
     */
    public static BufferedImage pressText(String pressText, String newImg, BufferedImage image, int fontStyle, Color color, int fontSize, int width, int height) {

        /**
        *    这个地方代表二维码图片上哪个地方需要写上文字,如果没有设置好就会重叠在一起
        *    在生成二维码的时候适当留点白边展示文字
        */
        //计算文字开始的位置
        //x开始的位置:(图片宽度-字体大小*字的个数)/2
        int startX = 95;
        //这个地方好像有固定算法,不过我管他花里胡哨,直接按照需求设置
//        int startX = (width - (fontSize * pressText.length())) / 3 - 28;
        //y开始的位置:图片高度-(图片高度-图片宽度)/2
        int startY = 290;
//        int startY = height - (height - width) / 2 - 30;

        try {
            int imageW = image.getWidth();
            int imageH = image.getHeight();
            Graphics g = image.createGraphics();
            g.drawImage(image, 0, 0, imageW, imageH, null);
            g.setColor(color);
            g.setFont(new Font("粗体", Font.BOLD, 18));
            g.drawString(pressText, startX, startY);
            g.drawString("", startX - 5, startY + 30);
            g.dispose();
            //这个地方是插入二维码中间图标的
//            FileOutputStream out = new FileOutputStream(newImg);
//            ImageIO.write(image, "png", out);
//            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
//            encoder.encode(image);
//            out.close();
            //System.out.println("image press success");
            return image;

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e);
        }
        return  null;
    }

}

第三步: 使用工具

在这里面有的包是会报红的,根据自己的需求去做,我会保留核心代码。

public class TbconsoleCardController {

    /**
     * 导出
     */
    @RequestMapping(value = "/exportExcel")
    @ResponseBody
    public void exportExcel(HttpServletResponse response) {
        List<BufferedImage> imgList = createQrCode("批量的二维码内容");
        //导出表格
        exceImgList(imgList, response);
    }

    /**
     * 批量生成二维码
     */
    public List<BufferedImage> createQrCode(List<String> deccaNoList){
        List<BufferedImage> imgList = new ArrayList<>();
        int width = 300;
        int height = 380;
        int font = 10; //字体大小
        int fontStyle = 1; //字体风格
        for (String "二维码内容": deccaNoList) {
            try {
                BufferedImage encode = QRCodeUtil.encode("二维码内容", null, true);
                BufferedImage image =  QRCodeUtil.pressText("二维码内容", "", encode, fontStyle, Color.black, font, width, height);
                imgList.add(image);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return imgList;
    }

    /**
     * 导出批量生成的二维码
     * @param imgList
     * @param response
     */
    public void exceImgList(List<BufferedImage> imgList,HttpServletResponse response){
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet1 = wb.createSheet("二维码");
        sheet1.setColumnWidth(0, 45*256);
        sheet1.setDefaultRowHeight((short)(4636));
        //画图的顶级管理器,一个sheet只能获取一个(一定要注意这点)
        HSSFPatriarch patriarch = sheet1.createDrawingPatriarch();
        FileOutputStream fileOut = null;
        try {
            int i = 0;
            for (BufferedImage encode : imgList) {
                // 先把读进来的图片放到一个ByteArrayOutputStream中,以便产生ByteArray
                ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
                ImageIO.write(encode, "png", byteArrayOut);
                // anchor主要用于设置图片的属性
                /**
                 * 该构造函数有8个参数
                 * 前四个参数是控制图片在单元格的位置,分别是图片距离单元格left,top,right,bottom的像素距离
                 * 后四个参数,前两个表示图片左上角所在的cellNum和 rowNum,后两个参数对应的表示图片右下角所在的cellNum和 rowNum,
                 * excel中的cellNum和rowNum的index都是从0开始的
                 */
                HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1020, 255,(short) 0, i, (short) 0, i);
                // 插入图片
                patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
                i++;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            if (fileOut != null) {
                try {
                    fileOut.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
//这个地方可选导出到表格,也可导出到指定的文件夹
        try {
            response.setContentType("application/vnd.ms-excel;");
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" +
                    URLEncoder.encode("二维码", "UTF-8")+".xls");
            wb.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}

 结果:

其他文献

java生成二维码图片(有logo),并在图片下方附文字_新丨客的博客-CSDN博客

【Java】------- Java实现多个二维码图片生成并存入Excel文件中然后下载(可以添加图标,和文字)_java 批量下载二维码返回excel_皮皮冰要做大神的博客-CSDN博客

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万能冲!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值