Browse Source

二维码生成方式改成生成二维码图片,再打印图片

master
han\hanst 5 months ago
parent
commit
67473f1f58
  1. 3
      build.gradle
  2. 12
      src/main/java/com/gaotao/modules/base/service/Impl/ReportLabelListServiceImpl.java
  3. 102
      src/main/java/com/gaotao/modules/base/utils/ZplGenerator.java

3
build.gradle

@ -109,6 +109,9 @@ dependencies {
implementation 'com.itextpdf:itext7-core:7.2.5'
implementation 'com.itextpdf:html2pdf:4.0.5'
implementation 'com.google.zxing:core:3.5.3'
implementation 'com.google.zxing:javase:3.5.3'
}
test {

12
src/main/java/com/gaotao/modules/base/service/Impl/ReportLabelListServiceImpl.java

@ -169,17 +169,15 @@ public class ReportLabelListServiceImpl extends ServiceImpl<ReportLabelListMappe
rfidFlag = labelSettingDataList.getFirst().getRfidFlag();
}
try {
// 1. 生成带真实数据的ZPL代码如果没有提供ZPL代码
String zplCode = printRequest.getZplCode();
if (zplCode == null || zplCode.trim().isEmpty()) {
log.info("未提供ZPL代码,使用真实数据生成ZPL: reportId={}", printRequest.getReportId());
zplCode = previewLabelWithRealData(printRequest.getReportId());
printRequest.setZplCode(zplCode);
}
// 1. 生成带真实数据的ZPL代码
String zplCode = previewLabelWithRealData(printRequest.getReportId());
printRequest.setZplCode(zplCode);
// 2. 验证ZPL代码
if (zplCode == null || zplCode.trim().isEmpty()) {
throw new RuntimeException("ZPL代码不能为空");
} else {
log.info("生成的ZPL代码: {}", zplCode);
}
// 3. 获取用户的打印机配置

102
src/main/java/com/gaotao/modules/base/utils/ZplGenerator.java

@ -8,6 +8,17 @@ import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.List;
import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
/**
* ZPL代码生成器
* 统一处理不同打印方向的ZPL代码生成
@ -382,32 +393,83 @@ public class ZplGenerator {
* 生成二维码ZPL代码
*/
private String generateQRCodeZPL(ReportLabelList element, int x, int y) {
String orientation = config.getQrcodeOrientation();
String data = element.getData() != null ? element.getData() : "";
// 将毫米转换为ZPL尺寸单位
int sizeInDots = Math.max(1, Math.round((element.getHeight() != null ? element.getHeight() : 10) * this.dpi / 25.4f));
int size = Math.max(1, Math.min(10, Math.round(sizeInDots / 25f)));
// 根据数据长度自动调整最小尺寸
if (data.length() > 300) {
size = Math.max(size, 8);
} else if (data.length() > 200) {
size = Math.max(size, 6);
} else if (data.length() > 100) {
size = Math.max(size, 4);
} else {
size = Math.max(size, 2);
try {
return generateZplQRCode(data, sizeInDots, x, y);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 根据数据类型选择模式
if (data.matches("^\\d+$")) {
// 纯数字内容使用数字模式
return String.format("^FO%d,%d^BQ%s,2,%d^FDMN,%s^FS", x, y, orientation, size, data);
} else {
// 混合内容使用自动模式
return String.format("^FO%d,%d^BQ%s,2,%d^FDMA,%s^FS", x, y, orientation, size, data);
/**
* 生成二维码并转为 ZPL
*
* @param content 二维码内容支持中文
* @param size 二维码宽高像素 == dots
* @param x 打印起点 X 坐标单位dots
* @param y 打印起点 Y 坐标单位dots
* @return ZPL 字符串
*/
public String generateZplQRCode(String content, int size, int x, int y) throws Exception {
byte[] qrBytes = generateQRCode(content, size, size);
return convertToZpl(qrBytes, x, y);
}
// 1. 生成二维码支持中文
private static byte[] generateQRCode(String content, int width, int height) throws Exception {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix bitMatrix = new MultiFormatWriter().encode(
content,
BarcodeFormat.QR_CODE,
width,
height,
hints
);
BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
return baos.toByteArray();
}
// 2. 转换 PNG 图片为 ZPL ^GF 指令
private static String convertToZpl(byte[] imageBytes, int x, int y) throws Exception {
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
int widthBytes = (image.getWidth() + 7) / 8; // 每行字节数
int totalBytes = widthBytes * image.getHeight();
StringBuilder zpl = new StringBuilder();
zpl.append("^FO").append(x).append(",").append(y).append("\n");
zpl.append("^GFA,").append(totalBytes).append(",").append(totalBytes).append(",").append(widthBytes).append(",");
StringBuilder imageData = new StringBuilder();
for (int yPos = 0; yPos < image.getHeight(); yPos++) {
int bit = 0;
int currentByte = 0;
for (int xPos = 0; xPos < image.getWidth(); xPos++) {
int rgb = image.getRGB(xPos, yPos);
int gray = (rgb >> 16 & 0xff) * 299 + (rgb >> 8 & 0xff) * 587 + (rgb & 0xff) * 114;
gray = gray / 1000;
currentByte <<= 1;
if (gray < 128) { // 黑色点
currentByte |= 1;
}
bit++;
if (bit == 8) {
imageData.append(String.format("%02X", currentByte));
bit = 0;
currentByte = 0;
}
}
if (bit > 0) {
currentByte <<= (8 - bit);
imageData.append(String.format("%02X", currentByte));
}
}
zpl.append(imageData);
return zpl.toString();
}
/**

Loading…
Cancel
Save