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

Java導(dǎo)出多個(gè)excel表打包到zip文件中供客戶端另存為窗口下載實(shí)現(xiàn)方法

 更新時(shí)間:2023年12月08日 14:59:04   作者:劉大貓.  
最近的項(xiàng)目有一個(gè)導(dǎo)出匯總數(shù)據(jù)的要求,考慮到用戶軟件的差異,所以要分別導(dǎo)出xls以及xlsx并且打包提供下載,下面這篇文章主要給大家介紹了關(guān)于Java導(dǎo)出多個(gè)excel表打包到zip文件中供客戶端另存為窗口下載的實(shí)現(xiàn)方法,需要的朋友可以參考下

一、業(yè)務(wù)背景

業(yè)務(wù)需求:從數(shù)據(jù)庫(kù)查詢多個(gè)list集合信息封裝excel,每個(gè)excel都有2個(gè)sheet頁(yè),填充不同的信息,最后將所有excel打包成zip文件,以流的形式返回給客戶端,供客戶端另存為窗口下載。

  • 只發(fā)出一次請(qǐng)求
  • 每個(gè)excel表中到數(shù)據(jù)記錄不能超過(guò)2條
  • excel文件或者zip包不會(huì)上傳服務(wù)器,而是查詢后直接封裝excel,然后把多個(gè)excel封裝成zip包直接返回

之前看過(guò)其他人的方案大概有2種:

  • 方案1:打包成zip包后上傳到服務(wù)器某個(gè)路徑下,然后在讀取該路徑的zip文件,以流的形式返回給客戶端。
  • 方案2:不上傳服務(wù)器,而是查詢后直接封裝excel,然后把多個(gè)excel封裝成zip包直接返回。(本人采用的就是第二種方案)

最終的效果,如圖

二、實(shí)現(xiàn)思路

  • 設(shè)置HttpServletResponse的參數(shù),比如header、contentType
  • 新建一個(gè)Workbook對(duì)象并置為空,同時(shí)初始化相關(guān)對(duì)象,比如List、File等
  • 從數(shù)據(jù)庫(kù)查詢多條list
  • 以其中為主的一個(gè)list計(jì)算分頁(yè)數(shù)量
  • 循環(huán)遍歷list開(kāi)始
  • 初始化新的Workbook對(duì)象,并設(shè)置相應(yīng)的Title
  • 將list拆分成多個(gè)段,分別寫到的Workbook對(duì)象中
  • 將Workbook對(duì)象填充到List<XSSFWorkbook>中
  • 重復(fù)步驟6至步驟8直至寫完所有數(shù)據(jù)
  • 最后統(tǒng)一封裝zip壓縮包并導(dǎo)出,調(diào)用downFileByStream方法
  • 初始化ZipOutputStream對(duì)象
  • 循環(huán)遍歷List<XSSFWorkbook>將每一個(gè)wb寫入ZipOutputStream對(duì)象中,并將內(nèi)存流寫入Zip文件,即:將每一個(gè)excel封裝到zip包中
  • 關(guān)閉ZipOutputStream

二、準(zhǔn)備工作

1.準(zhǔn)備data模板.xlsx

2.引入poi相關(guān)依賴,用于操作excel

pom.xml

<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
</dependency>

3.針對(duì)WorkBook+ZIP壓縮輸入/輸出流,相關(guān)方法知識(shí)點(diǎn)要有所了解

Apache POI包中的HSSFWorkbook、XSSFWorkbook、SXSSFWorkbook的區(qū)別如下:

ZipOutputStream類的常用方法如下表所示:

方法返回值說(shuō)明
putNextEntry(ZipEntry e)void開(kāi)始寫一個(gè)新的ZipEntry,并將流內(nèi)的位置移至此entry所指數(shù)據(jù)的開(kāi)頭
write(byte[] b, int off, int len)void將字節(jié)數(shù)組寫入當(dāng)前ZIP條目數(shù)據(jù)
finish()void完成寫入ZIP輸出流的內(nèi)容,無(wú)須關(guān)閉它所配合的OutputStream
setComment(String comment)void可設(shè)置此ZIP文件的注釋文字

ZipInputStream類的常用方法如下表所示:

方法返回值說(shuō)明
read(byte[] b, int off, int len)int讀取目標(biāo)b數(shù)組內(nèi)off偏移量的位置,長(zhǎng)度是len字節(jié)
available()int判斷是否已讀完目前entry所指定的數(shù)據(jù)。已讀完返回0,否則返回1
closeEntry()void關(guān)閉當(dāng)前ZIP條目并定位流以讀取下一個(gè)條目
skip(long n)long跳過(guò)當(dāng)前ZIP條目中指定的字節(jié)數(shù)
getNextEntry()ZipEntry讀取下一個(gè)ZipEntry,并將流內(nèi)的位置移至該entry所指數(shù)據(jù)的開(kāi)頭
createZipEntry(String name)ZipEntry以指定的name參數(shù)新建一個(gè)ZipEntry對(duì)象

Workbook類提供的方法

方法返回值說(shuō)明
getNumberOfSheets()int獲得工作?。╓orkbook)中工作表(Sheet)的個(gè)數(shù)
getSheets()Sheet[]返回工作?。╓orkbook)中工作表(Sheet)對(duì)象數(shù)組
getVersion()String返回正在使用的API的版本號(hào),好像是沒(méi)什么太大的作用。
getName()String獲取Sheet的名稱
getColumns()int獲取Sheet表中所包含的總列數(shù)
getColumn(int column)Cell[]獲取某一列的所有單元格,返回的是單元格對(duì)象數(shù)組
getRows()int獲取Sheet表中所包含的總行數(shù)
getRow(int row)Cell[]獲取某一行的所有單元格,返回的是單元格對(duì)象數(shù)組
getCell(int column, int row)Cell獲取指定單元格的對(duì)象引用,需要注意的是它的兩個(gè)參數(shù),第一個(gè)是列數(shù),第二個(gè)是行數(shù),這與通常的行、列組合有些不同。
write()寫入Exel工作表
close()關(guān)閉Excel工作薄對(duì)象
getPhysicalNumberOfCells()int獲取該行的總列數(shù)
getSheetAt(int index)Sheet根據(jù)索引index獲取對(duì)應(yīng)的sheet頁(yè)
getBodyStyle(Workbook wb)CellStyle設(shè)置excel中比如第一行Title樣式
setCellStyle(CellStyle var1)void跟getBodyStyle()方法搭配設(shè)置樣式
setCellValue(String var1)void設(shè)置值
getStringCellValue()String獲取對(duì)應(yīng)列的值

三、完整的項(xiàng)目代碼

ExportUtil工具類

package com.excel.utils;

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 導(dǎo)出【用戶、組、隸屬關(guān)系】工具
 * @Author 211145187
 * @Date 2023/4/13 16:29
 **/
public class ExportUtil {
    private static Logger logger = LoggerFactory.getLogger(ExportUtil.class);

    /**
     * 自定義獲取分頁(yè)總頁(yè)數(shù)的方法
     * @param count 查詢集合數(shù)量
     * @param pageSize 配置文件中設(shè)置的單文件存儲(chǔ)最大條數(shù)
     * @return 總頁(yè)數(shù)
     */
    public static Integer getPageCount(Integer count, Integer pageSize){
        Integer pageCount = 0;
        if(count.equals(0)){
            return pageCount;
        }
        pageCount = count/pageSize;
        if(count % pageSize != 0){
            pageCount++;
        }

        return pageCount;
    }

    /**
     * 自定義List分頁(yè)工具
     * @param list 待分頁(yè)的list數(shù)據(jù)
     * @param pageNum 頁(yè)碼
     * @param pageSize 頁(yè)容量
     * @param pageCount 總頁(yè)數(shù)
     * @return 分頁(yè)后的list數(shù)據(jù)
     */
    public static <T> List<T> getPageList(List<T> list, Integer pageNum, Integer pageSize, Integer pageCount){

        /**開(kāi)始索引*/
        int beginIndex = 0;
        /**結(jié)束索引*/
        int endIndex = 0;

        Integer compare = pageNum.compareTo(pageCount);
        if(!compare.equals(0)){
            beginIndex = (pageNum - 1) * pageSize;
            endIndex = beginIndex + pageSize;
        }else{
            beginIndex = (pageNum - 1) * pageSize;
            endIndex = list.size();
        }
        List pageList = list.subList(beginIndex, endIndex);

        return pageList;
    }

    /**
     * HSSFWorkbook轉(zhuǎn)file
     * @param wb wb
     * @param name 文件名稱
     * @return File
     */
    public static File xssfWorkbookToFile(Workbook wb, String name) {
        File toFile = new File(name);
        try {
            OutputStream os = new FileOutputStream(toFile);
            wb.write(os);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return toFile;
    }


    /**
     * 直接下載zip包
     * @param response response
     * @param excels wb集合
     */
    public static void downFileByStream(HttpServletResponse response, List<XSSFWorkbook> excels){
        try {
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            ZipOutputStream zipOutputStream = new ZipOutputStream(toClient);
            for(int i=0; i<excels.size(); i++){
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                // 將Workbook寫入內(nèi)存流
                excels.get(i).write(baos);
                ZipEntry zipEntry = new ZipEntry("data" + i + ".xlsx");
                zipOutputStream.putNextEntry(zipEntry);
                // 將內(nèi)存流寫入Zip文件
                zipOutputStream.write(baos.toByteArray());
            }
            zipOutputStream.closeEntry();
            zipOutputStream.flush();
            zipOutputStream.close();
        }catch (Exception e){
            logger.error("downFileByStream==========fail:{}", e.getMessage());
        }
    }
}

application.properties

server.port=8001
#導(dǎo)出excel配置,單文件存儲(chǔ)最大數(shù)量
export.num=2

OperateExcelController

package com.excel.controller;

import com.excel.bean.Score;
import com.excel.bean.Teacher;
import com.excel.utils.ExportUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 測(cè)試3.17版本操作Excel
 * @Author 211145187
 * @Date 2022/2/22 19:43
 **/
@RequestMapping("/excel")
@Controller
public class OperateExcelController {
	private static Logger logger = LoggerFactory.getLogger(OperateExcelController.class);
    @Value("${export.num:10000}")
    private Integer exportLimitNum;

    //構(gòu)建教師集合數(shù)據(jù)
    public List<Teacher> buildTeacherList1() {
        List<Teacher> teacherList = new ArrayList<>();
        Teacher teacher1 = new Teacher();
        teacher1.setName("周杰倫");
        teacher1.setClasses("三年二班");
        teacher1.setCollege("魔法學(xué)院");
        teacher1.setAlias("Jay Chou");
        teacherList.add(teacher1);
        Teacher teacher2 = new Teacher();
        teacher2.setName("陳奕迅");
        teacher2.setClasses("三年二班");
        teacher2.setCollege("魔法學(xué)院");
        teacher2.setAlias("Eason");
        teacherList.add(teacher2);
        Teacher teacher3 = new Teacher();
        teacher3.setName("林俊杰");
        teacher3.setClasses("三年二班");
        teacher3.setCollege("魔法學(xué)院");
        teacher3.setAlias("Eason");
        teacherList.add(teacher3);
        Teacher teacher4 = new Teacher();
        teacher4.setName("張杰");
        teacher4.setClasses("三年二班");
        teacher4.setCollege("魔法學(xué)院");
        teacher4.setAlias("Eason");
        teacherList.add(teacher4);
        return teacherList;
    }
    //構(gòu)建分?jǐn)?shù)集合數(shù)據(jù)
    public List<Score> buildScoreList1() {
        List<Score> scoreList = new ArrayList<>();
        Score score1 = new Score();
        score1.setName("流川楓");
        score1.setClasses("三年二班");
        score1.setWriteScore("6");
        score1.setComputerScore("4");
        scoreList.add(score1);
        Score score2 = new Score();
        score2.setName("櫻木花道");
        score2.setClasses("三年二班");
        score2.setWriteScore("6");
        score2.setComputerScore("4");
        scoreList.add(score2);
        Score score3 = new Score();
        score3.setName("大猩猩");
        score3.setClasses("三年二班");
        score3.setWriteScore("6");
        score3.setComputerScore("4");
        scoreList.add(score3);
        Score score4 = new Score();
        score4.setName("三井");
        score4.setClasses("三年二班");
        score4.setWriteScore("6");
        score4.setComputerScore("4");
        scoreList.add(score4);
        return scoreList;
    }

    //方法5:java導(dǎo)出多個(gè)Excel為zip包
    @RequestMapping("/exportMultipleExcelToZip")
    public void exportMultipleExcelToZip(HttpServletResponse response) throws IOException {
        response.setHeader("Content-disposition", "attachment; filename=" + "test.zip");
        response.setContentType("application/zip; charset=utf-8");

        //創(chuàng)建HSSFWorkbook對(duì)象(excel的文檔對(duì)象)
        XSSFWorkbook wb = null;
        List<Teacher> teacherList = new ArrayList<>();
        //構(gòu)建sheet頁(yè)集合
        List<Score> scoreList = new ArrayList<>();
        File templateFile = new File("C:\\Users\\211145187\\Desktop\\data模板.xlsx");

        //.....省略部分代碼
        List<Teacher> buildTeacherList = buildTeacherList1();
        List<Score> buildScoreList = buildScoreList1();

        Integer pageLimitSize = exportLimitNum;
        //計(jì)算list的分頁(yè)數(shù)量
        Integer pageCount = ExportUtil.getPageCount(buildTeacherList.size(), pageLimitSize);
        List<XSSFWorkbook> excels = new ArrayList<>();
        try {
            for(Integer pageNum = 1; pageNum < pageCount + 1; pageNum++) {
                //注意:每次循環(huán)遍歷前都需要初始化新的wb對(duì)象
                //注意情況1:如果是初始化wb空對(duì)象然后手動(dòng)添加title,下方三行代碼不會(huì)報(bào)錯(cuò)
//                wb = new XSSFWorkbook();
//                buildScoreSheetTitle(wb);
//                buildTeacherSheetTitle(wb);

                //注意情況2:如果是初始化wb對(duì)象,并且以流的形式初始化,那么io流必須放在里面才行,如果放在for循環(huán)外面會(huì)報(bào)“Stream Closed”錯(cuò)誤
                InputStream io = new FileInputStream(templateFile);
                wb = new XSSFWorkbook(io);
                teacherList = ExportUtil.getPageList(buildTeacherList, pageNum, pageLimitSize, pageCount);
                scoreList = ExportUtil.getPageList(buildScoreList, pageNum, pageLimitSize, pageCount);
                buildScoreSheetParams(wb, scoreList);
                buildTeacherSheetParams(wb, teacherList);
                excels.add(wb);
            }
            //最后統(tǒng)一封裝zip壓縮包并導(dǎo)出
            ExportUtil.downFileByStream(response, excels);
        } catch (Exception e) {
            logger.error("IOException:", e);
        }
    }

    /**
     * 填充教師頁(yè)信息
     * @param wb wb
     * @param bodyData bodyData
     */
    private void buildTeacherSheetParams(Workbook wb, List<Teacher> bodyData){
        int teacherColumnCount = wb.getSheetAt(1).getRow(0).getPhysicalNumberOfCells();
        Sheet sheet = wb.getSheetAt(1);
        // build data
        for(int j=0; j<bodyData.size(); j++){
            Teacher itm = bodyData.get(j);
            Row rowData = sheet.createRow(j+1);
            for(int k=0;k<teacherColumnCount; k++){
                Cell cell = rowData.createCell(k);
                cell.setCellValue(getValueByTeacher(k, itm));
            }
        }
    }
    private String getValueByTeacher(int columnIndex,Teacher itm){
        String cellValue;
        switch (columnIndex){
            case 0:cellValue = itm.getName(); break;
            case 1:cellValue = itm.getClasses()+""; break;
            case 2:cellValue = itm.getCollege(); break;
            case 3:cellValue = itm.getAlias(); break;
            default:cellValue=""; break;
        }
        return cellValue;
    }
    /**
     * 填充分?jǐn)?shù)頁(yè)信息
     * @param wb wb
     * @param bodyData bodyData
     */
    private void buildScoreSheetParams(Workbook wb, List<Score> bodyData){
        int scoreColumnCount = wb.getSheetAt(0).getRow(0).getPhysicalNumberOfCells();
        Sheet sheet = wb.getSheetAt(0);
        // build data
        for(int j=0; j<bodyData.size(); j++){
            Score itm = bodyData.get(j);
            Row rowData = sheet.createRow(j+1);
            for(int k=0;k<scoreColumnCount; k++){
                Cell cell = rowData.createCell(k);
                cell.setCellValue(getValueByScore(k, itm));
            }
        }
    }
    private String getValueByScore(int columnIndex,Score itm){
        String cellValue;
        switch (columnIndex){
            case 0:cellValue = itm.getName(); break;
            case 1:cellValue = itm.getClasses()+""; break;
            case 2:cellValue = itm.getWriteScore(); break;
            case 3:cellValue = itm.getComputerScore(); break;
            default:cellValue=""; break;
        }
        return cellValue;
    }

    /**
     * 構(gòu)建分?jǐn)?shù)表excel的標(biāo)頭
     * @Author 211145187
     * @Date 2022/2/22 20:20
     * @Param wb wb
     **/
    private void buildScoreSheetTitle(XSSFWorkbook wb) {
        //建立新的sheet對(duì)象(excel的表單)
        XSSFSheet sheet=wb.createSheet("成績(jī)表");
        XSSFRow row=sheet.createRow(0);
        //創(chuàng)建單元格并設(shè)置單元格內(nèi)容
        XSSFCell cell0 = row.createCell(0);
        cell0.setCellValue("姓名");
        cell0.setCellStyle(getHeadStyle(wb));
        XSSFCell cell1 = row.createCell(1);
        cell1.setCellValue("班級(jí)");
        cell1.setCellStyle(getHeadStyle(wb));
        XSSFCell cell2 = row.createCell(2);
        cell2.setCellValue("筆試成績(jī)");
        cell2.setCellStyle(getHeadStyle(wb));
        XSSFCell cell3 = row.createCell(3);
        cell3.setCellValue("機(jī)試成績(jī)");
        cell3.setCellStyle(getHeadStyle(wb));
    }
    /**
     * 構(gòu)建教師表excel的標(biāo)頭
     * @Author 211145187
     * @Date 2022/2/22 20:20
     * @Param wb wb
     **/
    private void buildTeacherSheetTitle(XSSFWorkbook wb) {
        //建立新的sheet對(duì)象(excel的表單)
        XSSFSheet sheet=wb.createSheet("教師表");
        XSSFRow row=sheet.createRow(0);
        //創(chuàng)建單元格并設(shè)置單元格內(nèi)容
        XSSFCell cell0 = row.createCell(0);
        cell0.setCellValue("姓名");
        cell0.setCellStyle(getHeadStyle(wb));
        XSSFCell cell1 = row.createCell(1);
        cell1.setCellValue("班級(jí)");
        cell1.setCellStyle(getHeadStyle(wb));
        XSSFCell cell2 = row.createCell(2);
        cell2.setCellValue("所屬學(xué)院");
        cell2.setCellStyle(getHeadStyle(wb));
        XSSFCell cell3 = row.createCell(3);
        cell3.setCellValue("別名");
        cell3.setCellStyle(getHeadStyle(wb));
    }

    /**
     * 設(shè)置樣式
     * @Author 211145187
     * @Date 2022/2/22 20:15
     * @Param wb wb
     * @Return CellStyle
     **/
    private CellStyle getHeadStyle(Workbook wb) {
        CellStyle cellStyle = wb.createCellStyle();
        //用于設(shè)置前景顏色
        cellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
        /**
         * setFillPattern用于設(shè)置單元格填充樣式
         * 注意:
         *      1)setFillPattern必須設(shè)置否則光設(shè)置setFillForegroundColor無(wú)效
         *      2)3.10.1版本支持short類型參數(shù),而3.17版本支持FillPatternType類型參數(shù)
         */
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        return cellStyle;
    }
}

四、可能遇到的問(wèn)題

錯(cuò)誤場(chǎng)景1:java.io.IOException: Stream closed

原因分析:

我這里導(dǎo)致流關(guān)閉會(huì)有2種場(chǎng)景觸發(fā):場(chǎng)景1:工具類方法downFileByStream()中的for循環(huán)執(zhí)行write()方法。
場(chǎng)景2:wb = new XSSFWorkbook(io);通過(guò)IO流初始化wb對(duì)象時(shí)。

解決方案:

針對(duì)場(chǎng)景1中的解決方案就是:Workbook的write()方法最終會(huì)關(guān)閉它寫入的輸出流。如果只是一次性全部輸出那就不會(huì)碰到這種問(wèn)題,但是現(xiàn)在的場(chǎng)景是工具類方法downFileByStream()中的for循環(huán)執(zhí)行write()方法,所以解決方案就是用一個(gè)ByteArrayOutputStream去接收存儲(chǔ)當(dāng)前Workbook的內(nèi)容,這樣哪怕Workbook關(guān)閉了,但是內(nèi)容已經(jīng)提前存入了ByteArrayOutputStream中,只要讀取了就可以繼續(xù)使用。因此才有這樣的如下寫法:

/**
     * 直接下載zip包
     * @param response response
     * @param excels wb集合
     */
    public static void downFileByStream(HttpServletResponse response, List<XSSFWorkbook> excels){
        try {
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            ZipOutputStream zipOutputStream = new ZipOutputStream(toClient);
            for(int i=0; i<excels.size(); i++){
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                // 將Workbook寫入內(nèi)存流
                excels.get(i).write(baos);
                ZipEntry zipEntry = new ZipEntry("data" + i + ".xlsx");
                zipOutputStream.putNextEntry(zipEntry);
                // 將內(nèi)存流寫入Zip文件
                zipOutputStream.write(baos.toByteArray());
            }
            zipOutputStream.closeEntry();
            zipOutputStream.flush();
            zipOutputStream.close();
        }catch (Exception e){
            logger.error("downFileByStream==========fail:{}", e.getMessage());
        }
    }

針對(duì)場(chǎng)景2中的解決方案就是:把IO流初始化提到for循環(huán)里面,如實(shí)有了如下寫法:

for(Integer pageNum = 1; pageNum < pageCount + 1; pageNum++) {
                //注意:每次循環(huán)遍歷前都需要初始化新的wb對(duì)象
                //注意情況1:如果是初始化wb空對(duì)象然后手動(dòng)添加title,下方三行代碼不會(huì)報(bào)錯(cuò)
//                wb = new XSSFWorkbook();
//                buildScoreSheetTitle(wb);
//                buildTeacherSheetTitle(wb);

                //注意情況2:如果是初始化wb對(duì)象,并且以流的形式初始化,那么io流必須放在里面才行,如果放在for循環(huán)外面會(huì)報(bào)“Stream Closed”錯(cuò)誤
                InputStream io = new FileInputStream(templateFile);
                wb = new XSSFWorkbook(io);
                ...
            }

錯(cuò)誤場(chǎng)景2:調(diào)用接口沒(méi)有另存為彈窗,但是F12查看接口結(jié)果返回一堆亂碼

錯(cuò)誤原因分析:可能是返回結(jié)果HttpServletResponse設(shè)置的setContentType格式不對(duì)。

正確的應(yīng)該設(shè)置為如下,一定要設(shè)置為application/zip:

response.setHeader("Content-disposition", "attachment; filename=" + "test.zip");
response.setContentType("application/zip; charset=utf-8");

總結(jié) 

到此這篇關(guān)于Java導(dǎo)出多個(gè)excel表打包到zip文件中供客戶端另存為窗口下載實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java導(dǎo)出多excel表打包到zip文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論