做网站怎么做多少钱,网站根目录文件名,网站开发的合同范本,行业型网站开发一#xff1a;使用场景
在最近的工作当中遇到了一个需求#xff0c;在列表导出时#xff0c;不仅需要将列表信息导出为excel文件#xff0c;同时也需要将列表每一条数据所对应的附件信息放在同一个文件夹当中#xff0c;并且压缩成一个zip响应给浏览器。首先后端需要写两…一使用场景
在最近的工作当中遇到了一个需求在列表导出时不仅需要将列表信息导出为excel文件同时也需要将列表每一条数据所对应的附件信息放在同一个文件夹当中并且压缩成一个zip响应给浏览器。首先后端需要写两个接口一个负责导出excel列表另一个负责生成zip并且响应给前端浏览器此时我们只研究生成zip的接口。
二生成zip思路分析
定义response通过for循环获取到附件的流文件生成本地临时文件并且进行压缩获取到输出的压缩流文件将其传递给response删除本地临时文件并且关闭流文件
三代码实现
3.1 Controller控制层
ApiOperation(导出附件)PostMapping(/exportAnnex)public void exportAnnex(HttpServletResponse response, RequestBody ContentManage param) {contentManageService.exportAnnex(param, response);}3.2 service层
/*** 导出附件信息** param param 查询参数* param response 响应*/void exportAnnex(ContentManage param, HttpServletResponse response);3.3 service实现类
/*** 导出附件信息** param param 查询参数* param response 响应*/OverrideAsyncpublic void exportAnnex(ContentManage param, HttpServletResponse response) {try {//筛选出文件模式的列表ListContentManage releaseModeContentManageList new ArrayList();String fileName 导出的压缩包名称;// 设置response的Headerresponse.setCharacterEncoding(UTF-8);//Content-Disposition的作用告知浏览器以何种方式显示响应返回的文件用浏览器打开还是以附件的形式下载到本地保存//attachment表示以附件方式下载 inline表示在线打开 Content-Disposition: inline; filename文件名.mp3// filename表示文件的默认名称因为网络传输只支持URL编码的相关支付因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称response.setHeader(Content-Disposition, attachment;filename fileName .zip ;filename*utf-8 URLEncoder.encode(fileName .zip, UTF-8));//设置响应格式已文件流的方式返回给前端。response.setContentType(application/octet-stream;charsetutf-8);OutputStream stream response.getOutputStream();ByteArrayOutputStream outputStream new ByteArrayOutputStream();ZipOutputStream zos new ZipOutputStream(outputStream);for (ContentManage contentManage : releaseModeContentManageList) {String filename 附件名称;String folderName 目录名称;File file new File(folderName);boolean mkdirs file.mkdirs();//此处的inputStream是获取各自业务的流文件InputStream inputStream obsClientHelper.downloadInputStream(attachmentUrl);if (inputStream null) {throw new RuntimeException(OBS文件下载失败);}File attachmentFile new File(folderName, filename);FileOutputStream fos new FileOutputStream(attachmentFile);try {byte[] buffer new byte[1024];int length 0;while (-1 ! (length inputStream.read(buffer, 0, buffer.length))) {fos.write(buffer, 0, length);}File temp new File(file.getAbsolutePath());CompressUtil.doCompressFile(temp, zos, );//要想删除文件夹下的所有内容必须关闭流inputStream.close();fos.close();//这种方式删除path下的文件时若path路径下的文件读写流没有关闭则删除不了FileUtils.deleteDirectory(file);} catch (IOException e) {log.error(附件打包压缩异常{}, e.getMessage());}}IOUtils.write(outputStream.toByteArray(), stream);zos.close();stream.flush();stream.close();} catch (Exception e) {throw new RuntimeException(压缩异常);}}
3.4 CompressUtil类
package com.byd.ghy.phylogeny.utils;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;/*** author fhey* date 2023-05-11 20:48:28* description: 压缩工具类*/
Component
Slf4j
public class CompressUtil {/*** 将文件打包到zip并创建文件** param sourceFilePath* param zipFilePath* throws IOException*/public static void createLocalCompressFile(String sourceFilePath, String zipFilePath) throws IOException {createLocalCompressFile(sourceFilePath, zipFilePath, null);}/*** 将文件打包到zip并创建文件** param sourceFilePath* param zipFilePath* param zipName* throws IOException*/public static void createLocalCompressFile(String sourceFilePath, String zipFilePath, String zipName) throws IOException {File sourceFile new File(sourceFilePath);if (!sourceFile.exists()) {throw new RuntimeException(sourceFilePath 不存在);}if (StringUtils.isBlank(zipName)) {zipName sourceFile.getName();}File zipFile createNewFile(zipFilePath File.separator zipName .zip);try (FileOutputStream fileOutputStream new FileOutputStream(zipFile)) {compressFile(sourceFile, fileOutputStream);}}/*** 获取压缩文件流** param sourceFilePath* return ByteArrayOutputStream* throws IOException*/public static OutputStream compressFile(String sourceFilePath, OutputStream outputStream) throws IOException {File sourceFile new File(sourceFilePath);if (!sourceFile.exists()) {throw new RuntimeException(sourceFilePath 不存在);}return compressFile(sourceFile, outputStream);}/*** 获取压缩文件流** param sourceFile* return ByteArrayOutputStream* throws IOException*/private static OutputStream compressFile(File sourceFile, OutputStream outputStream) throws IOException {try (CheckedOutputStream checkedOutputStream new CheckedOutputStream(outputStream, new CRC32());ZipOutputStream zipOutputStream new ZipOutputStream(checkedOutputStream)) {doCompressFile(sourceFile, zipOutputStream, StringUtils.EMPTY);return outputStream;}}/*** 处理目录下的文件** param sourceFile* param zipOutputStream* param zipFilePath* throws IOException*/public static void doCompressFile(File sourceFile, ZipOutputStream zipOutputStream, String zipFilePath) throws IOException {// 如果文件是隐藏的不进行压缩if (sourceFile.isHidden()) {return;}if (sourceFile.isDirectory()) {//如果是文件夹handDirectory(sourceFile, zipOutputStream, zipFilePath);} else {//如果是文件就添加到压缩包中try (FileInputStream fileInputStream new FileInputStream(sourceFile)) {//String fileName zipFilePath File.separator sourceFile.getName();String fileName zipFilePath sourceFile.getName();addCompressFile(fileInputStream, fileName, zipOutputStream);//String fileName zipFilePath.replace(\\, /) / sourceFile.getName();//addCompressFile(fileInputStream, fileName, zipOutputStream);}}}/*** 处理文件夹** param dir 文件夹* param zipOut 压缩包输出流* param zipFilePath 压缩包中的文件夹路径* throws IOException*/private static void handDirectory(File dir, ZipOutputStream zipOut, String zipFilePath) throws IOException {File[] files dir.listFiles();if (ArrayUtils.isEmpty(files)) {ZipEntry zipEntry new ZipEntry(zipFilePath dir.getName() File.separator);zipOut.putNextEntry(zipEntry);zipOut.closeEntry();return;}for (File file : files) {doCompressFile(file, zipOut, zipFilePath dir.getName() File.separator);}}/*** 获取压缩文件流** param documentList 需要压缩的文件集合* return ByteArrayOutputStream*//*public static OutputStream compressFile(ListFileInfo documentList, OutputStream outputStream) {MapString, ListFileInfo documentMap new HashMap();documentMap.put(, documentList);return compressFile(documentMap, outputStream);}*//*** 将文件打包到zip** param documentMap 需要下载的附件集合 map的key对应zip里的文件夹名* return ByteArrayOutputStream*//*public static OutputStream compressFile(MapString, ListFileInfo documentMap, OutputStream outputStream) {CheckedOutputStream checkedOutputStream new CheckedOutputStream(outputStream, new CRC32());ZipOutputStream zipOutputStream new ZipOutputStream(checkedOutputStream);try {for (Map.EntryString, ListFileInfo documentListEntry : documentMap.entrySet()) {String dirName documentMap.size() 1 ? documentListEntry.getKey() : ;MapString, Integer fileNameToLen new HashMap();//记录单个合同号文件夹下每个文件名称出现的次数对重复文件名重命名for (FileInfo document : documentListEntry.getValue()) {try {//防止单个文件夹下文件名重复 对重复的文件进行重命名String documentName document.getFileName();if (fileNameToLen.get(documentName) null) {fileNameToLen.put(documentName, 1);} else {int fileLen fileNameToLen.get(documentName) 1;fileNameToLen.put(documentName, fileLen);documentName documentName ( fileLen );}String fileName documentName . document.getSuffix();if (StringUtils.isNotBlank(dirName)) {fileName dirName File.separator fileName;}addCompressFile(document.getFileInputStream(), fileName, zipOutputStream);} catch (Exception e) {logger.info(filesToZip exception :, e);}}}} catch (Exception e) {logger.error(filesToZip exception: e.getMessage(), e);}return outputStream;}*//*** 将单个文件写入文件压缩包** param inputStream 文件输入流* param fileName 文件在压缩包中的相对全路径* param zipOutputStream 压缩包输出流*/private static void addCompressFile(InputStream inputStream, String fileName, ZipOutputStream zipOutputStream) {try (BufferedInputStream bufferedInputStream new BufferedInputStream(inputStream)) {ZipEntry zipEntry new ZipEntry(fileName);zipOutputStream.putNextEntry(zipEntry);byte[] bytes new byte[1024];int length;while ((length bufferedInputStream.read(bytes)) 0) {zipOutputStream.write(bytes, 0, length);zipOutputStream.flush();}zipOutputStream.closeEntry();//System.out.println(map size, value is RamUsageEstimator.sizeOf(zipOutputStream));} catch (Exception e) {log.info(addFileToZip exception:, e);throw new RuntimeException(e);}}/*** 通过网络请求下载zip** param sourceFilePath 需要压缩的文件路径* param response HttpServletResponse* param zipName 压缩包名称* throws IOException*/public static void httpDownloadCompressFile(String sourceFilePath, HttpServletResponse response, String zipName) throws IOException {File sourceFile new File(sourceFilePath);if (!sourceFile.exists()) {throw new RuntimeException(sourceFilePath 不存在);}if (StringUtils.isBlank(zipName)) {zipName sourceFile.getName();}try (ServletOutputStream servletOutputStream response.getOutputStream()) {CompressUtil.compressFile(sourceFile, servletOutputStream);response.setContentType(application/zip);response.setHeader(Content-Disposition, attachment; filename\ zipName .zip\);servletOutputStream.flush();}}public static void httpDownloadCompressFileOld(String sourceFilePath, HttpServletResponse response, String zipName) throws IOException {try (ServletOutputStream servletOutputStream response.getOutputStream()) {ByteArrayOutputStream byteArrayOutputStream new ByteArrayOutputStream();byte[] zipBytes byteArrayOutputStream.toByteArray();response.setContentType(application/zip);response.setHeader(Content-Disposition, attachment; filename\ zipName .zip\);response.setContentLength(zipBytes.length);servletOutputStream.write(zipBytes);servletOutputStream.flush();}}/*** 通过网络请求下载zip** param sourceFilePath 需要压缩的文件路径* param response HttpServletResponse* throws IOException*/public static void httpDownloadCompressFile(String sourceFilePath, HttpServletResponse response) throws IOException {httpDownloadCompressFile(sourceFilePath, response, null);}/*** 检查文件名是否已经存在如果存在就在文件名后面加上“(1)”如果文件名“(1)”也存在则改为“(2)”以此类推。如果文件名不存在就直接创建一个新文件。** param filename 文件名* return File*/public static File createNewFile(String filename) {File file new File(filename);if (!file.exists()) {try {file.createNewFile();} catch (IOException e) {e.printStackTrace();}} else {String base filename.substring(0, filename.lastIndexOf(.));String ext filename.substring(filename.lastIndexOf(.));int i 1;while (true) {String newFilename base ( i ) ext;file new File(newFilename);if (!file.exists()) {try {file.createNewFile();} catch (IOException e) {e.printStackTrace();}break;}i;}}return file;}}