【示例】springboot实现json文件生成,压缩为zip文件并在浏览器下载

FileController

java 复制代码
@GetMapping("/tea/downloadFormula")
public ResponseEntity<byte[]> downloadFormula(){
	logger.info("下载茶类配方, {}", JSONObject.toJSONString(req));
    List<String> macList = req.getMacList();
    // 创建临时文件根目录
    File tempFileDirectory = new File(gemiFilePath);
    if (!tempFileDirectory.exists()) {
        tempFileDirectory.mkdirs();
    }
    logger.info("临时文件目录路径: {}", tempFileDirectory.getAbsolutePath());
    String filePath, fileName, outputFileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
    List<GemiTeaFormulaVO> formulaVOList;
    Map<Integer, List<GemiTeaFormulaVO>> formulaMap;
    Integer teaId;
    String teaCategory, imageUrl;
    List<GemiTeaFormulaVO> tempListByFormulaName;
    for (String mac : macList) {
        filePath = mac;
        fileName = mac + ".json";
        logger.info("filePath:{} fileName:{}", filePath, fileName);
        // 一个设备下可能有多个配方
        formulaVOList = gemiTeaFormulaDao.getTeaFormulaByMac(mac);
        if (formulaVOList == null || formulaVOList.size() == 0) {
            logger.info("没有查到配方");
            continue;
        }
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject;
        GemiTea gemiTea;
        int teaCategoryNum = 1;
        // 根据茶类分组
        formulaMap = groupByFormulaName(formulaVOList);
        for (Map.Entry<Integer, List<GemiTeaFormulaVO>> entry : formulaMap.entrySet()) {
            teaId = entry.getKey();
            gemiTea = gemiTeaDao.getById(teaId);
            if(gemiTea == null) {
                continue;
            }
            teaCategory = gemiTea.getTeaCategory();
            imageUrl = gemiTea.getImageUrl();
            logger.info("teaCategory:{} imageUrl:{}", teaCategory, imageUrl);
            tempListByFormulaName = entry.getValue();
            jsonObject = new JSONObject();
            jsonObject.put("id", teaId + "_" + teaCategoryNum);
            jsonObject.put("name", gemiTea.getTeaCategory());
            jsonObject.put("total", tempListByFormulaName.size());
            JSONArray formulaArray = new JSONArray();
            JSONObject formulaObject;
            Integer formulaId;
            List<GemiTeaFormulaDetail> gemiTeaFormulaDetailList;
            for (GemiTeaFormulaVO formulaVO: tempListByFormulaName) {
                formulaId = formulaVO.getId();
                formulaObject = new JSONObject();
                formulaObject.put("id", formulaId);
                formulaObject.put("name", formulaVO.getFormulaName());
                // 配方总阶段数
                gemiTeaFormulaDetailList = gemiTeaFormulaDetailDao.getByFormulaId(formulaId);
                if(gemiTeaFormulaDetailList == null || gemiTeaFormulaDetailList.size() == 0) {
                    gemiTeaFormulaDetailList = new ArrayList<>();
                }
                JSONArray formulaDetailArray = new JSONArray();
                JSONObject formulaDetailObject;
                for (GemiTeaFormulaDetail formulaDetail: gemiTeaFormulaDetailList ) {
                    formulaDetailObject = new JSONObject();
                    formulaDetailObject.put("id", formulaDetail.getCurrentStage());
                    formulaDetailObject.put("waterOutput", formulaDetail.getWaterOutput());
                    formulaDetailObject.put("waterOutletTemp", formulaDetail.getWaterOutletTemp());
                    formulaDetailObject.put("mixMethod", formulaDetail.getMixMethod());
                    formulaDetailObject.put("frothingTime", formulaDetail.getFrothingTime());
                    formulaDetailObject.put("nextStage", formulaDetail.getNextStage());
                    formulaDetailArray.add(formulaDetailObject);
                }
                formulaObject.put("total", formulaDetailArray.size());
                formulaObject.put("subsection", formulaDetailArray);
                formulaArray.add(formulaObject);
            }
            jsonObject.put("formula", formulaArray);
            jsonArray.add(jsonObject);
            teaCategoryNum++;
            logger.info("mac:{} 开始生成图片文件", mac);
            ImageTool.downloadImage(imageUrl, filePath,mac + "_" + teaCategory + ".png");
        }
        logger.info("json:{}", jsonArray.toJSONString());
        logger.info("mac:{} 开始生成json文件", mac);
        GemiFileUtil.createJsonFile(filePath, fileName, jsonArray.toJSONString());
    }
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ZipTool.createZipFile(tempFileDirectory, baos);
    // 删除目录
    GemiFileUtil.deleteDirectory(tempFileDirectory);
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Disposition", "attachment; filename=" + outputFileName + ".zip");
    return ResponseEntity.ok()
            .headers(headers)
            .contentLength(baos.size())
            .body(baos.toByteArray());
}

FileUtil

java 复制代码
  private static final String fileTemp= "/fileTemp";

    public static File createJsonFile(String filePath, String fileName, String jsonString) {
        // 创建文件目录
        File tempFileDirectory = new File(fileTemp+ "/" + filePath);
        if (!tempFileDirectory.exists()) {
            tempFileDirectory.mkdirs();
        }
        logger.info("生成文件路径:" + (fileTemp+ "/" + filePath + "/" + fileName));
        File jsonFile = new File(fileTemp+ "/" + filePath + "/" + fileName);
        try (FileWriter fileWriter = new FileWriter(jsonFile)) {
            fileWriter.write(jsonString);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jsonFile;
    }

    public static void deleteDirectory(File directory) {
        if (directory.exists()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        // 递归删除子目录
                        deleteDirectory(file);
                    } else {
                        // 删除文件
                        file.delete();
                    }
                }
            }
            // 最后删除目录本身
            directory.delete();
        }
    }

ImageTool

java 复制代码
 private static final String filePath = "/filePath";

    public static void downloadImage(String imageUrl, String filePath, String fileName) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet;
        try {
            logger.info("imageUrl:{}", imageUrl);
            if(StringUtils.isEmpty(imageUrl)){
                logger.info("图片地址为空");
                return;
            }
            httpGet = new HttpGet(imageUrl);
            CloseableHttpResponse response = httpClient.execute(httpGet);
            File tempFileDirectory = new File(filePath + "/" + filePath);
            if (!tempFileDirectory.exists()) {
                tempFileDirectory.mkdirs();
            }
            logger.info("path:" + tempFileDirectory.getAbsolutePath());
            logger.info("生成文件路径:" + (filePath + "/" + filePath + "/" + fileName));
            FileOutputStream fos = new FileOutputStream(filePath + "/" + filePath + "/" + fileName);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                // 将图片内容写入文件
                entity.writeTo(fos);
                logger.info("Image downloaded successfully!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

ZipTool

java 复制代码
    public static void zipFiles(File directory, String baseName, ZipArchiveOutputStream zos) throws IOException {
        File[] files = directory.listFiles();
        if (files == null) {
            return; // 可能是目录不存在或没有读取权限
        }

        for (File file : files) {
            Path filePath = file.toPath();
            String entryName = baseName.isEmpty() ? filePath.getFileName().toString() : baseName + "/" + filePath.getFileName().toString();

            if (Files.isDirectory(filePath)) {
                // 递归处理子目录
                ZipArchiveEntry dirEntry = new ZipArchiveEntry(entryName + "/"); // 注意添加斜杠以表示目录
                zos.putArchiveEntry(dirEntry);
                zos.closeArchiveEntry();
                zipFiles(file, entryName, zos);
                continue;
            }

            // 处理文件
            ZipArchiveEntry fileEntry = new ZipArchiveEntry(entryName);
            zos.putArchiveEntry(fileEntry);

            try (InputStream fis = Files.newInputStream(filePath)) {
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }
            }
            zos.closeArchiveEntry();
        }
    }

    // 示例方法,用于创建ZIP文件并调用zipFiles方法
    public static void createZipFile(File directory, ByteArrayOutputStream byteArrayOutputStream) {
        ZipArchiveOutputStream zos = null;
        try {
            zos = new ZipArchiveOutputStream(byteArrayOutputStream);
            // 假设我们不想在ZIP中包含根目录本身
            zipFiles(directory, "", zos);
        } catch (IOException e){
            e.printStackTrace();
        } finally {
            try {
                if (zos != null) {
                    zos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
相关推荐
Albert Edison3 小时前
【最新版】IntelliJ IDEA 2025 创建 SpringBoot 项目
java·spring boot·intellij-idea
Piper蛋窝4 小时前
深入 Go 语言垃圾回收:从原理到内建类型 Slice、Map 的陷阱以及为何需要 strings.Builder
后端·go
六毛的毛6 小时前
Springboot开发常见注解一览
java·spring boot·后端
AntBlack7 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
31535669137 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端
uzong7 小时前
curl案例讲解
后端
开开心心就好8 小时前
免费PDF处理软件,支持多种操作
运维·服务器·前端·spring boot·智能手机·pdf·电脑
一只叫煤球的猫8 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端
猴哥源码8 小时前
基于Java+SpringBoot的农事管理系统
java·spring boot
大鸡腿同学9 小时前
身弱武修法:玄之又玄,奇妙之门
后端