【示例】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();
            }
        }
    }
相关推荐
LightOfNight11 分钟前
【后端面试题】【中间件】【NoSQL】MongoDB的配置服务器、复制机制、写入语义和面试准备
分布式·后端·mongodb·中间件·面试·架构·nosql
java6666688881 小时前
Spring Boot中的数据加密与解密
java·spring boot·后端
OceanBase数据库官方博客1 小时前
OceanBase v4.2 特性解析:对Json与Xml的扩展支持
xml·json·oceanbase·分布式数据库·产品特性
喜欢猪猪2 小时前
springboot的双亲委派
java·spring boot·后端
VX_DZbishe4 小时前
springboot旅游管理系统-计算机毕业设计源码16021
java·spring boot·python·servlet·django·flask·php
嗨!陌生人5 小时前
SpringSecurity中文文档(Servlet Session Management)
java·hadoop·spring boot·后端·spring cloud·servlet
G皮T10 小时前
【Spring Boot】Java 的数据库连接模板:JDBCTemplate
java·数据库·spring boot·jdbc·jdbctemplate
weixin_4404016910 小时前
黑马苍穹外卖7 用户下单+订单支付(微信小程序支付流程图)
java·spring boot·微信小程序·mybatis
randy.lou10 小时前
SpringBoot: Eureka入门
spring boot·后端·eureka
碎像10 小时前
使用AI工具 Baidu Comate 辅助编码 快速定位修改Bug
java·前端·后端·bug·intellij idea