二维码生成,普通的就不说了,问题就是需要再二维码中填写100-200的字的中文,奇葩需求对吧
文字过大会导致二维码过密,打印出来扫不出的问题
1:生成一个大的二维码
2:把这个二维码缩小到50*50,贴到pdf中
功能实现简单,做了一版加密的优化

java通过加密,可以通过java解密,也可以通过html实现解密验证
package org.easwift.modules.online_doc.utils; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.WriterException; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import lombok.extern.slf4j.Slf4j; import org.easwift.modules.admin.enums.FlowTypeEnum; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterOutputStream; /** * @author tongzuqi * @create 2025/8/1 9:21 AM */ @Slf4j public class QRCodeUtil { /** * 生成二维码图片(原始) * @param text 二维码内容 * @param width 二维码宽度 * @param height 二维码高度 * @param margin 边框大小(默认为4) * @param filePath 文件路径 * @throws WriterException * @throws IOException */ public static void generateV1(String text,int width,int height,int margin,String filePath) throws WriterException, IOException { QRCodeWriter qrCodeWriter = new QRCodeWriter(); Map<EncodeHintType, Object> hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); hints.put(EncodeHintType.MARGIN, margin); BitMatrix bitMatrix = qrCodeWriter.encode( text, BarcodeFormat.QR_CODE, width, height, hints); MatrixToImageWriter.writeToPath(bitMatrix, "PNG", Paths.get(filePath)); } /** * 生成二维码图片(压缩中文内容后生成二维码图片V2版本,压缩和解压方法需要配套使用 * @param text 二维码内容 * @param width 二维码宽度 * @param height 二维码高度 * @param margin 边框大小(默认为4) * @param filePath 文件路径 * @throws WriterException * @throws IOException */ public static void generateV2(String text,int width,int height,int margin,String filePath) throws WriterException, IOException { QRCodeWriter qrCodeWriter = new QRCodeWriter(); Map<EncodeHintType, Object> hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); hints.put(EncodeHintType.MARGIN, margin); text = compressChinese(text); log.info("generateV2压缩后内容:{}", text); log.info("generateV2解密后内容:{}", decompressChinese(text)); BitMatrix bitMatrix = qrCodeWriter.encode( text, BarcodeFormat.QR_CODE, width, height, hints); MatrixToImageWriter.writeToPath(bitMatrix, "PNG", Paths.get(filePath)); } public static String generateReport(QRCodeUtilGenerateFo qrCodeUtilGenerateFo){ int index = 60;//字数截取 String fileName = String.format("%s_%s.png",qrCodeUtilGenerateFo.getWtId(),System.currentTimeMillis()); String filePath = qrCodeUtilGenerateFo.getFilePath() + "/qrCode/"+qrCodeUtilGenerateFo.getFlowTypeEnum().getCode()+"/"+fileName; String text = String.format("reportNo=%s&projectName=%s&requester=%s&sampleName=%s", qrCodeUtilGenerateFo.getReportNo(), qrCodeUtilGenerateFo.getProjectName().length() > index ? qrCodeUtilGenerateFo.getProjectName().substring(0,index) + "..." : qrCodeUtilGenerateFo.getProjectName(), qrCodeUtilGenerateFo.getRequester().length() > index ? qrCodeUtilGenerateFo.getRequester().substring(0,index) + "..." : qrCodeUtilGenerateFo.getRequester(), qrCodeUtilGenerateFo.getSampleName() ); try { QRCodeUtil.generateV2(text,1000, 1000, 0,filePath); log.info("QRCodeUtil工具类, 生成报告二维码 : " + filePath); return filePath; } catch (WriterException e) { log.error("QRCodeUtil工具类, WriterException : " + e.getMessage()); } catch (IOException e) { log.error("QRCodeUtil工具类, IOException :: " + e.getMessage()); } return ""; } public static void main(String[] args) { // // Try to generate a QR code image // try { // // Define the variables to be used in the QR code // String reportNo = "一二三四五六七八九十"; // String reportId = "20"; // String projectName = "一二三四五六七八九十"; // String requester = "一二三四五六七八九十"; // String sampleName = "一"; // // Generate a file name using the current time // String fileName = String.format("%s_%s_%s.png",reportNo,reportId,System.currentTimeMillis()); // // Define the file path // String filePath = "/Users/tongzuqi/Desktop/qrCode/"+fileName; // // Generate the text to be encoded in the QR code // String text = String.format("reportNo=%s&projectName=%s&requester=%s&sampleNo=%s",reportNo,projectName,requester,sampleName); // // Generate the QR code image // QRCodeUtil.generateV2(text,1000, 1000, 0,filePath); // } catch (WriterException e) { // // If a WriterException is thrown, print an error message // System.out.println("Could not generate QR Code, WriterException :: " + e.getMessage()); // } catch (IOException e) { // // If an IOException is thrown, throw a RuntimeException // throw new RuntimeException(e); // } QRCodeUtil.generateReport(new QRCodeUtilGenerateFo().setFlowTypeEnum(FlowTypeEnum.ENTRUST).setFilePath("/Users/tongzuqi/Desktop") .setReportNo("XCBG-2025-04-21-001").setRequester("委托单位填写").setProjectName("测试项目名称40字显示测试项目名称40字显示测试项目名称40字显示测试项目名称40字显示测试项目名称40字显示测试项目名称往后隐藏123456").setWtId(11) .setSampleName("水泥") ); } // 在生成二维码前压缩文本 public static String compressChinese(String text) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); try (DeflaterOutputStream deflater = new DeflaterOutputStream(out, new Deflater(Deflater.BEST_COMPRESSION))) { deflater.write(text.getBytes(StandardCharsets.UTF_8)); } return Base64.getUrlEncoder().withoutPadding().encodeToString(out.toByteArray()); } // 解压方法(供扫描端使用) public static String decompressChinese(String compressed) throws IOException { byte[] data = Base64.getUrlDecoder().decode(compressed); ByteArrayOutputStream out = new ByteArrayOutputStream(); try (InflaterOutputStream inflater = new InflaterOutputStream(out)) { inflater.write(data); } return new String(out.toByteArray(), StandardCharsets.UTF_8); } }
html 验证
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>文本解压工具</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/pako/2.1.0/pako.min.js"></script> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } textarea { width: 100%; height: 100px; margin: 10px 0; } button { padding: 8px 15px; background: #4CAF50; color: white; border: none; cursor: pointer; } button:hover { background: #45a049; } </style> </head> <body> <h1>文本解压工具</h1> <p>输入压缩后的Base64 URL编码字符串:</p> <textarea id="compressedInput" placeholder="请输入压缩后的文本..."></textarea> <button onclick="decompress()">解压</button> <p>解压结果:</p> <textarea id="resultOutput" readonly></textarea> <script> function decompress() { const compressedInput = document.getElementById('compressedInput').value.trim(); const resultOutput = document.getElementById('resultOutput'); if (!compressedInput) { alert('请输入要解压的内容'); return; } try { // 1. Base64 URL解码 const base64 = compressedInput .replace(/-/g, '+') .replace(/_/g, '/'); const binaryString = atob(base64); const bytes = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } // 2. 使用pako解压 const decompressed = pako.inflate(bytes, { to: 'string' }); // 3. 显示结果 resultOutput.value = decompressed; } catch (e) { resultOutput.value = '解压失败: ' + e.message; console.error(e); } } </script> </body> </html>
浙公网安备 33010602011771号