【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

原文地址:https://www.cnblogs.com/jxd283465/p/12486489.html