From adbe071c0551defaef1d8247db4f587aafb69eeb Mon Sep 17 00:00:00 2001
From: "DESKTOP-J7ED0MB\\yinjinlu" <411641505@qq.com>
Date: Mon, 17 Oct 2022 22:00:50 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9D=A1=E7=A0=81=E6=94=AF=E6=8C=81=E4=BA=8C?=
=?UTF-8?q?=E7=BB=B4=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ktg-common/pom.xml | 6 +
.../ktg/common/constant/UserConstants.java | 8 +
.../ktg/common/utils/barcode/BarcodeUtil.java | 213 +++++++++++++++---
.../wm/service/impl/WmBarcodeServiceImpl.java | 8 +-
4 files changed, 202 insertions(+), 33 deletions(-)
diff --git a/ktg-common/pom.xml b/ktg-common/pom.xml
index 321f9d0..cb248e6 100644
--- a/ktg-common/pom.xml
+++ b/ktg-common/pom.xml
@@ -144,6 +144,12 @@
2.0
+
+ com.google.zxing
+ core
+ 3.3.3
+
+
\ No newline at end of file
diff --git a/ktg-common/src/main/java/com/ktg/common/constant/UserConstants.java b/ktg-common/src/main/java/com/ktg/common/constant/UserConstants.java
index d1d94f5..56211d6 100644
--- a/ktg-common/src/main/java/com/ktg/common/constant/UserConstants.java
+++ b/ktg-common/src/main/java/com/ktg/common/constant/UserConstants.java
@@ -184,4 +184,12 @@ public class UserConstants
public static final String VIRTUAL_WS ="XBKKQ_VIRTUAL";
public static final String VIRTUAL_WA ="XBKKW_VIRTUAL";
+ /**
+ * 条码类型
+ */
+ public static final String QR_CODE = "QR_CODE";
+ public static final String EAN_CODE = "EAN_CODE";
+ public static final String UPC_CODE = "UPC_CODE";
+ public static final String CODE39_CODE = "CODE39_CODE";
+
}
diff --git a/ktg-common/src/main/java/com/ktg/common/utils/barcode/BarcodeUtil.java b/ktg-common/src/main/java/com/ktg/common/utils/barcode/BarcodeUtil.java
index 4ff582a..16e11a4 100644
--- a/ktg-common/src/main/java/com/ktg/common/utils/barcode/BarcodeUtil.java
+++ b/ktg-common/src/main/java/com/ktg/common/utils/barcode/BarcodeUtil.java
@@ -1,59 +1,102 @@
package com.ktg.common.utils.barcode;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import com.ktg.common.constant.UserConstants;
import com.ktg.common.utils.StringUtils;
+import org.krysalis.barcode4j.impl.AbstractBarcodeBean;
import org.krysalis.barcode4j.impl.code39.Code39Bean;
+import org.krysalis.barcode4j.impl.upcean.EAN13Bean;
+import org.krysalis.barcode4j.impl.upcean.UPCABean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.UnitConv;
-import java.io.ByteArrayOutputStream;
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
-import java.io.FileNotFoundException;
+import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.OutputStream;
-import java.io.File;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
public class BarcodeUtil {
-
- public static File generateFile(String msg, String path) {
+ private static final String CHARSET = "utf-8";
+ private static final String FORMAT_NAME = "PNG";
+ // 二维码尺寸,长宽尺寸一致
+ private static final int QRCODE_SIZE = 300;
+ // 二维码内部logo的宽和高
+ private static final int WIDTH = 60;
+ private static final int HEIGHT = 60;
+
+ public static File generateBarCode(String msg, String barCodeFormat, String path) {
File file = new File(path);
try {
- generate(msg, new FileOutputStream(file));
- } catch (FileNotFoundException e) {
- throw new RuntimeException(e);
- }
+ if(StringUtils.isEmpty(msg)){
+ throw new RuntimeException("条码内容不能为空!");
+ }
+ //检查父级目录是否存在,不存在先新建
+ File parentFile = file.getParentFile();
+ if(!parentFile.exists()){
+ parentFile.mkdirs();
+ }
+ /*
+ * 生成条码
+ */
+ if(UserConstants.QR_CODE.equals(barCodeFormat)){
+ //生成二维码
+ generateQRCode(msg, null, file.getAbsolutePath(), false);
+ }else{
+ //生成一维码
+ generateLineCode(msg, barCodeFormat, file.getAbsolutePath());
+ }
+ }catch (Exception e) {
+ throw new RuntimeException("生成条码发生错误:"+e.getMessage());
+ }
return file;
}
-
- public static byte[] generate(String msg) {
- ByteArrayOutputStream ous = new ByteArrayOutputStream();
- generate(msg, ous);
- return ous.toByteArray();
- }
-
-
- public static void generate(String msg, OutputStream ous) {
- if (StringUtils.isEmpty(msg) || ous == null) {
- return;
- }
-
- Code39Bean bean = new Code39Bean();
-
+ /**
+ * 生成一维条形码
+ * @param msg 条形码的内容
+ * @param barCodeFormat 条形码格式 see {@link UserConstants}
+ * @param destFilePath 条形码存储的路径
+ * @throws Exception
+ */
+ public static void generateLineCode(String msg,String barCodeFormat,String destFilePath) throws Exception {
+ AbstractBarcodeBean bean = null;
+ if(UserConstants.EAN_CODE.equals(barCodeFormat)){
+ bean = new EAN13Bean();
+ }else if(UserConstants.CODE39_CODE.equals(barCodeFormat)){
+ bean = new Code39Bean();
+ }else if(UserConstants.UPC_CODE.equals(barCodeFormat)){
+ bean = new UPCABean();
+ }else{
+ throw new Exception("不支持的条码类型!");
+ }
// 精细度
final int dpi = 150;
- // module宽度
- final double moduleWidth = UnitConv.in2mm(1.0f / dpi);
+ if (bean instanceof Code39Bean) {
+ Code39Bean codeBean = (Code39Bean) bean;
+ // module宽度
+ final double moduleWidth = UnitConv.in2mm(1.0f / dpi);
- // 配置对象
- bean.setModuleWidth(moduleWidth);
- bean.setWideFactor(3);
- bean.doQuietZone(false);
+ // 配置对象
+ bean.setModuleWidth(moduleWidth);
+ codeBean.setWideFactor(3);
+ bean.doQuietZone(false);
+ }
String format = "image/png";
try {
// 输出到流
- BitmapCanvasProvider canvas = new BitmapCanvasProvider(ous, format, dpi,
+ BitmapCanvasProvider canvas = new BitmapCanvasProvider(new FileOutputStream(destFilePath), format, dpi,
BufferedImage.TYPE_BYTE_BINARY, false, 0);
// 生成条形码
@@ -65,4 +108,110 @@ public class BarcodeUtil {
throw new RuntimeException(e);
}
}
+ /**
+ * 生成带logo二维码,并保存到磁盘
+ *
+ * @param content 二维码的内容
+ * @param imgPath 二维码内部插入的图片路径,如果不需要可以传空
+ * @param destFilePath 整个二维码存储的路径
+ * @param needCompress 二维码内部插入的图片是否需要压缩的标识
+ * @throws Exception 异常
+ */
+ public static void generateQRCode(String content, String imgPath, String destFilePath, boolean needCompress) throws Exception {
+ BufferedImage image = createQrCode(content, imgPath, needCompress);
+ ImageIO.write(image, FORMAT_NAME, new File(destFilePath));
+ }
+
+ /**
+ * 生成二维码图片
+ *
+ * @param content 二维码内容
+ * @param imagePath 二维码内部图片路径,如果不需要可以传空
+ * @param needCompress 二维码内部图片是否需要压缩标识
+ * @return 二维码图片
+ * @throws WriterException 异常
+ */
+ private static BufferedImage createQrCode(String content,String imagePath,boolean needCompress) throws WriterException, IOException {
+ /**
+ * EncodeHintType 编码提示类型 枚举类型:
+ * CHARACTER_SET: 设置字符编码类型 "UTF-8" QR_CODE类型默认的编码格式 "ISO-8859-1"
+ * MARGIN: 设置二维码边距,单位像素,值越小,二维码距离四周越近
+ * ERROR_CORRECTION: 设置误差校正
+ * ErrorCorrectionLevel:误差校正等级,L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction
+ * 不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的
+ */
+ Map hints = new ConcurrentHashMap<>(3);
+ hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
+ hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
+ hints.put(EncodeHintType.MARGIN, 1);
+ //加密生成二维码的矩阵对象 二维的0 1 然后根据特定的值选择属性
+ BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
+ int width = bitMatrix.getWidth();
+ int height = bitMatrix.getHeight();
+ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ for (int i = 0; i < width; i++) {
+ for (int j = 0; j < height; j++) {
+ //设置二维码的黑色0xFF000000 和白色0xFFFFFFFF
+ image.setRGB(i, j, bitMatrix.get(i, j) ? 0xFF000000 : 0xFFFFFFFF);
+ }
+ }
+ if (StringUtils.isBlank(imagePath)) {
+ return image;
+ }
+ //插入小图标 logo
+ insertImage(image, imagePath, needCompress);
+ return image;
+ }
+ /**
+ * 将logo插入二维码中间
+ *
+ * @param source 生成的二位码存储对象
+ * @param imagePath 二维码内部图片的路径
+ * 一般的业务场景会把插入的小logo放到oss生成url
+ * @param needCompress 二维码内部图片是否需要压缩
+ * @throws IOException 异常
+ */
+ private static void insertImage(BufferedImage source, String imagePath, boolean needCompress) throws IOException {
+ File file = new File(imagePath);
+ if (!file.exists()) {
+ //可以自定义抛出异常
+ throw new RuntimeException("文件路径不存在:" + imagePath);
+ }
+ //这里修改ImageIO.read() 内可以接受Url InputStream File ImageInputStream
+ Image src = ImageIO.read(file);
+ int width = src.getWidth(null);
+ int height = src.getHeight(null);
+ //是否压缩
+ 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;
+ }
+ Graphics2D graphics = source.createGraphics();
+ int x = (QRCODE_SIZE - width) / 2;
+ int y = (QRCODE_SIZE - height) / 2;
+ graphics.drawImage(src,x,y,width,height,null);
+ Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
+ graphics.setStroke(new BasicStroke(3f));
+ graphics.draw(shape);
+ graphics.dispose();
+ }
+
+
+ public static void main(String[] args) {
+ String msg="item12345678";
+ String EANmsg="012345678901";
+ String UPCmsg="12345678901";
+ String path = "D:/test/barcode/"+UUID.randomUUID()+".png";
+ generateBarCode(msg, UserConstants.QR_CODE, path);
+ }
}
diff --git a/ktg-mes/src/main/java/com/ktg/mes/wm/service/impl/WmBarcodeServiceImpl.java b/ktg-mes/src/main/java/com/ktg/mes/wm/service/impl/WmBarcodeServiceImpl.java
index 2120ba4..9841c8e 100644
--- a/ktg-mes/src/main/java/com/ktg/mes/wm/service/impl/WmBarcodeServiceImpl.java
+++ b/ktg-mes/src/main/java/com/ktg/mes/wm/service/impl/WmBarcodeServiceImpl.java
@@ -116,7 +116,8 @@ public class WmBarcodeServiceImpl implements IWmBarcodeService
@Override
public String generateBarcode(WmBarcode wmBarcode) {
- File buf = BarcodeUtil.generateFile(wmBarcode.getBarcodeContent(),"./tmp/barcode/"+wmBarcode.getBarcodeContent()+".png");
+ File buf = BarcodeUtil.generateBarCode(wmBarcode.getBarcodeContent(), wmBarcode.getBarcodeFormart(),
+ "./tmp/barcode/" + wmBarcode.getBarcodeContent() + ".png");
MultipartFile file = FileUtils.getMultipartFile(buf);
String fileName = null;
try {
@@ -124,6 +125,11 @@ public class WmBarcodeServiceImpl implements IWmBarcodeService
} catch (IOException e) {
e.printStackTrace();
return null;
+ }finally{
+ //删除掉临时文件
+ if(buf!=null && buf.exists()){
+ FileUtils.deleteFile(buf.getAbsolutePath());
+ }
}
return fileName;
}