欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java將文件壓縮成zip并下載

 更新時間:2025年04月09日 09:39:33   作者:頗有幾分姿色  
這篇文章主要為大家詳細介紹了Java如何將文件壓縮成zip和下載,并處理base64和url,文中的示例代碼講解詳細,感興趣的小伙伴可以參考一下

Java文件壓縮成zip并下載

使用jdk自帶的zip包下的類來實現(xiàn)壓縮

1.實體類

實體類主要是文件名和文件路徑(base64字符串),壓縮文件路徑時可以不使用類里的文件名。

import lombok.Data;

@Data
public class FileInfoDto {
    /**文件名*/
    private String fileName;

    **文件路徑或base64字符串*/
    private String file;
}

2.工具類

創(chuàng)建和刪除文件的方式來輔助壓縮,在創(chuàng)建一個zip文件時,每個zipEntry代表zip文件中的一個項,zipEntry的名稱在zip文件內(nèi)必須是唯一的,因為zip文件格式使用這些條目名稱作為查找鍵,來定位和提取存儲在zip中的文件。所以名稱相同時會拋出異常,我這里在調(diào)用前做了處理。

我省略了項目路徑的import,使用時導入自己的路徑即可。

import org.springframework.core.io.ClassPathResource;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author xxx
 * @date 2023/10/18 14:43
 * @description:
 */
public class BaseZipUtils {
    /**
     * 使用給定的文件列表創(chuàng)建ZIP文件并將其發(fā)送到HTTP響應。
     *
     * @param response HttpServletResponse
     * @param fileList 文件列表
     * @param title    ZIP文件的標題
     * @param type  1-base64壓縮,2-url-壓縮
     */
    public static void downZipFile(HttpServletResponse response, List<FileInfoDto> fileList, String title, Integer type) {
        // 獲取模板路徑,并構建ZIP文件的完整路徑。
        String tempDirPath = getTemplatePath();
        File zipFilePath = new File(tempDirPath, LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "_" + title);

        try {
            if (1 == type) {
                // 基于Base64編碼的文件創(chuàng)建ZIP文件。
                zipFiles(fileList, zipFilePath);
            } else {
                zipFilesFromURLs(fileList, zipFilePath);
            }

            // 如果ZIP文件存在,將其發(fā)送到HTTP響應。
            if (zipFilePath.exists()) {
                try (InputStream is = new FileInputStream(zipFilePath);
                     OutputStream os = response.getOutputStream()) {

                    response.setContentType("application/octet-stream");
                    response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(zipFilePath.getName(), "UTF-8"));

                    // 從ZIP文件讀取內(nèi)容并寫入HTTP響應。
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = is.read(buffer)) != -1) {
                        os.write(buffer, 0, bytesRead);
                    }
                } finally {
                    // 刪除臨時ZIP文件。
                    Files.deleteIfExists(zipFilePath.toPath());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 將Base64編碼的文件列表壓縮為一個ZIP文件。
     *
     * @param srcFiles 需要壓縮的文件列表
     * @param zipFile  生成的ZIP文件
     */
    public static void zipFiles(List<FileInfoDto> srcFiles, File zipFile) throws IOException {
        // 如果ZIP文件不存在,創(chuàng)建它。
        if (!zipFile.exists()) {
            Files.createFile(zipFile.toPath());
        }

        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) {
            for (FileInfoDto fileInfo : srcFiles) {
                // 解碼文件名。
                String fileName = URLDecoder.decode(fileInfo.getFileName(), "UTF-8");

                // 創(chuàng)建ZIP條目并添加到ZIP輸出流中。
                ZipEntry entry = new ZipEntry(fileName);
                zos.putNextEntry(entry);

                // 將Base64編碼的文件內(nèi)容解碼為字節(jié)數(shù)組。
                byte[] fileBytes = Base64.getDecoder().decode(fileInfo.getFile());

                // 將字節(jié)數(shù)組寫入ZIP文件。
                zos.write(fileBytes);
                zos.closeEntry();
            }
        }
    }

    /**
     * 使用從URL獲取的文件列表創(chuàng)建ZIP文件。
     *
     * @param srcFilesURLs 需要壓縮的文件URL列表
     * @param zipFile      生成的ZIP文件
     */
    public static void zipFilesFromURLs(List<FileInfoDto> srcFilesURLs, File zipFile) throws IOException {
        // 如果ZIP文件不存在,創(chuàng)建它。
        if (!zipFile.exists()) {
            Files.createFile(zipFile.toPath());
        }

        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) {
            for (FileInfoDto dto : srcFilesURLs) {
                URL url = new URL(dto.getFile());

                // 獲取文件的文件名。
                String fileName = Paths.get(url.getPath()).getFileName().toString();

                // 創(chuàng)建ZIP條目并添加到ZIP輸出流中。
                ZipEntry entry = new ZipEntry(fileName);
                zos.putNextEntry(entry);

                // 從URL讀取文件內(nèi)容。
                try (InputStream is = url.openStream()) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = is.read(buffer)) != -1) {
                        // 將從URL讀取的內(nèi)容寫入ZIP文件。
                        zos.write(buffer, 0, bytesRead);
                    }
                }
                zos.closeEntry();
            }
        }
    }

    /**
     * 獲取類路徑的絕對地址。
     *
     * @return 類路徑的絕對地址
     */
    public static String getTemplatePath() {
        try {
            String realPath = new ClassPathResource("").getURL().getPath();
            return URLDecoder.decode(realPath, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

3.js接收blob

/**
 * 處理Blob響應并觸發(fā)瀏覽器下載。
 * @param {Object} res - 包含頭信息和數(shù)據(jù)的響應對象。
 * @param {string} [name] - 下載文件的可選名稱。
 * @param {string} [type2] - Blob的可選類型。
 */
export const handleBlob = (res, name, type2) => {
  // 從提供的名稱或響應頭中獲取文件名
  const fileName = name || (res.headers['content-disposition'] && 
                            decodeURI(res.headers['content-disposition'])
                            .split('filename=')[1]);

  // 從提供的type2或響應頭中獲取類型
  const type = type2 || res.headers['content-type'];

  // 創(chuàng)建Blob對象
  const blob = new Blob([res.data], { type });

  // 觸發(fā)瀏覽器下載
  const downloadElement = document.createElement('a');
  downloadElement.href = window.URL.createObjectURL(blob);
  downloadElement.download = fileName; // 設置下載文件的名稱
  document.body.appendChild(downloadElement);
  downloadElement.click();
  document.body.removeChild(downloadElement);
}

4.調(diào)用

String title = "測試.zip";
BaseZipUtils.downZipFile(response, fileList, title,1);

調(diào)用結果:

Java中多目錄文件壓縮成zip

將多個文件打包到zip提供給用戶下載,抽離出來了一個工具類,支持單文件、多文件、按類型的多文件的壓縮和下載。

1.實體類

import lombok.Data;

import java.io.Serializable;
import java.util.List;

/**
 * @date 2022/5/25 15:11
 * @description:
 */
@Data
public class ZipDto implements Serializable {

    /**類型名稱/子目錄名稱*/
    private String typeName;

    /**文件路徑*/
    private String fileUrl;

    /**
     * 分類型時,集合有值
     * 文件路徑集合
     */
    private List<String> urlList;
}

2.工具類

主要方法:

  • downZipListType: 允許用戶按類型將文件列表打包成zip文件進行下載。
  • downZipList: 提供批量下載功能,可以將多個文件一起打包成zip文件。
  • downZipOne: 為單個文件提供下載功能,雖然是單個文件,但為了保持統(tǒng)一性,仍然會將其打包成zip格式。

刪除了項目敏感import,自行導入實體即可。

import cn.hutool.core.util.StrUtil;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @date 2023/10/18 17:32
 * @description:
 */
@Slf4j
@UtilityClass
public class CustomOriZipUtils {

    private static final String SUFFIX_ZIP = ".zip";
    private static final String UNNAMED = "未命名";

    /**
     * 按類型批量下載。
     */
    public static void downZipListType(List<ZipDto> list, String fileName, HttpServletRequest request, HttpServletResponse response) {
        try (ZipOutputStream zos = createZipOutputStream(response, request, fileName)) {
            for (ZipDto dto : list) {
                writeToZipStream(dto.getUrlList(), zos, dto.getTypeName());
            }
        } catch (Exception e) {
            log.error("創(chuàng)建zip文件出錯", e);
        }
    }

    /**
     * 批量下載。
     */
    public static void downZipList(List<ZipDto> list, String fileName, HttpServletRequest request, HttpServletResponse response) {
        try (ZipOutputStream zos = createZipOutputStream(response, request,fileName)) {
            for (ZipDto dto : list) {
                writeToZipStream(Collections.singletonList(dto.getFileUrl()), zos, dto.getTypeName());
            }
        } catch (Exception e) {
            log.error("創(chuàng)建zip文件出錯", e);
        }
    }

    /**
     * 下載單個記錄。
     */
    public void downZipOne(ZipDto dto, String fileName, HttpServletRequest request, HttpServletResponse response) {
        try (ZipOutputStream zos = createZipOutputStream(response, request,fileName)) {
            writeToZipStream(Collections.singletonList(dto.getFileUrl()), zos, dto.getTypeName());
        } catch (Exception e) {
            log.error("創(chuàng)建zip文件出錯", e);
        }
    }

    /**
     * 為下載設置響應。
     */
    private void setResponse(HttpServletResponse response, HttpServletRequest request,String fileName) throws UnsupportedEncodingException {
        if (StrUtil.isAllBlank(fileName)) {
            fileName = LocalDate.now() + UNNAMED;
        }
        if (!fileName.endsWith(SUFFIX_ZIP)) {
            fileName += SUFFIX_ZIP;
        }
        fileName = encodeFileName(request, fileName);
        response.setHeader("Connection", "close");
        response.setHeader("Content-Type", "application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
    }

    /**
     * 將URL寫入zip流中。
     */
    private static void writeToZipStream(List<String> urls, ZipOutputStream zos, String subDir)  {
        byte[] buffer = new byte[1024];
        for (String url : urls) {
            if (StrUtil.isNotBlank(url)) {
                try (InputStream is = new URL(url).openStream()) {
                    String fileName = StrUtil.isAllBlank(subDir) ? getFileName(url) : subDir + "/" + getFileName(url);
                    zos.putNextEntry(new ZipEntry(fileName));
                    int length;
                    while ((length = is.read(buffer)) > 0) {
                        zos.write(buffer, 0, length);
                    }
                    zos.closeEntry();
                } catch (Exception e) {
                    log.error("將文件 [{}] 寫入zip時出錯", url, e);
                }
            }
        }
    }

    /**
     * 根據(jù)瀏覽器類型編碼文件名。
     */
    private static String encodeFileName(HttpServletRequest request, String fileName) throws UnsupportedEncodingException {
        String userAgent = request.getHeader("USER-AGENT");
        if (userAgent.contains("Firefox")) {
            return new String(fileName.getBytes(), "ISO8859-1");
        }
        return URLEncoder.encode(fileName, "UTF-8");
    }

    /**
     * 創(chuàng)建ZipOutputStream并設置響應頭。
     */
    private static ZipOutputStream createZipOutputStream(HttpServletResponse response,HttpServletRequest request, String fileName) throws IOException {
        setResponse(response, request,fileName);
        return new ZipOutputStream(response.getOutputStream());
    }

    /**
     * 從url獲取文件名
     * @param url
     * @return
     */
    public String getFileName(String url) {
        return url.substring(url.lastIndexOf('/') + 1);
    }

3.效果

多目錄文件壓縮下載:

單文件打包下載:

到此這篇關于Java將文件壓縮成zip并下載的文章就介紹到這了,更多相關Java文件壓縮內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java實現(xiàn)雙鏈表的示例代碼

    Java實現(xiàn)雙鏈表的示例代碼

    雙向鏈表也叫雙鏈表,是鏈表的一種,它的每個數(shù)據(jù)結點中都有兩個指針,分別指向直接后繼和直接前驅。本文將用Java語言實現(xiàn)雙鏈表,需要的可以參考一下
    2022-09-09
  • Java并發(fā)包之CopyOnWriteArrayList類的深入講解

    Java并發(fā)包之CopyOnWriteArrayList類的深入講解

    這篇文章主要給大家介紹了關于Java并發(fā)包之CopyOnWriteArrayList類的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • java中Collections.sort排序詳解

    java中Collections.sort排序詳解

    這篇文章主要介紹了java中Collections.sort排序詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • 一步步教你搭建Scala開發(fā)環(huán)境(非常詳細!)

    一步步教你搭建Scala開發(fā)環(huán)境(非常詳細!)

    Scala是一門基于jvm的函數(shù)式的面向對象編程語言,擁有比java更加簡潔的語法,下面這篇文章主要給大家介紹了關于搭建Scala開發(fā)環(huán)境的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • spring-data-jpa中findOne與getOne的區(qū)別說明

    spring-data-jpa中findOne與getOne的區(qū)別說明

    這篇文章主要介紹了spring-data-jpa中findOne與getOne的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java字符串數(shù)字左右補全0的四種方式

    Java字符串數(shù)字左右補全0的四種方式

    這篇文章主要給大家介紹了關于Java字符串數(shù)字左右補全0的四種方式,在編程中有時候我們需要對一個字符串進行字符填充,以滿足某些特定的要求,其中補全0是一種常見的需求,需要的朋友可以參考下
    2023-08-08
  • Spring Boot構建框架詳解

    Spring Boot構建框架詳解

    這篇文章主要為大家詳細介紹了Spring Boot構建框架的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • SpringBoot集成Swagger3的實現(xiàn)

    SpringBoot集成Swagger3的實現(xiàn)

    本文主要介紹了SpringBoot集成Swagger3的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Java實現(xiàn)較大二進制文件的讀、寫方法

    Java實現(xiàn)較大二進制文件的讀、寫方法

    本篇文章主要介紹了Java實現(xiàn)較大二進制文件的讀、寫方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • 微信公眾號測試賬號自定義菜單的實例代碼

    微信公眾號測試賬號自定義菜單的實例代碼

    這篇文章主要介紹了微信公眾號測試賬號自定義菜單的實例代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02

最新評論