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

FileController

@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

  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

 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

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();}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/36103.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里巴巴找黄金宝箱(IV)

系列文章目录 本人最近再练习算法&#xff0c;所以会发布自己的解题思路&#xff0c;希望大家多指教 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、java代码五、测试用例 前言 一、题目描述 贫如洗的椎夫阿里巴巴在去砍柴的路上&#xff0c;无意中发现…

一款专为网页开发者设计的高效工具,它简化了响应式网站的开发流程

大家好&#xff0c;今天给大家分享的是一款专为web开发人员和测试人员设计的工具&#xff0c;它通过改进的web浏览器功能&#xff0c;帮助用户进行响应式web开发和兼容性测试。 主要功能 所有设备上的镜像用户交互&#xff1a;允许开发人员在单一设备上进行操作&#xff0c;实时…

Python高精度浮点运算库之mpmath使用详解

概要 在科学计算和工程应用中,精确的数学计算至关重要。Python 作为一种灵活而强大的编程语言,提供了多种数学库,其中 mpmath 库因其高精度浮点运算和丰富的数学函数支持而备受关注。mpmath 库不仅适用于基本的高精度计算,还支持复数运算、矩阵运算和特殊函数计算,广泛应…

使用微信开发者工具创建运行项目全流程

小程序基础知识 1. 认识什么是小程序 什么是微信小程序 微信小程序是一种运行在微信内部的 轻量级 应用程序。 在使用小程序时 不需要下载安装&#xff0c;用户 扫一扫 或 搜一下 即可打开应用。它也体现了 “用完即走” 的理念&#xff0c;用户不用关心安装太多应用的问题…

SyntaxError: Unexpected token ‘<‘ (at chunk-vendors.fb93d34e.js:1:1)打包后页面白屏vue

本地运行一切正常&#xff0c;打包到线上&#xff0c;页面一篇空白。我确定输入路径正确。。。 控制台报错&#xff0c;我就开始百度&#xff0c;有的说清空缓存就行了&#xff0c;但我清空了还是这样。。。 然后我就去排查原因。看到页面请求js&#xff0c;但是请求的好像有点…

技术市集 | 如何通过WSL 2在Windows上挂载Linux磁盘?

你是否常常苦恼&#xff0c;为了传输或者共享不同系统的文件需要频繁地在 Windows 和 Linux 系统之间切换&#xff0c;既耽误工作效率&#xff0c;也容易出错。 那么有没有一种办法&#xff0c;能够让你在Windows系统中像访问本地硬盘一样来操作Linux系统中的文件呢&#xff1…

2024肥晨赠书活动第三期:《前端工程化:基于Vue.js 3.0的设计与实践》

文章目录 内容简介作者简介关于《前端工程化&#xff1a;基于Vue.js 3.0的设计与实践》文章目录文章简介《前端工程化&#xff1a;基于Vue.js 3.0的设计与实践》全书速览结束语 内容简介 本书以Vue.js的3.0版本为核心技术栈&#xff0c;围绕“前端工程化”和TypeScript的知识点…

简单的springboot整合activiti5.22.0

简单的springboot整合activiti5.22.0 1. 需求 我们公司原本的流程服务是本地workflow模块以及一个远程的webService对应的activiti服务&#xff0c;其中activiti版本为5.22.0&#xff0c;之前想将activiiti5.22.0进行升级&#xff0c;选择了camunda&#xff0c;也对项目进行了…

数据处理:数据转译、取小数点后三位

发现一个好用的写法&#xff1a; 一、英转中 <div class"text" v-if"kaBuLe">卡布叻星星&#xff1a;{{ getChinese(kaBuLeType) }} </div>const pageData: {[propName: string]: any } reactive({kaBuLeType:, }) //对应中文 function get…

ArcGIS Pro SDK (七)编辑 3 地图拓扑

ArcGIS Pro SDK &#xff08;七&#xff09;编辑 3 地图拓扑 目录 ArcGIS Pro SDK &#xff08;七&#xff09;编辑 3 地图拓扑1 构建地图拓扑 环境&#xff1a;Visual Studio 2022 .NET6 ArcGIS Pro SDK 3.0 1 构建地图拓扑 private async Task BuildGraphWithActiveView()…

Hive 和 Hive 的 JDBC 区别

Hive 和 Hive 的 JDBC 主要有以下区别&#xff1a; 1. Hive&#xff1a; Hive 是一个基于 Hadoop 的数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供了类似 SQL 的查询语言 HiveQL 来查询数据。 HiveQL 支持类似于 SQL 的语法&#xff0c…

1、加密算法-MD5随机盐

一、说明 MD5消息摘要算法&#xff0c;属Hash算法一类。MD5算法对输入任意长度的消息进行运行&#xff0c;产生一个128位的消息摘要(32位的数字字母混合码)。 二、主要特点 不可逆&#xff0c;相同数据的MD5值肯定一样&#xff0c;不同数据的MD5值不一样 (一个MD5理论上的确…

torch_scatter::scatter_max 转onnx再转tensorrt踩坑记录

torch_scatter::scatter_max转onnx onnx转tensorRT 方法选择 自定义算子。在TensorRT中实现NonZero&#xff0c;该过程非常复杂&#xff0c;参考&#xff1a;https://blog.csdn.net/weixin_45878768/article/details/128149343

小程序开发平台源码系统——内容付费(知识付费)小程序功能 带完整的安装代码包以及搭建部署教程

系统概述 随着互联网的发展&#xff0c;人们对于知识和信息的获取需求日益增长。内容付费小程序应运而生&#xff0c;为用户提供了一个便捷、高效的知识交易平台。小程序开发平台源码系统则为开发者提供了构建内容付费小程序的基础和工具&#xff0c;使其能够快速打造具有个性化…

十年磨一剑,华火电燃组合灶重磅问世,引领厨房新时代

十年磨一剑&#xff0c;华火研发团队经过不懈努力&#xff0c;成功将等离子电生明火技术与电陶炉红外线光波炉技术精妙融合&#xff0c;打造出的这款具有划时代是意义的电燃组合灶HH-SZQP60&#xff0c;终于在 2024 年6月震撼登场&#xff0c;该灶以其卓越的创新技术和独特的产…

VAE-pytorch代码

import osimport torch import torch.nn as nn import torch.nn.functional as F from torch.utils.data import DataLoaderfrom torchvision import transforms, datasets from torchvision.utils import save_imagefrom tqdm import tqdmclass VAE(nn.Module): # 定义VAE模型…

增值电信业务经营许可证详解

最近有很多人问小编&#xff0c;什么是增值电信业务经营许可证?可能大家对这个名词还很陌生&#xff0c;不着急&#xff01;今天小编就给大家好好讲讲这个证到底是什么?为什么需要办这个这个证&#xff1f;它可以给企业带来什么&#xff1f; 带着疑问我们继续往下看。 什么…

一步步带你解锁Stable Diffusion:老外都眼馋的 SD 中文提示词插件分享

大家好我是极客菌&#xff01;今天我们继续来分享一个外国人都眼馋的 SD 中文提示词插件。 那我们废话不多说&#xff0c;直接开整。 SD 的插件安装&#xff0c;小伙伴们应该都会了吧&#xff0c;我这里再简单讲下哦&#xff0c;到「扩展」中的「可下载」中点击「加载扩展列表…

LangChain资料总结

1、LangChain介绍 - 莫尔索随笔 2、LangChain 介绍 | LangChain中文网:500页中文文档教程&#xff0c;助力大模型LLM应用开发从入门到精通 3、&#x1f308; Spring AI 语雀 4、AI全栈「AGI」 专栏 语雀 5、GitHub - langchain4j/langchain4j: Java version of LangChain…

国标GB/T 28181详解:国标GBT28181-2022的目录通知流程

目录 一、定义 二、作用 1、实时同步设备目录状态 2、优化资源管理和调度 3、增强系统的可扩展性和灵活性 4、提高系统的可靠性和稳定性 5、支持多级级联和分布式部署 6、便于用户管理和监控 三、基本要求 1、目录通知满足以下基本要求 2、关键要素 &#xff08;1…