导出几万的数据,放在一个excel文件可能会超行,而且很多数据放在缓存占用了大量的java内存,肯定会溢出,那么分成几个excel然后打包再下载就好多了 /** * 导出项目所有数据 * @param request * @param response * @return * @throws Exception */ public void exportAllExcel(HttpServletRequest request, HttpServletResponse response) throws Exception{ try{ String caseId = request.getParameter("caseId"); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); String reportTitle = "caseInfo_"+sdf.format(new Date());//导出文件的名字 String corpQuestionId = null; String contactQuestionId = null; List<Object> header = new ArrayList<Object>(); int count = 0; //项目信息导出 if(contactQuestionId == null && corpQuestionId == null){ header.addAll(Constant.CORP_BASE_INFO_HEADER);//Constant实体中写的是导出的中文表头 header.addAll(Constant.CUSTOMER_REGION_INFO_HEADER); header.addAll(Constant.CUSTOMER_TRADE_INFO_HEADER); header.addAll(Constant.CORP_DIAL_INFO_HEADER); header.addAll(Constant.CONTACT_BASE_INFO_HEADER); header.addAll(Constant.LEADS_INFO_HEADER); header.addAll(Constant.CONTACT_DIAL_INFO_HEADER); count = getQuestionManageService().getAllInfo(Long.parseLong(caseId)).size();//getAllInfo()是查询要导出记录总条数 } ExcelParser parser = new ExcelParser(); //导出6万以上数据。。。 int pageSiz= 50000;//设置每一个excel文件导出的数量 int page;//页数 //计算分页 page = count/pageSiz+(count%pageSiz > 0 ? 1:0); String auto_name = PrimaryKeyGenerator.getShortStringKey();//自动的生成一个文件码 //upload.excel是在misc.properties配置文件中配置的一个上传文件的路径,在这个路径下建一个文件夹 String folder = WebUtils.getModuleProperty("upload.excel") + File.separator +auto_name+"_myfolder"; //如果文件夹已存在就删除,可以根据需求安排是否进行删除,按照我的需求我不需要删除,因为我自动生成的文件码不会重复 //dropFolderOrFile(new File(folder)); File myfolder = new File(folder); myfolder.mkdir(); //开始从第一页循环导出一个文件到那个文件夹 for(int i = 0; i < page; i++){ List<Object[]> pageValues = new ArrayList<Object[]>(); //获取每次分页的数据 RowSelection rows = new RowSelection(i,pageSiz); //查询要导出的数据 if(contactQuestionId != null && corpQuestionId == null){ pageValues = getQuestionManageService().queryContactContent(Long.parseLong(contactQuestionId),Long.parseLong(caseId), rows); }else if(corpQuestionId != null && contactQuestionId == null){ pageValues = getQuestionManageService().queryCorpContent(Long.parseLong(corpQuestionId),Long.parseLong(caseId), rows); }else if(corpQuestionId != null && contactQuestionId != null){ pageValues = getQuestionManageService().getAllQuestionarieInfo(Long.parseLong(corpQuestionId),Long.parseLong(contactQuestionId),Long.parseLong(caseId), rows); }else if(contactQuestionId == null && corpQuestionId == null){ pageValues = getQuestionManageService().getAllInfo(Long.parseLong(caseId),rows); } List<Object[]> excelInfo = new ArrayList<Object[]>(); excelInfo.add(header.toArray()); excelInfo.addAll(pageValues); int j=i+1; //一定要在循环里建workBook,不然会造成数据堆积在内存,会溢出 HSSFWorkbook workBook = new HSSFWorkbook(); workBook = parser.getWriteBook(excelInfo); // System.gc();//什么呀?这个不知道是什么,注释掉 //生成excel文件 File f = new File(myfolder+File.separator+reportTitle+"_"+j+".xls"); if(f.exists()){ f.delete(); }else{ f.createNewFile(); } OutputStream os = new FileOutputStream(f); workBook.write(os); os.flush(); os.close(); } zipFile(folder);//folder是之前获取的文件夹路径 StringBuilder uri = new StringBuilder(); uri.append(folder); uri.append(".zip"); Utils.downloadFile(request,response,uri);//去下载zip文件 }catch(Exception e){ logger.error("导数时有错误!", e); e.printStackTrace(); } } /** * 使用POI进行Excel的写入工作 <br /> * 注:此方法会在生成的Excel工作表的最后多加一列,此列全部为空,不影响查看,<br /> * 但是对再次解析会有一定问题,再次解析这个生成的Excel时POI会认为最后这个空列也是一个有效列,<br /> * 所以我们需要解析的时候处理一下。<br /> * 这样做的原因:<br /> * 在使用jdbc-odbc的方式读取Excel时,用POI生成的Excel的文件的最后一列不被识别,<br /> * 无奈之举,在生成的Excel后面多加一列空列,这样使用jdbc-obdc读取时就不会有问题了。<br /> * 不过这也引出了上面的注意事项。其实,无论是不是poi生成的Excel文档,都需要做类似的判断的,<br /> * 任何的解析器都不会知道这个空列是否有用,那么必然会读取出来由用户来选择是否保留。 * * @param values * @throws IOException * ,FileNotFoundException * @throws IOException * @throws * @throws * @throws Exception */ public HSSFWorkbook getWriteBook(List<Object[]> values) throws IOException,FileNotFoundException { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet1 = wb.createSheet("Info"); int row = 0; for (Object[] objs : values) { HSSFRow row0 = sheet1.createRow(row); int col = 0; for (Object obj : objs) { row0.createCell(col).setCellValue(new HSSFRichTextString(obj == null || "null".equals(obj.toString()) ? "": String.valueOf(obj))); col++; } row++; } return wb; } /** * 删除文件夹 * @param folder */ private void dropFolderOrFile(File file) { if (file.isDirectory()) { File[] fs = file.listFiles(); for (File f : fs) { dropFolderOrFile(f); } } file.delete(); } /** * 将指定文件夹打包成zip * @param folder * @throws IOException */ private void zipFile(String folder) throws IOException { File zipFile = new File(folder + ".zip"); if (zipFile.exists()) { zipFile.delete(); } ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(zipFile)); File dir = new File(folder); File[] fs = dir.listFiles(); byte[] buf = null; if(fs!=null){ for (File f : fs) { zipout.putNextEntry(new ZipEntry(f.getName())); FileInputStream fileInputStream = new FileInputStream(f); buf = new byte[2048]; BufferedInputStream origin = new BufferedInputStream(fileInputStream,2048); int len; while ((len = origin.read(buf,0,2048))!=-1) { zipout.write(buf,0,len); } zipout.flush(); origin.close(); fileInputStream.close(); } } zipout.flush(); zipout.close(); } /**导出 * @param response * @param fileName * @return * @throws IOException */ public static void downloadFile(HttpServletRequest request,HttpServletResponse response,StringBuilder uri) throws IOException { //获取服务其上的文件名称 StringBuffer filename = new StringBuffer(); // filename.append(request.getSession().getServletContext().getRealPath("/")); filename.append(uri); File file = new File(filename.toString()); StringBuffer sb = new StringBuffer(); sb.append("attachment; filename=").append(uri.substring(uri.lastIndexOf("//")+1)); response.setHeader("Expires", "0"); response.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0"); response.setHeader("Pragma", "public"); response.setContentType("application/x-msdownload;charset=UTF-8"); response.setHeader("Content-Disposition", new String( sb.toString().getBytes(), "ISO8859-1")); //将此文件流写入到response输出流中 FileInputStream inputStream = new FileInputStream(file); OutputStream outputStream = response.getOutputStream(); byte[] buffer = new byte[1024]; int i = -1; while ((i = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, i); } outputStream.flush(); outputStream.close(); inputStream.close(); }