前言
? ?在實際項目中,我們可能會接到將文件或者資料打包壓縮導出的需求,例如將系統中某些生成的文件一起打包壓縮下載提供給客戶使用,今天提供一個jdk自帶的工具類快速實現打包壓縮的功能,方法我已經封裝好,大家如果在項目中遇到類似需求可以直接復制過去使用
一、思路和步驟
??首先將我們在系統上生成的文件或者服務器上現有的文件讀取到輸出流中,然后傳給zip壓縮流實現壓縮并響應到瀏覽器下載
具體步驟:
1、將文件轉換為流
2、將生成好的文件流數據和文件名(壓縮包內一個文件對應一個文件名)封裝
3、將數據添加到壓縮流中進行壓縮
4、響應到瀏覽器下載
5、關閉流
二、工具類封裝
??下面是一個工具類封裝和具體實現
1、封裝一個數據實體
import lombok.AllArgsConstructor;
import lombok.Data;/*** @Author: 你住過的屋檐* @Date: 2025/2/26 下午5:34* @aphorism You are lucky to have someone to help you.No one to help you, is just fate.No one should do anything for you, because life is your own, you are responsible for yourself*/
@Data
@AllArgsConstructor
public class FileData {/*** 文件名*/private String fileName;/*** 文件流字節數組*/private byte[] fileByte;
}
2、工具類
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;/*** @Author: 你住過的屋檐* @Date: 2025/2/26 下午4:01* @aphorism You are lucky to have someone to help you.No one to help you, is just fate.No one should do anything for you, because life is your own, you are responsible for yourself*/
public class ZipUtils {/*** 壓縮文件并下載* @param zipName 壓縮包名稱* @param fileDataList 壓縮數據流* @param response 響應對象* @throws IOException*/public static void downLoadZip(String zipName, List<FileData> fileDataList, HttpServletResponse response) throws IOException {if(fileDataList==null||fileDataList.isEmpty()){throw new IOException("數據為空");}ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream();ZipOutputStream zos = new ZipOutputStream(zipOutputStream);for (FileData fileData : fileDataList) {// 添加文件到 ZIP件中addFileToZip(zos, fileData.getFileName(), fileData.getFileByte());}// finish()方法用于完成當前 ZIP 文件的寫入。它會寫入 ZIP 文件的結束記錄,確保 ZIP 文件的完整性zos.finish();//關閉 ZipOutputStream,釋放資源zos.close();// 創建輸入流資源ByteArrayInputStream in = new ByteArrayInputStream(zipOutputStream.toByteArray());// 設置響應頭,通知瀏覽器下載response.setContentType("application/force-download");String fileName= URLEncoder.encode(zipName,"utf-8");response.setHeader("Content-disposition", "attachment; filename="+fileName );response.setContentLength(in.available());OutputStream out = response.getOutputStream();byte[] b= new byte[1024];int len;while((len=in.read(b))!=-1){out.write(b,0,len);}//用于強制將緩沖區中的數據立即寫入到目標輸出流中,避免數據丟失。out.flush();//關閉輸出流并釋放資源out.close();//關閉輸入流并釋放資源in.close();}/*** 添加文件到 ZIP 文件中* @param zipOut* @param fileName 文件名* @param content 添加內容* @throws IOException*/private static void addFileToZip(ZipOutputStream zipOut, String fileName, byte[] content) throws IOException {ZipEntry zipEntry = new ZipEntry(fileName);zipOut.putNextEntry(zipEntry);zipOut.write(content);zipOut.closeEntry();}
}
三、實現效果
下面是演示效果
1、在D盤創建了一個文檔,寫一個hello world!
2、寫一個調用接口
import com.customs.broker.utils.zip.FileData;
import com.customs.broker.utils.zip.ZipUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;@RestController
public class TestController {@GetMapping("/download")public void downLoadZip(HttpServletResponse response){try {File file = new File("D:\\測試文檔.txt");//轉換為輸入流FileInputStream fis = new FileInputStream(file);ByteArrayOutputStream outputStream = new ByteArrayOutputStream();//讀取文件到輸出流中byte[] buffer = new byte[1024];int len;while ((len = fis.read(buffer)) != -1) {outputStream.write(buffer, 0, len);}List<FileData> fileDataList = new ArrayList<>();//將文件流和文件名封裝進實體FileData fileData = new FileData("測試文檔.txt", outputStream.toByteArray());//添加fileDataList.add(fileData);//執行壓縮打包下載ZipUtils.downLoadZip("test.zip",fileDataList,response);} catch (IOException e) {e.printStackTrace();}}}
3、啟動項目后瀏覽器執行調用接口
http://127.0.0.1:8080/download
直接生成了壓縮包并且下載到了瀏覽器
打包壓縮包已經將hello world!的文檔壓縮進壓縮包
為了幫助更多像你一樣的讀者,我將持續在專欄中分享技術干貨和實用技巧。如果你覺得這篇文章對你有幫助,可以考慮關注我的專欄,謝謝。