java导出excel并且压缩成zip上传到oss,并下载,使用字节流去存储,不用文件流保存文件到本地
最近项目上要求实现导出excel并根据条数做分割,然后将分割后的多个excel打包成压缩包上传到oss服务器上,然后提供下载方法,具体代码如下:这里只展示部分代码,获取数据的代码就不展示了
ByteArrayOutputStream zipos = new ByteArrayOutputStream(61858764);//设置大小为60M ZipOutputStream zos = new ZipOutputStream (zipos) ;//创建压缩流,初始化一个输出流缓存区 for(Entry<String, JSONObject> entry : mapData.entrySet()){ String key = entry.getKey(); JSONObject jsonVal = entry.getValue(); OrderMonitorExcelViewSvc orderMonitorExcelView = new OrderMonitorExcelViewSvc(jsonVal); try { orderMonitorExcelView.outputToFile("orderMonitorExport_"+key); } catch (Exception e1) { logger.info(e1); } HSSFWorkbook workbook = orderMonitorExcelView.getWorkbook(); ByteArrayOutputStream os = new ByteArrayOutputStream(61858764);//设置大小为60M try { workbook.write(os); //创建一个压缩文件里的名称 ZipEntry zipEntry = new ZipEntry("订单监控查询"+key+".xls"); System.out.println(os.size()); zipEntry.setSize(os.size()); zipEntry.setCompressedSize(os.size()); zos.putNextEntry(zipEntry); os.writeTo(zos); zos.closeEntry(); os.close(); } catch (IOException e) { logger.info("写入ZipOutputStream异常"); } } try { zos.close();//注意关闭流的顺序,在上传oss之前必须关闭流否则下载解压的时候会报“文件末端错误”的问题 zipos.close(); ByteArrayInputStream zipis = new ByteArrayInputStream(zipos.toByteArray()); @SuppressWarnings("deprecation") int rel = cpsdCoralStorage.uploadFile("order_monitor_data/"+batchno,zipis); if(rel==0){ orderMonitorDao.updateDownloadBatch("0", batchno); } zipis.close(); } catch (IOException e) { logger.info("上传oss失败"); logger.info("关闭压缩流异常"+e); }
下载方法:
@RequestMapping(value = { "downloadExport" }) public void downloadExport(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "batchno", required = true) String batchno) throws IOException { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); String formatDate = sdf.format(new Date()); String pathName = "order_monitor_data/" + batchno; String srcFileName = "导出结果" + formatDate + ".zip"; InputStream is = cpsdCoralStorage.downloadFile(pathName); try { response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(srcFileName, "utf-8")); OutputStream out = response.getOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int temp =0; while((temp=is.read())!=-1){ // 读取内容 baos.write(temp); } byte[] xlsBytes = baos.toByteArray(); out.write(xlsBytes); out.flush(); out.close(); } catch (FileNotFoundException e) { logger.logException(e); } catch (IOException e) { logger.logException(e); } }
本次分享主要是因为之前导出都是先存一个文件,需要找一个存储目录,这样发布到生产环境会有各种问题,还需要看文件夹是否有读写权限,我用的这个方法是直接设置一个存储流,直接对流进行操作,省去了这些麻烦!