Java-生成二维码带多行文字-支持自动换行-支持tab缩进效果-支持高度自适应

最新版本更新
https://code.jiangjiesheng.cn/article/352

1. 样式1 :

2.1 效果图 :

忽略红色,最外层的红色只是方便展示当前图片的宽高
在这里插入图片描述

2.2 代码

package cn.jiangjiesheng.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * 或者换个思路,写html导出pdf 或者导出png ,不知道能否行得通?参考 eduinp 生产pdf和zip打包的逻辑的逻辑。
 * <dependency>
 * <groupId>com.google.zxing</groupId>
 * <artifactId>core</artifactId>
 * <version>3.4.1</version>
 * </dependency>
 * <dependency>
 * <groupId>com.google.zxing</groupId>
 * <artifactId>javase</artifactId>
 * <version>3.4.1</version>
 * </dependency>
 */
public class QRCodeWithTextGenerator {

    private final static Logger log = LoggerFactory.getLogger(QRCodeWithTextGenerator.class);

    private static boolean IS_DEBUG = true;
    private static final String OUTPUT_FILE = "qrcode.png"; // 输出文件名
    private static final String SPACE = " "; // 输出文件名
    private static int QRCODE_WIDTH = 200;
    private static final int FONT_SIZE = 12;
    private static final int EXPANSION_FACTOR = 5; // textInfo 扩大倍数 ,按 \\n 换行(一条属性信息),一条属性信息可能比较长,还会继续换行,最终来裁切图片,此值大致表示每条属性信息最多可能的换行条数
    private static final int SPACE_COUNT = 14; // 换行时左侧的空格占位
    private static Font FONT = new Font("Microsoft YaHei", Font.PLAIN, FONT_SIZE);

    public static void main(String[] args) {
        try {
            //main 方法测试使用 直接使用 static 默认值就行
            //init();

            String QR_CODE_TEXT = "http://code.jiangjiesheng.cn";
            String textInfo = "设备名称: xxxx\n所属机构: 123456789123456789123456789\n所属测点: xxxx\n所属区域: 江苏省南京市江北新区安徽省安庆市\n其他信息: 联系人 xxx \n";

            BufferedImage image = generateQRCodeWithText(QR_CODE_TEXT, QRCODE_WIDTH, textInfo);
            saveImageToFile(image, OUTPUT_FILE);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @PostConstruct
    public void init() throws IOException, FontFormatException {
        // 加载系统字体
        // FONT = new Font("Microsoft YaHei", Font.PLAIN, FONT_SIZE);

        // 加载自定义字体
        try {
            writeFontFile(this.getClass(), "Microsoft YaHei-normal.ttc", false);
            String fontPath = getFontFilePath4Read("Microsoft YaHei-normal.ttc");

            FONT = Font.createFont(Font.TRUETYPE_FONT, new File(fontPath)).deriveFont(Font.PLAIN, FONT_SIZE);
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            ge.registerFont(FONT);
        } catch (IOException | FontFormatException e) {
            log.error("加载自定义字体出错", e);
        }
    }

    private static BufferedImage generateQRCodeWithText(String codeContent, int qrcodeWidthHeight, String textInfo) throws WriterException {
        // 设置二维码参数
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.MARGIN, 1); // 边距

        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode(codeContent, BarcodeFormat.QR_CODE, qrcodeWidthHeight, qrcodeWidthHeight, hints);

        int qrWidth = bitMatrix.getWidth();
        int qrHeight = bitMatrix.getHeight();

        // 创建二维码图像
        BufferedImage qrImage = new BufferedImage(qrWidth, qrHeight, BufferedImage.TYPE_INT_ARGB);
        for (int x = 0; x < qrWidth; x++) {
            for (int y = 0; y < qrHeight; y++) {
                qrImage.setRGB(x, y, bitMatrix.get(x, y) ? Color.BLACK.getRGB() : Color.WHITE.getRGB());
            }
        }

        // 创建一个新的图像,包含二维码和文本
        int textPadding = 10; // 文本区域的内边距
        int imageWidth = qrcodeWidthHeight + textPadding; // 文本区域的内边距

        int lineHeight = FONT_SIZE + 10; // 行高

        //默认每一行不需要换行的高度
        int textHeightNoWrap = (int) (lineHeight * (countLines(textInfo))); // +1 最后一行后也保留个空行,模拟padding
        int textMaxHeightWrapped = textHeightNoWrap * EXPANSION_FACTOR;

        // 计算总的宽度和高度
        int totalWidth = qrWidth;
        // int totalHeightNoWrap = qrHeight + textHeightNoWrap &
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值