POI导出Excel,每个Excel中有多个sheet 通过Zip导出多个Excel的压缩文件。

POI导出Excel,每个Excel中有多个sheet
通过Zip导出多个Excel的压缩文件。

假如项目部署到服务器上,就无法直接下载到本地桌面,需要先下载到服务器的某个文件夹,再使用response通过浏览器下载到客户端的桌面。
假如需要同时下载多个Excel,response请求只满足一次下载一个文件,这是需要先将多个Excel文件下载到同一个文件夹下,再将此文件夹压缩,之后下载压缩文件。

根据别人方法总结的,在此记录一下。

参考别人的:java将不同模块数据导出到多个excel并压缩下载


private ExportToExcelByPOI exportToExcelByPOI{

private final static Logger logger = LoggerFactory.getLogger(BasyybqkckController.class);

/**
     * 工具类
     *
     * @param workbook
     * @param sheetNum   第几个sheet
     * @param sheetTitle sheet的名称
     * @param headers    表头,可生成复杂的表头
     * @param fieldName  表头对饮的字段名
     * @param list       数据
     * @param type       用来分辨不同页面的导出
     * @throws Exception
     */
    public void exportExcelPoiTool(SXSSFWorkbook workbook, int sheetNum, String sheetTitle, String[][] headers, String[] fieldName,
                                   List<HashMap<String, Object>> list, String type) throws Exception {
        //设计表头
        int mergerNum = 0; //合并数
        //表头占几行,正文内容从表头之下开始
        int headersLen = headers.length;
        // 第一步,创建一个webbook,对应一个Excel以xsl为扩展名文件
        //SXSSFSheet sheet = (SXSSFSheet) workbook.createSheet();
        Sheet sheet = workbook.createSheet(sheetTitle);
        workbook.setSheetName(sheetNum, sheetTitle);
        // 冻结最左边的两列、冻结最上面的一行
        // 即:滚动横向滚动条时,左边的第一、二列固定不动;滚动纵向滚动条时,上面的第一,二,三行固定不动。
        //sheet.createFreezePane(2, 3);


        //设置列宽度大小
        // sheet.setDefaultColumnWidth((short) 30);
        //第二步, 生成表格第一行的样式和字体
        // 设置并获取到需要的样式
        XSSFCellStyle xssfCellStyleHeader = getAndSetXSSFCellStyleHeader(workbook);
        XSSFCellStyle xssfCellStyleOne = getAndSetXSSFCellStyleOne(workbook);
        XSSFCellStyle xssfCellStyleTwo = getAndSetXSSFCellStyleTwo(workbook);

        // 产生表格标题行
        // 循环创建header单元格(根据实际情况灵活创建即可)
        //给单元格设置值
        for (int i = 0; i < headers.length; i++) {
            //XSSFRow row = sheet.createRow(i);
            Row row = sheet.createRow(i);
            row.setHeight((short) 700);
            for (int j = 0; j < headers[i].length; j++) {
                //XSSFCell cell = row.createCell(j);
                Cell cell = row.createCell(j);
                cell.setCellStyle(xssfCellStyleHeader);
                cell.setCellValue(headers[i][j]);
            }
        }
        Map<Integer, List<Integer>> jumpMap = new HashMap<Integer, List<Integer>>(); // 合并行时要跳过的行列
        //合并列
        for (int i = 0; i < headers[headers.length - 1].length; i++) {
            if ("".equals(headers[headers.length - 1][i])) {
                for (int j = headers.length - 2; j >= 0; j--) {
                    if (!"".equals(headers[j][i])) {
                        sheet.addMergedRegion(new CellRangeAddress(j, headers.length - 1, i, i)); // 合并单元格
                        break;
                    } else {
                        if (jumpMap.containsKey(j)) {
                            List<Integer> jumpList = jumpMap.get(j);
                            jumpList.add(i);
                            jumpMap.put(j, jumpList);
                        } else {
                            List<Integer> jumpList = new ArrayList<Integer>();
                            jumpList.add(i);
                            jumpMap.put(j, jumpList);
                        }
                    }
                }
            }
        }
        //合并行
        for (int i = 0; i < headers.length - 1; i++) {
            for (int j = 0; j < headers[i].length; j++) {
                List<Integer> jumpList = jumpMap.get(i);
                if (jumpList == null || (jumpList != null && !jumpList.contains(j))) {
                    if ("".equals(headers[i][j])) {
                        mergerNum++;
                        if (mergerNum != 0 && j == (headers[i].length - 1)) {
                            sheet.addMergedRegion(new CellRangeAddress(i, i, j - mergerNum, j)); // 合并单元格
                            mergerNum = 0;
                        }
                    } else {
                        if (mergerNum != 0) {
                            sheet.addMergedRegion(new CellRangeAddress(i, i, j - mergerNum - 1, j - 1)); // 合并单元格
                            mergerNum = 0;
                        }
                    }
                }
            }
        }
        // 第三步:遍历集合数据,产生数据行,开始插入数据
        // 遍历创建行,导出数据
        if (list.size() > 0) {
            for (int rownum = 0; rownum < list.size(); rownum++) {
                // 从第四行开始有数据,前三行是表头
                Row row = sheet.createRow(rownum + headersLen);
                // 循环创建单元格
                for (int cellnum = 0; cellnum < fieldName.length; cellnum++) {
                    Cell cell = row.createCell(cellnum);
                    // 根据行数,设置该行内的单元格样式
                    cell.setCellStyle(xssfCellStyleOne);
                    if (fieldName[cellnum].equals("xh")) {
                        cell.setCellValue(rownum + 1);//序号
                    } else {
                        cell.setCellValue(list.get(rownum).get(fieldName[cellnum]) + "");
                    }
                }
            }
        }
 //设置内容的sheet
 setSheet(sheet);
 // 即:滚动横向滚动条时,左边的第一、二列固定不动;滚动纵向滚动条时,上面的第一,二,三行固定不动。
 sheet.createFreezePane(2, 3);
 //sheet.createFreezePane(2, headersLen);
 /**
     * 导出到本机桌面
     *
     * @param list,要导出的数据,一条数据对应一个sheet。 一条数据中包含多条要导出的数据,格式如下:
     *                                   List<List<Map<String,Object>>> list
     * @param headers                    表头,表头有一行的,两行的,三行的
     * @param fieldName                  表头对应的字段名称
     * @param fileName                   文件名
     * @param sheetTile                  sheet名称,一个sheetTitle对应list中的一条数据
     * @param type                       用来分辨不同的导出:
     * @return
     */
    public int exportToExcelByPoi_pc(List list, String[][] headers, String[] fieldName,
                                  String fileName, String[] sheetTile, String type) {
        //获取桌面路径,用于下载文件
        FileSystemView fsv = FileSystemView.getFileSystemView();
        File com = fsv.getHomeDirectory();
        // 导出的excel,全文件名
        //final String excelExportDestfilepath = com + "/" + map.get("fileName");
        final String excelExportDestfilepath = com + "/" + "/" + fileName + ".xlsx";

        ExportToExcelByPOI excelExport = null;
        // 用于导出多个sheet
        excelExport = new ExportToExcelByPOI();
        FileOutputStream fos = null;
        SXSSFWorkbook sxssfWorkbook = null;
        try {
            /// -> 从数据库中查询出要进行excel导出的数据
            long startTime0 = System.currentTimeMillis();
            long endTime0 = System.currentTimeMillis();
            logger.info("查询数据总耗时:{} 毫秒; list数量为 {}", endTime0 - startTime0, list.size());
            /// -> excel到处逻辑
            long startTime = System.currentTimeMillis();
            // 获取SXSSFWorkbook实例
            sxssfWorkbook = new SXSSFWorkbook();
            // sheet名称
            //Sheet sheet = sxssfWorkbook.createSheet(fileName);
            // 创建第一行,作为header表头;从第二行开始
            int ts = sheetTile.length;
            for (int i = 0; i < sheetTile.length; i++) {
                excelExport.exportExcelPoiTool(sxssfWorkbook, i, sheetTile[i], headers, fieldName, (List<HashMap<String, Object>>) list.get(i), type);
            }
            //在后面设置sheet
            //setSheet(sheet);
            fos = new FileOutputStream(excelExportDestfilepath);
            sxssfWorkbook.write(fos);
            long endTime = System.currentTimeMillis();
            logger.info("数据全部导出至excel总耗时:{} 毫秒!", endTime - startTime, list.size());
        } catch (Exception e) {
            logger.error("发生异常咯!", e);
        } finally {
            try {
                if (sxssfWorkbook != null)
                    // dispose of temporary files backing this workbook on disk -> 处
                    //     理SXSSFWorkbook导出excel时,产生的临时文件
                    sxssfWorkbook.dispose();
                if (fos != null)
                    fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return 1;
    }
            与导出到本机桌面不同的是的地方就是多了一个文件下载,
            1、先将文件下载到服务器的桌面,
            2、然后再将服务器上的文件通过浏览器下载到客户端,
            3、最后删除服务器上的文件
/**
     * 服务器导出到本机
     *
     * @param list,要导出的数据,一条数据对应一个sheet。 一条数据中包含多条要导出的数据,格式如下:
     *                                   List<List<Map<String,Object>>> list
     * @param headers                    表头,表头有一行的,两行的,三行的
     * @param fieldName                  表头对应的字段名称
     * @param fileName                   文件名
     * @param sheetTile                  sheet名称,一个sheetTitle对应list中的一条数据
     * @param type                       用来分辨不同的导出:
     * @param response
     * @return
     */
    public void exportToExcelByPoi(List list, String[][] headers, String[] fieldName,
                    String fileName, String[] sheetTile, String type, HttpServletResponse response) {
        //获取桌面路径,用于下载文件
        FileSystemView fsv = FileSystemView.getFileSystemView();
        File com = fsv.getHomeDirectory();
        // 导出的excel,全文件名
        //final String excelExportDestfilepath = filePath + fileName + ".xlsx";
        final String excelExportDestfilepath = com + "/" + "/" + fileName + ".xlsx";

        ExportToExcelByPOI excelExport = null;
        // 用于导出多个sheet
        excelExport = new ExportToExcelByPOI();
        FileOutputStream fos = null;
        SXSSFWorkbook sxssfWorkbook = null;
        try {
            /// -> 从数据库中查询出要进行excel导出的数据
            long startTime0 = System.currentTimeMillis();
            long endTime0 = System.currentTimeMillis();
            logger.info("查询数据总耗时:{} 毫秒; list数量为 {}", endTime0 - startTime0, list.size());
            /// -> excel到处逻辑
            long startTime = System.currentTimeMillis();
            // 获取SXSSFWorkbook实例
            sxssfWorkbook = new SXSSFWorkbook();
            // sheet名称
            //Sheet sheet = sxssfWorkbook.createSheet(fileName);
            //导出
            for (int i = 0; i < sheetTile.length; i++) {
                excelExport.exportExcelPoiTool(sxssfWorkbook, i, sheetTile[i], headers, fieldName, (List<HashMap<String, Object>>) list.get(i), type);
            }
            //在后面设置sheet
            //setSheet(sheet);
            fos = new FileOutputStream(excelExportDestfilepath);
            sxssfWorkbook.write(fos);

			// 以下是与导出到本机桌面不同的地方
            // 文件下载
            String excelName = fileName + ".xlsx";
            InputStream inputStream = null;
            ServletOutputStream outServletOutputStream = null;
            // 输出文档路径及名称
            File outFile = new File(excelExportDestfilepath);

            inputStream = new FileInputStream(excelExportDestfilepath);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msexcel");
            //response.addHeader("Content-Disposition", "attachment;filename=我" + "你" + ".xlsx");
            //response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
            //防止文件名中文乱码
            response.setHeader("Content-Disposition", "attachment;filename=" +
                    new String(excelName.getBytes("GBK"), "ISO8859-1"));
            outServletOutputStream = response.getOutputStream();
            byte[] buffer = new byte[512];
            int bytesToRead = -1;
            while ((bytesToRead = inputStream.read(buffer)) != -1) {
                outServletOutputStream.write(buffer, 0, bytesToRead);
            }
            // 流关闭后
            inputStream.close();
            //删除服务器上下载的文件
            outFile.delete();

            long endTime = System.currentTimeMillis();
            logger.info("数据全部导出至excel总耗时:{} 毫秒!", endTime - startTime, list.size());
        } catch (Exception e) {
            logger.error("发生异常咯!", e);
        } finally {
            try {
                if (sxssfWorkbook != null)
                    // dispose of temporary files backing this workbook on disk -> 处
                    //     理SXSSFWorkbook导出excel时,产生的临时文件
                    sxssfWorkbook.dispose();
                if (fos != null)
                    fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }
调用exportToExcelByPoi方法,进行导出

	@Autowired
    private ExportToExcelByPOI exportToExcelByPOI;

    @RequestMapping(value = "/exportToExcelByPoi", method = RequestMethod.GET)
	@ResponseBody
	public void exportPoi(@RequestParam Map<String, Object> map, HttpServletRequest request, HttpServletResponse response) {
	    //生成复杂的表头
		String[][] propertyDes = {{"序号","疾病", "例数", "", "", "死亡率", "", "", "药占比", "", "", "材料占比",
				"", "", "药品和材料占比", "", "", "平均住院日", "", "", "平均住院费用", "", ""},

				{"","", "本期值", "上期值", "", "本期值", "上期值", "", "本期值", "上期值", "", "本期值", "上期值",
						"", "本期值", "上期值", "", "本期值", "上期值", "", "本期值", "上期值", ""},

				{"","", "", "值", "±%", "", "值", "±%", "", "值", "±%", "", "值", "±%", "", "值", "±%",
						"", "值", "±%", "", "值", "±%"}};
		// 表头对应的字段名称
		String[] fieldName = {"xh","name", "ls", "lsPrev", "lsRadio",
				"swl", "swlPrev", "swlRadio", "yzb", "yzbPrev", "yzbRadio",
				"clzb", "clzbPrev", "clzbRadio", "ypyclzb", "ypyclzbPrev", "ypyclzbRadio",
				"pjzyr", "pjzyrPrev", "pjzyrRadio", "pjzyfy", "pjzyfyPrev","pjzyfyRadio"};
		// 查询要导出的数据
		List<HashMap<String, Object>> list = service.getData(map);
		//将数据转换成要导出的格式,这里根据情况而定
		List<HashMap<String, Object>> listData = conversionListData(list);
		// sheet的名称,要导出多个sheet的话,就会对应多个
		String[] sheetTile={fileName};
        List listExcel=new ArrayList();
        // 一个sheetTitle,对应一个listData,多个SheetTitle,对应多个ListData。这里是一个sheetTitle对应一个ListData。
		listExcel.add(listData);

		//多个的话如下:
 		String[] sheetTile = {"济南市", "青岛市", "淄博市", "枣庄市", "东营市", "烟台市", "潍坊市", "济宁市", "泰安市",
                "威海市", "日照市", "临沂市", "德州市", "聊城市", "滨州市", "菏泽市"};
 		for (int i = 0; i < sheetTile.length; i++) {
                List param = new ArrayList();
                // 分别查询16个地级市的数据
                List<HashMap<String, Object>> list = service.getData(map);
                //将数据转换为导出的格式
                List<HashMap<String, Object>> listData = conversionListData(list);
                // 把数据放到数组中,数组中放的是16个地级市的数据
                listExcel.add(listData );
        }
		exportToExcelByPOI.exportToExcelByPoi(listExcel,propertyDes,fieldName,fileName,sheetTile,response);
	}

以下代码:将多个Excel压缩成一个文件进行导出

 /**
     * 服务器导出多个Excel的Zip文件到客户端
     *
     *
     * @param list,要导出的数据,一条数据对应一个sheet。 一条数据中包含多条要导出的数据,格式如下:
     *                                   List<List<Map<String,Object>>> list
     * @param headers                    表头,表头有一行的,两行的,三行的
     * @param fieldName                  表头对应的字段名称
     * @param fileName                   文件名
     * @param sheetTile                  sheet名称,一个sheetTitle对应list中的一条数据
     * @param type                       用来分辨不同的导出:
     * @param response
     * @return
     */
    public void exportToExcelByPoi_zip(List list, String[][] headers, String[] fieldName,
                                      String[] fileName, String[] sheetTile, String type,
                                       HttpServletResponse response, HttpServletRequest request) {
        // 生成的excel表格路径
        final List<String> fileNameList = new ArrayList<String>();
        // list中包括多个excel的信息
        for (int i = 0; i < list.size(); i++) {
            List ListQuarter = (List) list.get(i);
            // 将数据导入到excel表格中,并将生成的表格路径添加到fileNameList中
            ExportExcelZipUtils.toExcelForZip(ListQuarter,headers,fieldName,fileName[i],sheetTile,type,response,request,fileNameList);
        }
        // 将生成的多个excel表格路径压缩成zip格式文件,并返回生成的临时zip文件路径
        final String zipFilePath = ExportExcelZipUtils.toZipFiles(request, fileNameList, "批量导出excel文件.zip");
        // zip文件创建成功
        if (!StringUtils.isEmpty(zipFilePath)) {
            try {
                // 设置response头
                ExportExcelZipUtils.setResponseHeader(response, "批量导出excel文件.zip");
                // 下载
                ExportExcelZipUtils.downloadZip(response.getOutputStream(), zipFilePath);
            } catch (final IOException e) {
                logger.info("get outputStream from response failed");
            }
        }
    }
public class ExportExcelZipUtils {
    private final static org.slf4j.Logger logger = LoggerFactory.getLogger(ExportToExcelByPOI.class);
    /**
     * 设置excel压缩文件导出时的请求头
     * @param response
     * @param fileName:多个excel的压缩文件名
     */
    public static void setResponseHeader(final HttpServletResponse response, final String fileName) {

        logger.info("begin to set response header");
        try {
            response.reset();
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            logger.info("set response header successfully");

        } catch (final Exception e) {
            logger.error("set response header failed", e);
        }
    }

    /**
     * 生成excel文件
     * @param list
     * @param headers
     * @param fieldName
     * @param fileName
     * @param sheetTile
     * @param type
     * @param response
     * @param request
     * @param fileNameList
     */
    public static void toExcelForZip(List list, String[][] headers, String[] fieldName,
                                     String fileName, String[] sheetTile, String type,
                                     HttpServletResponse response, HttpServletRequest request,
                                     List<String> fileNameList) {
        final File dirFile = new File(request.getRealPath(File.separator + "excel") + File.separator);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        final String file = request.getRealPath(File.separator + "excel") + File.separator + fileName + ".xlsx";

        //获取桌面路径,用于下载文件
        FileSystemView fsv = FileSystemView.getFileSystemView();
        File com = fsv.getHomeDirectory();
        // 导出的excel,全文件名
        final String excelExportDestfilepath = com + "/" + "/" + fileName + ".xlsx";

        ExportToExcelByPOI excelExport = null;
        // 用于导出多个sheet
        excelExport = new ExportToExcelByPOI();

        FileOutputStream fos = null;
        SXSSFWorkbook sxssfWorkbook = null;
        try {
            fos = new FileOutputStream(file);//为压缩文件做准备

            /// -> 从数据库中查询出要进行excel导出的数据
            long startTime0 = System.currentTimeMillis();
            long endTime0 = System.currentTimeMillis();
            logger.info("查询数据总耗时:{} 毫秒; list数量为 {}", endTime0 - startTime0, list.size());
            /// -> excel到处逻辑
            long startTime = System.currentTimeMillis();
            // 获取SXSSFWorkbook实例
            sxssfWorkbook = new SXSSFWorkbook();
            // sheet名称
            //Sheet sheet = sxssfWorkbook.createSheet(fileName);
            //导出
            for (int i = 0; i < sheetTile.length; i++) {
                excelExport.exportExcelPoiTool(sxssfWorkbook, i, sheetTile[i], headers, fieldName, (List<HashMap<String, Object>>) list.get(i), type);
            }
            //在后面设置sheet
            //setSheet(sheet);
            //在这里不能写这一行,写上这一行后,导出的文件会有问题。
            //fos = new FileOutputStream(excelExportDestfilepath);
            sxssfWorkbook.write(fos);
            fos.flush();//为压缩文件做准备
            fileNameList.add(file);//为压缩文件做准备
            long endTime = System.currentTimeMillis();
            logger.info("数据全部导出至excel总耗时:{} 毫秒!", endTime - startTime, list.size());
        } catch (Exception e) {
            logger.error("发生异常咯!", e);
        } finally {
            try {
                if (sxssfWorkbook != null)
                    // dispose of temporary files backing this workbook on disk -> 处
                    //     理SXSSFWorkbook导出excel时,产生的临时文件
                    sxssfWorkbook.dispose();
                if (fos != null)
                    fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }
    public static String toZipFiles(final HttpServletRequest request, final List<String> fileNameList,
                                    final String zipFileName) {

        String zipFilePath = request.getRealPath(File.separator + "excel") + File.separator + zipFileName;
        logger.info("begin to create zip file");

        final File[] files = new File[fileNameList.size()];
        for (int i = 0; i < fileNameList.size(); i++) {
            files[i] = new File(fileNameList.get(i));
        }
        // 压缩文件
        final File zipFile = new File(zipFilePath);
        // 将excel文件压缩成zip文件
        final byte[] buf = new byte[1024];
        ZipOutputStream zipOut = null;
        FileInputStream fis = null;
        try {
            zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
            for (int i = 0; i < files.length; i++) {
                fis = new FileInputStream(files[i]);
                zipOut.putNextEntry(new ZipEntry(files[i].getName()));
                int len = 0;
                while ((len = fis.read(buf)) > 0) {
                    zipOut.write(buf, 0, len);
                }
                zipOut.closeEntry();
                fis.close();
            }
        } catch (final Exception e) {
            zipFilePath = null;
            logger.error("failed to create zip file");
        } finally {
            if (zipOut != null) {
                try {
                    zipOut.close();
                } catch (final IOException e) {
                    logger.error("failed to close ZipOutputStream");
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (final IOException e) {
                    logger.error("failed to close FileInputStream");
                }
            }
        }
        return zipFilePath;
    }

    public static void downloadZip(final OutputStream out, final String zipFilePath) {

        logger.info("begin to download zip file from " + zipFilePath);
        FileInputStream inStream = null;
        try {
            inStream = new FileInputStream(zipFilePath);
            final byte[] buf = new byte[4096];
            int readLength;
            while (((readLength = inStream.read(buf)) != -1)) {
                out.write(buf, 0, readLength);
            }
            out.flush();
        } catch (final Exception e) {
            logger.error("download zip excel failed");
        } finally {
            try {
                inStream.close();
            } catch (final IOException e) {
                logger.error("failed to close FileInputStream");
            }
            try {
                out.close();
            } catch (final IOException e) {
                logger.error("failed to close OutputStream");
            }
        }
    }
}

调用exportToExcelByPoi_zip方法
1、listQuarterExcel的格式:List<List<HashMap<String, Object>>
2、headers:表头
3、field:表头对应的字段名
4、fileName:文件名
5、sheetTitle:sheet名称
6、type:用来区分不同的页面的导出

exportToExcelByPOI.exportToExcelByPoi_zip(listQuarterExcel,headers,field,fileName,sheetTile,type,response,request);
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值