Selaa lähdekoodia

添加后台生成二维码common/utils/QRCodeUtils

luobo 4 vuotta sitten
vanhempi
commit
de1f3f5473

+ 6 - 0
ruoyi-common/pom.xml

@@ -166,6 +166,12 @@
             <groupId>com.belerweb</groupId>
             <artifactId>pinyin4j</artifactId>
         </dependency>
+        <!--二维码-->
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+            <version>3.3.0</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 223 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/QRCodeUtils.java

@@ -0,0 +1,223 @@
+package com.ruoyi.common.utils;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import com.ruoyi.common.utils.file.FileUtils;
+import com.ruoyi.common.utils.uuid.IdUtils;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Hashtable;
+
+public class QRCodeUtils {
+
+        private static final String CHARSET = "utf-8";
+        public static final String FORMAT = "png";
+        // 二维码尺寸
+        private static final int QRCODE_SIZE = 300;
+        // LOGO宽度
+        private static final int LOGO_WIDTH = 60;
+        // LOGO高度
+        private static final int LOGO_HEIGHT = 60;
+
+        /**
+         * 生成二维码
+         *
+         * @param content      二维码内容
+         * @param logoPath     logo地址
+         * @param needCompress 是否压缩logo
+         * @return 图片
+         * @throws Exception
+         */
+        public static BufferedImage createImage(String content, String logoPath, boolean needCompress) throws Exception {
+            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
+            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
+            hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
+            hints.put(EncodeHintType.MARGIN, 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 x = 0; x < width; x++) {
+                for (int y = 0; y < height; y++) {
+                    image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
+                }
+            }
+            if (logoPath == null || "".equals(logoPath)) {
+                return image;
+            }
+            // 插入图片
+            QRCodeUtils.insertImage(image, logoPath, needCompress);
+            return image;
+        }
+
+        /**
+         * 插入LOGO
+         *
+         * @param source       二维码图片
+         * @param logoPath     LOGO图片地址
+         * @param needCompress 是否压缩
+         * @throws IOException
+         */
+        private static void insertImage(BufferedImage source, String logoPath, boolean needCompress) throws IOException {
+            InputStream inputStream = null;
+            try {
+                inputStream = FileUtils.getResourceAsStream(logoPath);
+                Image src = ImageIO.read(inputStream);
+                int width = src.getWidth(null);
+                int height = src.getHeight(null);
+                if (needCompress) { // 压缩LOGO
+                    if (width > LOGO_WIDTH) {
+                        width = LOGO_WIDTH;
+                    }
+                    if (height > LOGO_HEIGHT) {
+                        height = LOGO_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();
+            } catch (IOException e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            } finally {
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            }
+        }
+
+        /**
+         * 生成二维码(内嵌LOGO)
+         * 二维码文件名随机,文件名可能会有重复
+         *
+         * @param content      内容
+         * @param logoPath     LOGO地址
+         * @param destPath     存放目录
+         * @param needCompress 是否压缩LOGO
+         * @throws Exception
+         */
+        public static String encode(String content, String logoPath, String destPath, boolean needCompress) throws Exception {
+            BufferedImage image = QRCodeUtils.createImage(content, logoPath, needCompress);
+            mkdirs(destPath);
+            String fileName = IdUtils.fastSimpleUUID()+ "." + FORMAT.toLowerCase();
+            ImageIO.write(image, FORMAT, new File(destPath + "/" + fileName));
+            return fileName;
+        }
+
+        /**
+         * 生成二维码(内嵌LOGO)
+         * 调用者指定二维码文件名
+         *
+         * @param content      内容
+         * @param logoPath     LOGO地址
+         * @param destPath     存放目录
+         * @param fileName     二维码文件名
+         * @param needCompress 是否压缩LOGO
+         * @throws Exception
+         */
+        public static String encode(String content, String logoPath, String destPath, String fileName, boolean needCompress) throws Exception {
+            BufferedImage image = QRCodeUtils.createImage(content, logoPath, needCompress);
+            mkdirs(destPath);
+            fileName = fileName.substring(0, fileName.indexOf(".") > 0 ? fileName.indexOf(".") : fileName.length())
+                    + "." + FORMAT.toLowerCase();
+            ImageIO.write(image, FORMAT, new File(destPath + "/" + fileName));
+            return fileName;
+        }
+
+        /**
+         * 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.
+         * (mkdir如果父目录不存在则会抛出异常)
+         *
+         * @param destPath 存放目录
+         */
+        public static void mkdirs(String destPath) {
+            File file = new File(destPath);
+            if (!file.exists() && !file.isDirectory()) {
+                file.mkdirs();
+            }
+        }
+
+        /**
+         * 生成二维码(内嵌LOGO)
+         *
+         * @param content  内容
+         * @param logoPath LOGO地址
+         * @param destPath 存储地址
+         * @throws Exception
+         */
+        public static String encode(String content, String logoPath, String destPath) throws Exception {
+            return QRCodeUtils.encode(content, logoPath, destPath, false);
+        }
+
+        /**
+         * 生成二维码
+         *
+         * @param content      内容
+         * @param destPath     存储地址
+         * @param needCompress 是否压缩LOGO
+         * @throws Exception
+         */
+        public static String encode(String content, String destPath, boolean needCompress) throws Exception {
+            return QRCodeUtils.encode(content, null, destPath, needCompress);
+        }
+
+        /**
+         * 生成二维码
+         *
+         * @param content  内容
+         * @param destPath 存储地址
+         * @throws Exception
+         */
+        public static String encode(String content, String destPath) throws Exception {
+            return QRCodeUtils.encode(content, null, destPath, false);
+        }
+
+        /**
+         * 生成二维码(内嵌LOGO)
+         *
+         * @param content      内容
+         * @param logoPath     LOGO地址
+         * @param output       输出流
+         * @param needCompress 是否压缩LOGO
+         * @throws Exception
+         */
+        public static void encode(String content, String logoPath, OutputStream output, boolean needCompress)
+                throws Exception {
+            BufferedImage image = QRCodeUtils.createImage(content, logoPath, needCompress);
+            ImageIO.write(image, FORMAT, output);
+        }
+
+        /**
+         * 生成二维码
+         *
+         * @param content 内容
+         * @param output  输出流
+         * @throws Exception
+         */
+        public static void encode(String content, OutputStream output) throws Exception {
+            QRCodeUtils.encode(content, null, output, false);
+        }
+    }

+ 10 - 6
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java

@@ -1,11 +1,6 @@
 package com.ruoyi.common.utils.file;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
 import java.net.URLEncoder;
 import javax.servlet.http.HttpServletRequest;
 
@@ -139,4 +134,13 @@ public class FileUtils extends org.apache.commons.io.FileUtils
         }
         return filename;
     }
+    /**
+     * 获取指定文件的输入流
+     *
+     * @param logoPath 文件的路径
+     * @return
+     */
+    public static InputStream getResourceAsStream(String logoPath) {
+        return FileUtils.class.getResourceAsStream(logoPath);
+    }
 }