• 【Java】批量生成小程序参数码并打包下载


    介绍

    微信官网小程序二维码API:https://developers.weixin.qq.com/miniprogram/dev/api/qrcode.html

    为满足不同需求和场景,这里提供了三个接口,开发者可挑选适合自己的接口。

    A接口,生成小程序码,可接受path参数较长,生成个数受限。

    B接口,生成小程序码,可接受页面参数较短,生成个数不受限。

    C接口,生成二维码,可接受path参数较长,生成个数受限。

     接口A:https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN

     

     接口B:https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN

    该接口主要用于获取二维码(不带参数)

    接口C:https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN

    注意事项

    代码

    1.获取小程序token、生成小程序二维码 工具类

    import com.alibaba.fastjson.JSONObject;
    
    import javax.servlet.http.HttpServletRequest;
    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    public class CreateQrcore {
    
        /*
         * 获取 token
         * 普通的 get 可获 token
         */
        public static String getToken() {
            try {
                Map<String, String> map = new LinkedHashMap<>();
                map.put("grant_type", "client_credential");
                map.put("appid", "appid");
                map.put("secret", "secret");
    
                String rt = UrlUtil.sendPost("https://api.weixin.qq.com/cgi-bin/token", map);
                System.out.println("what is:" + rt);
                JSONObject json = JSONObject.parseObject(rt);
    
                if (json.getString("access_token") != null || json.getString("access_token") != "") {
                    return json.getString("access_token");
                } else {
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * 生成带参小程序二维码
         *
         * @param scene       要输入的内容
         * @param accessToken token
         */
        public static void postMiniqrQr(String scene, String accessToken, String path) {
            try {
                URL url = new URL("https://api.weixin.qq.com/wxa/getwxacode?access_token=" + accessToken);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                // conn.setConnectTimeout(10000);//连接超时 单位毫秒
                // conn.setReadTimeout(2000);//读取超时 单位毫秒
                // 发送POST请求必须设置如下两行
                httpURLConnection.setDoOutput(true); // 打开写入属性
                httpURLConnection.setDoInput(true); // 打开读取属性
                httpURLConnection.setRequestMethod("POST");// 提交方式
                // 不得不说一下这个提交方式转换!!真的坑。。改了好长时间!!一定要记得加响应头
                httpURLConnection.setRequestProperty("Content-Type", "application/x-javascript; charset=UTF-8");// 设置响应头
                // 获取URLConnection对象对应的输出流
                PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
                // 发送请求参数
                JSONObject paramJson = new JSONObject();
    //            paramJson.put("scene", scene); // 你要放的内容
                paramJson.put("path", "pages/index/index?scene=" + scene);
                paramJson.put("width", 430); // 宽度
                paramJson.put("auto_color", true);
                printWriter.write(paramJson.toString());
                // flush输出流的缓冲
                printWriter.flush();
                BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());
                File file = new File(path);
                if (!file.exists()) {
                    file.mkdir();
                }
                //创建一个空文件
                OutputStream os = new FileOutputStream(new File(path + scene + ".jpg"));
                //ByteArrayOutputStream os = new ByteArrayOutputStream();
                int len;
                byte[] arr = new byte[1024];
                while ((len = bis.read(arr)) != -1) {
                    os.write(arr, 0, len);
                    os.flush();
                }
                os.close();
                // 上传云储存
                //InputStream is = new ByteArrayInputStream(os.toByteArray());
                //retMap = UploadUtils.upload(is);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /*
         * 获取 二维码图片
         *
         */
        public static String getminiqrQr(String accessToken, HttpServletRequest request, String serialNum) {
            String p = "E://code"; //二维码生产的地址  本地F盘code文件夹
            System.out.println(p);
            String codeUrl = p + "/" + serialNum + ".png";
            String twoCodeUrl = serialNum + ".png";
            try {
                URL url = new URL("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("POST");// 提交模式
                // conn.setConnectTimeout(10000);//连接超时 单位毫秒
                // conn.setReadTimeout(2000);//读取超时 单位毫秒
                // 发送POST请求必须设置如下两行
                httpURLConnection.setDoOutput(true);
                httpURLConnection.setDoInput(true);
                // 获取URLConnection对象对应的输出流
                PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
                // 发送请求参数
                JSONObject paramJson = new JSONObject();
                paramJson.put("scene", serialNum);//这就是你二维码里携带的参数 String型  名称不可变
                paramJson.put("path", "pages/index/index"); //这是设置扫描二维码后跳转的页面
                paramJson.put("width", 430);
                paramJson.put("is_hyaline", false);
                paramJson.put("auto_color", false);
    
                System.out.println("httpURLConnection" + httpURLConnection);
                System.out.println("paramJson.toString()" + paramJson.toString());
                printWriter.write(paramJson.toString());
                // flush输出流的缓冲
                printWriter.flush();
                //开始获取数据
                BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());
                OutputStream os = new FileOutputStream(new File(codeUrl));
                int len;
                byte[] arr = new byte[1024];
                while ((len = bis.read(arr)) != -1) {
                    os.write(arr, 0, len);
                    os.flush();
                }
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return codeUrl;
        }
    }

    2.添加水印工具类

    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.BufferedOutputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    
    public class WaterMarkUtils {
    
        private static BufferedImage image;
        private static int imageWidth = 430;  //图片的宽度
        private static int imageHeight = 480; //图片的高度
    
        //生成图片文件
        @SuppressWarnings("restriction")
        public static void createImage(String fileLocation) {
            BufferedOutputStream bos = null;
            if (image != null) {
                try {
                    FileOutputStream fos = new FileOutputStream(fileLocation);
                    bos = new BufferedOutputStream(fos);
    
    //                JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
    //                encoder.encode(image);
                    ImageIO.write(image, "jpg", bos);
                    bos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bos != null) {//关闭输出流
                        try {
                            bos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    
        public static void graphicsGeneration(String scene, String path) {
            int H_title = 50;     //头部高度
            int H_mainPic = 430;  //轮播广告高度
    
            image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
            //设置图片的背景色
            Graphics2D main = image.createGraphics();
            main.setColor(Color.white);
            main.fillRect(0, 0, imageWidth, imageHeight);
    
            //***********************页面头部
            Graphics title = image.createGraphics();
            //设置区域颜色
            title.setColor(new Color(255, 255, 255));
            //填充区域并确定区域大小位置
            title.fillRect(0, 0, imageWidth, H_title);
            //设置字体颜色,先设置颜色,再填充内容
            title.setColor(Color.BLACK);
            //设置字体
            Font titleFont = new Font("楷体", Font.BOLD, 40);
            title.setFont(titleFont);
            FontMetrics fm = sun.font.FontDesignMetrics.getMetrics(titleFont);
            int x = (430 - fm.stringWidth(scene)) / 2;
            title.drawString(scene, x, (H_title) / 2 + 20);
    
            //***********************插入中间广告图
            Graphics mainPic = image.getGraphics();
            BufferedImage bimg = null;
            try {
                bimg = javax.imageio.ImageIO.read(new java.io.File(path + scene + ".jpg"));
            } catch (Exception ignored) {
            }
    
            if (bimg != null) {
                mainPic.drawImage(bimg, 0, H_title, imageWidth, H_mainPic, null);
                mainPic.dispose();
            }
            createImage(path + scene + ".jpg");
    
        }
    
        public static void main(String[] args) {
            WaterMarkUtils cg = new WaterMarkUtils();
            try {
                graphicsGeneration("464646", "E:\code\test.jpg");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }

    3.打包下载工具类

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.nio.charset.Charset;
    import java.nio.file.Files;
    import java.util.ArrayList;
    import java.util.Enumeration;
    import java.util.List;
    import java.util.Objects;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;
    import java.util.zip.ZipInputStream;
    import java.util.zip.ZipOutputStream;
    
    /**
     * @author xqli7
     * @date 2019/1/23 16:14
     */
    public final class ZipUtils {
    
        private static final Logger LOG = LoggerFactory.getLogger(ZipUtils.class);
    
        private static final int BUFFER = 2048;
    
        private static final int TRANS_BUFFER = 10240;
    
        private ZipUtils() {
            throw new IllegalStateException("Utility class");
        }
    
        /**
         * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件并存放到zipFilePath路径下
         *
         * @param sourceFilePath 待压缩的文件路径
         * @param zipFilePath    压缩后存放路径
         * @param fileName       压缩后文件的名称
         * @return
         */
        public static boolean fileToZip(String sourceFilePath, String zipFilePath, String fileName) {
            boolean flag = false;
            File sourceFile = new File(sourceFilePath);
            if (!sourceFile.exists()) {
                LOG.info("待压缩的文件目录:{}不存在.", sourceFilePath);
                sourceFile.mkdir();
            }
            File zipFile = new File(zipFilePath + File.separator + fileName + ".zip");
    
            if (zipFile.exists()) {
                LOG.info("{}目录下存在名字为:{}.zip打包文件", zipFilePath, fileName);
                zipFile.delete();
            }
            File[] sourceFiles = sourceFile.listFiles();
            if (null == sourceFiles || sourceFiles.length < 1) {
                LOG.info("待压缩的文件目录:{}里面不存在文件,无需压缩.", sourceFilePath);
            } else {
                try (
                        FileOutputStream fos = new FileOutputStream(zipFile);
                        ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos))
                ) {
                    byte[] bytes = new byte[TRANS_BUFFER];
                    loopCreateZip(sourceFiles, zos, bytes);
                    flag = true;
                } catch (Exception e) {
                    LOG.error("", e);
                }
            }
            return flag;
        }
    
        /**
         * 递归删除文件、文件夹
         *
         * @param file
         */
        public static void deleteDirectory(File file) {
    
            File[] list = file.listFiles();
            int i = 0;
            if (list != null && list.length > 0) {
                for (File f : list) {
                    if (f.isDirectory()) {
                        //删除子文件夹
                        deleteDirectory(new File(f.getPath()));
                    } else {
                        //删除文件
                        f.delete();
                        i++;
                    }
                }
                //重新遍历一下文件夹内文件是否已删除干净,删除干净后则删除文件夹。
                if (Objects.requireNonNull(file.listFiles()).length <= 0) {
                    file.delete();
                }
            }
        }
    
        private static void loopCreateZip(File[] sourceFiles, ZipOutputStream zos, byte[] bytes) throws IOException {
            for (int i = 0; i < sourceFiles.length; i++) {
                // 创建ZIP实体,并添加进压缩包
                ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
                zos.putNextEntry(zipEntry);
                // 读取待压缩的文件并写进压缩包里
                try (
                        FileInputStream fis = new FileInputStream(sourceFiles[i]);
                        BufferedInputStream bis = new BufferedInputStream(fis, TRANS_BUFFER)
                ) {
                    int read = 0;
                    while ((read = bis.read(bytes, 0, TRANS_BUFFER)) != -1) {
                        zos.write(bytes, 0, read);
                    }
                } catch (IOException e) {
                    LOG.error("", e);
                }
            }
        }
    
        /**
         * 读取zip包中的文本文件以及文件内容
         *
         * @param filePath
         * @return
         * @throws IOException
         */
        public static boolean readZipFile(String filePath) {
            File sourceFile = new File(filePath);
            if (!sourceFile.exists()) {
                LOG.info("待读取的文件:{}不存在.", filePath);
                return false;
            }
            try (
                    FileInputStream fis = new FileInputStream(sourceFile);
                    ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
            ) {
                ZipEntry entry;
                while ((entry = zis.getNextEntry()) != null) {
                    LOG.info("Extracting:{} ", entry);
                    // write the files to the disk
                    write(entry, zis);
                }
            } catch (Exception e) {
                LOG.error("", e);
            }
            return true;
        }
    
        private static void write(ZipEntry entry, ZipInputStream zis) {
            int count;
            byte[] data = new byte[BUFFER];
            try (
                    BufferedOutputStream dest = new BufferedOutputStream(new FileOutputStream(entry.getName()), BUFFER)
            ) {
                while ((count = zis.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, count);
                }
                dest.flush();
            } catch (Exception e) {
                LOG.error("", e);
            }
        }
    
        /**
         * 对zip文件进行解压
         *
         * @param sourcePath 解压文件路径
         * @param targetDir  解压目标地址
         * @return
         */
        @SuppressWarnings("unchecked")
        public static List<File> unzip(String sourcePath, String targetDir) {
            List<File> files = new ArrayList<>();
            File targetDirFile = new File(targetDir);
            if (!Files.exists(targetDirFile.toPath())) {
                targetDirFile.mkdir();
            }
            File file = new File(sourcePath);
            ZipFile zipFile = null;
            try {
                zipFile = new ZipFile(file, Charset.forName("GBK"));
                ZipEntry entry;
                File entryFile;
                int bufferSize = 1024;
                byte[] buffer = new byte[bufferSize];
                Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zipFile.entries();
                while (entries.hasMoreElements()) {
                    entry = entries.nextElement();
                    if (entry.isDirectory()) {
                        return null;
                    }
                    entryFile = new File(targetDir + File.separator + entry.getName());
                    try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(entryFile));
                         BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry))
                    ) {
                        int length;
                        while ((length = bis.read(buffer, 0, bufferSize)) != -1) {
                            bos.write(buffer, 0, length);
                        }
                        bos.flush();
                        files.add(entryFile);
                    } catch (Exception e) {
                        LOG.error("文件读取出错", e);
                        return null;
                    }
                }
                return files;
            } catch (IOException e) {
                LOG.error("zip文件读取错误", e);
                return null;
            } finally {
                try {
                    if (zipFile != null) {
                        zipFile.close();
                    }
                } catch (IOException e) {
                    LOG.error("流关闭异常", e);
                }
            }
        }
    
        /**
         * @param fileName 文件名
         * @param path     文件保存路径(含文件名称)
         * @param response
         * @return
         */
        public static String downLoadZip(String tempPath, HttpServletResponse response) {
            try {
                int read = 0;
                byte[] buffer = new byte[1024];
                //创建输出流,下载zip
                OutputStream out = response.getOutputStream();
                FileInputStream in = new FileInputStream(new File(tempPath + "test.zip"));
                //设置响应头,控制浏览器下载该文件
                response.setHeader("Content-Type", "application/octet-stream");
                response.setHeader("Content-Disposition",
                        "attachment;filename=" + java.net.URLEncoder.encode("test.zip", "UTF-8"));
                while ((read = in.read(buffer)) != -1) {
                    out.write(buffer, 0, read);
                }
                out.flush();
                out.close();
                File zipFile = new File(tempPath + "/test.zip");
                if (zipFile.exists()) {
                    zipFile.delete();
                }
                File file = new File(tempPath);
                deleteDirectory(file);
            } catch (Exception e) {
                System.out.println(e);
            }
            return null;
        }
    }

    代码调用

    @PostMapping("download")
        public void download(@NotBlank(message = "{required}")
                                     String serialNums,
                             HttpServletResponse response) throws FebsException, IOException {
            try {
            //生成token String accessToken
    = CreateQrcore.getToken(); System.out.println("accessToken;" + accessToken); String[] ids = serialNums.split(StringPool.COMMA); for (String serialNum : ids) { //生成二维码 CreateQrcore.postMiniqrQr(serialNum, accessToken, tempPath); //添加图片 WaterMarkUtils.graphicsGeneration(serialNum, tempPath); } //创建压缩包 ZipUtils.fileToZip(tempPath, tempPath, "test"); //下载压缩包 ZipUtils.downLoadZip(tempPath, response); } catch (Exception e) { message = "导出二维码失败"; log.error(message, e); throw new FebsException(message); } }

    参考:https://blog.csdn.net/qq_36466653/article/details/80106903

  • 相关阅读:
    如何将程序集(dll)安装到全局程序集缓存(GAC)中
    当 ftp 遇上 http Proxy
    sql server 2008 帶主鍵table 字段 數據類型修改
    SQL 按指定顺序进行排序
    当发布时报错: 找不到 obj\Debug\Package\PackageTmp\xxx.aspx 文件
    c# 简体 繁体 转换
    SQL SERVER 简体与繁体 定序 轉換
    匿名类型与Lambda表达式
    使用委托实现了在循环中调用不同的方法
    学习源代码的心得
  • 原文地址:https://www.cnblogs.com/jxd283465/p/12486489.html
Copyright © 2020-2023  润新知