导出List列表中的数据到Excel文件,并提供下载
2013-12-23 16:08
260 查看
整体思路
客户在页面点击“导出Excel”链接-->>进入Java逻辑处理代码-->>复制Excel模版文件-->>向这个复制过的模版文件中写入List数据-->>把数据写入完成的Excel文件下载到客户端适用场景
数据格式固定、需要把List数据导出到Excel文件的情况下具体代码
1.页面链接
// 添加“导出Excel”链接 $("div#paddingDiv").append( " <a href='exportStatisticsData.sp?dateStart=" + $("#dateStartId").val() + "&dateEnd=" + $("#dateEndId").val() + "&selectOrgan=" + $("#selectOrgan").val() + "''>导出查询结果到Excel</a>");
2.SpringMVC的ModelAndView
<!-- 工作量报表,导出Excel的Action跳转 --> <bean name="/exportStatisticsData.sp" class="com.peak.acc.action.ExportStatisticsAction"> <property name="commonDao"> <ref bean="commonDao" /> </property> </bean>
try { // 接下来,取出数据,进行页面显示 list = commonDao.getObjectListByArguments("queryStatisticsT", null); // 将数据库查询出来的列表集,转成页面展示需要的格式,单独放在一个方法里 listShowInPage = exchangeToShowList(list, organString); /** * 最后展示到页面上的列表元素数量 */ int rows = listShowInPage.size(); // 模版文件对象(模版在项目中有) File templateFirst = null; if (rows <= 2) {// 如果只有少于等于两行数据,就使用模版2 templateFirst = new File(request.getRealPath("/") + "upload/acc/template/Acc任务数量统计模版2.xls"); } else {// 否则,使用模版1 templateFirst = new File(request.getRealPath("/") + "upload/acc/template/Acc任务数量统计模版1.xls"); } // 使用模版,生成Excel文件的目标路径 targetPath = "D:/acc_rm/Excel/createWhatYouWant/"; // 拷贝模版,生成一个新的文件,用于写入统计数据,使用UUID生成唯一文件名 String newFileName = targetPath + UUID.randomUUID().toString() + ".xls"; File newTargetFile = new File(targetPath); // 若目录不存在,就创建一个 if (!newTargetFile.exists()) { newTargetFile.mkdirs(); } // 创建目标Excel文件,.xls格式的 newTargetFile = new File(newFileName); // 调用静态方法copyFile()复制模版文件 到目标文件 AccFileUtil.copyFile(templateFirst, newTargetFile); log.info("任务统计的写入文件准备就绪"); // 把数据,写入到目标文件 createTheTargetExcel(rows, newTargetFile); // 附件名称 String filename = "会计标准化任务统计报表 " + startDate + " -- " + endDate + " " + organString + ".xls"; // 设置response的编码方式 response.setContentType("application/x-msdownload"); // 写明要下载的文件的大小 response.setContentLength((int) newTargetFile.length()); // 设置下载附件的文件名 response.setHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes("GBK"), "iso-8859-1")); // 读出文件到i/o流 FileInputStream fis = new FileInputStream(newTargetFile); byte[] b = new byte[1024];// 相当于我们的缓存 int k = 0;// 该值用于计算当前实际下载了多少字节 // 从response对象中得到输出流,准备下载 OutputStream myout = response.getOutputStream(); // 开始循环下载 while (-1 != (k = fis.read(b, 0, b.length))) { // 将b中的数据写到客户端的内存 myout.write(b, 0, k); } // 将写入到客户端的内存的数据,刷新到磁盘 myout.flush(); myout.close(); } catch (Exception e) { log .info("ExportExcel ------------------任务数量统计查询转换出现错误--------------------------:" + e.getMessage()); e.printStackTrace(); } finally { // 清空列表所占有的内存 clearAllList(); // 最后,检查一下目录下的文件个数,大于100的话,就进行清空 deleteDirFiles(targetPath, 100); } // 展示,这里无需返回视图 return null;
public static void copyFile(File sourceFile, File targetFile) throws IOException { BufferedInputStream bufIS = null; BufferedOutputStream bufOS = null; try { // 带缓冲的输入流 bufIS = new BufferedInputStream(new FileInputStream(sourceFile)); // 带缓冲的输出流 bufOS = new BufferedOutputStream(new FileOutputStream(targetFile)); // 缓冲数组 byte[] bytes = new byte[1024 * 5]; // 位置记录 int len = 0; while ((len = bufIS.read(bytes)) != -1) { // 把读入的数据流写入到输出流冲 bufOS.write(bytes, 0, len); } // 强制写入到输出流 bufOS.flush(); } catch (FileNotFoundException e) { log.info("复制文件时找不到文件:" + e.getMessage()); e.printStackTrace(); } catch (IOException e) { log.info("复制文件时出现IO错误:" + e.getMessage()); e.printStackTrace(); } finally { // 重要:记得关闭流 if (bufIS != null) { bufIS.close(); } if (bufOS != null) { bufOS.close(); } } }
/** * 向目标Excel文件写入数据 * * @param rows * 需要写多少行Excel * @param newTargetFile * 目标文件 * @throws IOException */ private void createTheTargetExcel(int rows, File newTargetFile) throws IOException { FileOutputStream localFile = null; try { // 获取到拷贝过后的Excel模版文件 POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream( newTargetFile)); // 根据Excel文件,获取到 工作簿 HSSFWorkbook workbook = new HSSFWorkbook(fs); // 获取到第一页工作表 HSSFSheet sheet = workbook.getSheetAt(0); // 定义行 HSSFRow row; // 列表中的把数据写入到Excel里面,从第四行开始(前三行是标题) for (int i = 0; i < rows; i++) { StatisticsShowE aline = (StatisticsShowE) listShowInPage.get(i); row = sheet.getRow(i + 3); // 获取第(i+3)行,前三行是标题 // 单元格的位置,从0开始 short tempCellCounter = 0; // 解决中文乱码问题(Excel文件内容里面的乱码) row.getCell(tempCellCounter).setEncoding( HSSFWorkbook.ENCODING_UTF_16); row.getCell(tempCellCounter).setCellValue(aline.getJgm()); tempCellCounter++; // 每日 row.getCell(tempCellCounter).setCellValue( aline.getMrrw().getWcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getMrrw().getWwcCount()); tempCellCounter++; // 日终 row.getCell(tempCellCounter).setCellValue( aline.getRzrw().getWcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getRzrw().getWwcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getRzrw().getCbCount()); tempCellCounter++; // 每周 row.getCell(tempCellCounter).setCellValue( aline.getMzrw().getWcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getMzrw().getWwcCount()); tempCellCounter++; // 每旬 row.getCell(tempCellCounter).setCellValue( aline.getMxrw().getWcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getMxrw().getWwcCount()); tempCellCounter++; // 每月 row.getCell(tempCellCounter).setCellValue( aline.getMyrw().getWcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getMyrw().getWwcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getMyrw().getCbCount()); tempCellCounter++; // 每季 row.getCell(tempCellCounter).setCellValue( aline.getMjrw().getWcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getMjrw().getWwcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getMjrw().getCbCount()); tempCellCounter++; // 半年 row.getCell(tempCellCounter).setCellValue( aline.getBnrw().getWcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getBnrw().getWwcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getBnrw().getCbCount()); tempCellCounter++; // 每年 row.getCell(tempCellCounter).setCellValue( aline.getMnrw().getWcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getMnrw().getWwcCount()); tempCellCounter++; row.getCell(tempCellCounter).setCellValue( aline.getMnrw().getCbCount()); tempCellCounter++; } // 新建一输出文件流 localFile = new FileOutputStream(newTargetFile); // 把数据写入到相应的Excel 工作簿 workbook.write(localFile); localFile.flush(); localFile.close(); } catch (FileNotFoundException e) { log.info("向Excel文件写入数据时出现异常:" + e.getMessage()); e.printStackTrace(); } catch (IOException e) { log.info("向Excel文件写入数据时出现异常:" + e.getMessage()); e.printStackTrace(); } finally { if (localFile == null) { // 操作结束,关闭文件 localFile.close(); } } }
/** * 当指定的目录下,文件个数超过一定数量时,进行清空 * * @param path * @param targetNum */ private void deleteDirFiles(String path, int targetNum) { File dirPath = new File(path); if (dirPath.exists()) {// 如果找到了这个目录 File[] excelFiles = dirPath.listFiles(); // 当该目录下的文件个数大于指定参数时 if (excelFiles.length > targetNum) { for (int i = 0; i < excelFiles.length; i++) { File tempFile = excelFiles[i]; // 日志记录删除的文件的名称 log.info(tempFile.getName() + " 已经删除"); if (tempFile.isFile()) {// 如果是文件,就进行删除 tempFile.delete(); } } } } }
注:使用的Excel解析框架是POI,此处仅提供实现思路和部分实现代码
导出效果:
最后导出的Excel文件:
模版文件:
相关文章推荐
- 使用ADO.net将数据导出到Excel并提供下载
- datagrid数据导出到excel文件给客户端下载的几种方法 (转)
- [转]datagrid数据导出到excel文件给客户端下载的几种方法
- datagrid数据导出到excel文件给客户端下载的几种方法
- datagrid数据导出到excel文件给客户端下载的几种方法
- Asp.net 2.0 GridView数据导出Excel文件(示例代码下载)
- datagrid数据导出到excel文件给客户端下载的几种方法 选择自 yangyifan0 的 Blog
- datagrid数据导出到excel文件给客户端下载的几种方法
- jsp页面导出当前list数据列表 excel
- datagrid数据导出到excel文件给客户端下载的几种方法
- 前端数据传到后台动态生成Excel文件并提供文件下载
- 数据导出到excel文件给客户端下载的几种方法
- php导出csv数据在浏览器中输出提供下载或保存到文件的示例
- Asp.net 2.0 GridView数据导出Excel文件(示例代码下载)
- 【POI】导出excel文件,不生成中间文件,直接将内存中的数据创建对象下载到浏览器
- Asp.net 2.0 GridView数据导出Excel文件(示例代码下载)
- datagrid数据导出到excel文件给客户端下载的几种方法
- 将页面的列表数据导出到excel文件中
- datagrid数据导出到excel文件给客户端下载的几种方法
- 使用ADO.net将数据导出到Excel并提供下载