Java实现导出多个excel表打包到zip文件中->供客户端下载

业务需求:将需求方要的数据导出excel表中。

                1.只发出一次请求

                 2.每个excel表中到数据记录不能超过50条

碰过的坑:原先我发出的是ajax请求,然后请求成功却返回的都是乱码!我是想要下载文件啊!!!

                 ajax请求,响应的是文本数据,所以下载文件不能用ajax请求!用什么呢?用链接就行了

  location.href= "../../aliGoodsOrder/export?startDate="+app.startDate+"&endDate="+app.endDate;

或者一个 标签。

后台怎么导出excel呢,分享一个特别简单的工具类给大家:

@Log4j
public class Excel {

    public static HSSFWorkbook createExcel(String sheetName, List cellNameList) {

        HSSFWorkbook excel = new HSSFWorkbook();
        HSSFSheet sheet = excel.createSheet(sheetName);
        HSSFRow row = sheet.createRow(0);
        int cellIndex = 0;
        for (String cellName : cellNameList) {
            HSSFCell cell = row.createCell(cellIndex);
            cell.setCellValue(cellName);
            cellIndex++;
        }
        return excel;
    }

    public static HSSFWorkbook createExcelData(HSSFWorkbook excel, List excelData,int rowIndex ,int columnSum){
        HSSFRow row=excel.getSheetAt(0).createRow(rowIndex);
        for(int i = 0; i < columnSum; i++){
            row.createCell(i).setCellValue(excelData.get(i));
        }
        return excel;
    }

}
  
        
            org.apache.poi
            poi-ooxml
            3.16
        

 

怎么使用呢:


    /**
     * @ Date       :2018/11/05
     * @ Description:将1688商品订单导出Excel
     */
    private HSSFWorkbook exportExcel(List allList,String name){
        log.info("|createdExcel================start!============|");
        HSSFWorkbook excel = null;
        try{
            List cellNameList = new ArrayList<>();
            cellNameList.add("订单号");
            cellNameList.add("商品名称");
            cellNameList.add("商品数量(件)");
            cellNameList.add("商品规格1(如:颜色)");
            cellNameList.add("商品规格2(如:尺码)");
            cellNameList.add("收件人-姓名");
            cellNameList.add("收件人-手机");
            cellNameList.add("收件人-省");
            cellNameList.add("收件人-市");
            cellNameList.add("收件人-区");
            cellNameList.add("收件人-详细地址");
            cellNameList.add("买家留言");
            cellNameList.add("1688商品id");
            String fileName = name;
            String sheetName  = name;
            excel = Excel.createExcel(sheetName,cellNameList);

            int rowIndex = 1;
            for (AliGoodsOrder order:
                    allList ) {
                List excelDate = new ArrayList<>();
                excelDate.add("");//订单号设置为空
                excelDate.add(order.getTitle()+"");
                excelDate.add(order.getNum()+"");
                excelDate.add(order.getSku1()+"");
                excelDate.add(order.getSku2()+"");
                excelDate.add(order.getReceiverName()+"");
                excelDate.add(order.getReceiverTel()+"");
                excelDate.add(order.getDeliveryProvince()+"");
                excelDate.add(order.getDeliveryCity()+"");
                excelDate.add(order.getDeliveryDistrict()+"");
                excelDate.add(order.getDeliveryAddress()+"");
                excelDate.add(order.getBuyerMessage()+"");
                excelDate.add(order.getAliId()+"");
                excel = Excel.createExcelData(excel,excelDate,rowIndex,13);
                rowIndex++;
            }

            log.info("|createdExcel================end!============|");
        }catch (Exception e){
            log.error(ExceptionUtils.getTraceInfo(e));
        }
        return excel;
    }

目前位置,excel的导出完成了呢?想要客户端下载的小宝贝们,可以把以下方法放入工具类中哦

    //导出excel文件
    public static  void downLoad(HttpServletResponse response, String fileName, HSSFWorkbook wb){
        try {
            response.reset();
            response.setContentType("application/ms-excel;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName+".xls", "UTF-8"))));
            try {
                wb.write(response.getOutputStream());
                response.getOutputStream().flush();
            } catch (Exception e) {
                log.error("Excel导出出错", e);
                throw e;
            }finally{
                if(response.getOutputStream()!=null){
                    response.getOutputStream().close();
                }
            }

        }catch (Exception e){
            log.error("downLoadExcel-------fail!");
            log.error(ExceptionUtils.getTraceInfo(e));
        }

    }

 如果你是需要客户端请求下载一个excle文件,到这里就可以结束咯(ps只要在控制类中调用此类就完成了)

如果你是想要将多个excel表打包成zip后再下载,请继续看

代码不必看懂!!!!你只要知道以下是为了获取一个excel表的列表(这里还有个小小知识点就是列表的子列表哦)

    /**
     * 分页获取Excel的list列表
     * @param startDate
     * @param endDate
     * @return
     */
    private List getExcelByPagination(String startDate, String endDate){
        List list = getOrderByDate(startDate,endDate);
        int totalPage = list.size()%50 == 0 ? list.size()/50 : list.size()/50 + 1;

        List hssfWorkbookList = new ArrayList<>();
        String fileName = startDate+"至"+endDate+"1688商品货单信息";
        for(int page = 1; page <= totalPage; page++){

            int fromIndex = (page-1)*50;
            int toIndex;
            if(page == totalPage && list.size()%50!= 0){
                toIndex = fromIndex + list.size()%50;
            }else{
                toIndex = fromIndex + 50;
            }

            HSSFWorkbook hssfWorkbook = exportExcel(list.subList(fromIndex,toIndex),fileName);
            if(hssfWorkbook != null){
                hssfWorkbookList.add(hssfWorkbook);
            }

        }
        return hssfWorkbookList;
    }

下载zip的工具类要贴出来了~

    //直接下载
    public static void downFileByStream(HttpServletResponse response,List excels,String fileName){
        try {
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            ZipOutputStream zipOut = new ZipOutputStream(toClient);
            for(int i=0;i

用法---》下载的实现服务类

    /**
     * @ Date       :2018/11/05
     * @ Description:一个excel表中导出50条记录,打包放入zip文件中并下载
     */
    @Override
    public void downLoadZip(HttpServletResponse response,String startDate, String endDate) {
        try {
            List hssfWorkbookList = getExcelByPagination(startDate,endDate);
            String fileName = startDate+"至"+endDate+"1688商品货单信息";

//            File temp = File.createTempFile("temp",".zip");
//            FileUtil.zipFiles(hssfWorkbookList,temp,fileName);
//            response = FileUtil.downFile(response, temp);
//            temp.deleteOnExit();
            FileUtil.downFileByStream(response,hssfWorkbookList,fileName);
        }catch (Exception e){
            log.error("downLoadZip=======fail!"+ExceptionUtils.getTraceInfo(e));

        }

    }

 从前端至后台的代码就贴完了

为啥上面代码有几行代码注释了呢?因为之前的想法是将excel导出后打包为zip文件,然后客户端就可以请求文件下载了。

但是之后发现多此一举了,直接将文件流存到response.getOutputStream()里面就行了

也贴下这个冗余的代码把。

   /**
     * 将多个Excel打包成zip文件
     * @param srcfile
     * @param zipfile
     */
    public static void zipFiles(List srcfile, File zipfile,String fileName) {
        try {
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipfile));
            for (int i = 0; i < srcfile.size(); i++) {
                out.putNextEntry(new ZipEntry(fileName+i+".xls"));
                srcfile.get(i).write(out);
            }
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 下载文件
     * @param response
     * @param file
     * @return
     */
    public static HttpServletResponse downFile(HttpServletResponse response, File file) {
        try {
            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/x-zip-compressed");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }

看到这个下载文件的代码,我又要多叨唠一句了,为啥我最后又是返回的null呢?因为返回response报错了呀,看网上大家都说

response.getOutputStream()和服务器里的out.write()冲突了啥啥啥反正我是没看懂,只记住了一个可爱的小朋友说,你只要返回null就行了。。。

这篇博客就这样粗略的贴代码放功能把,下篇了再讲讲遇到的新知识点

你可能感兴趣的:(个人项目经验,工作笔记)