关键词搜索

源码搜索 ×
×

SpringMVC + Apache POI 实现WEB中Excel下载功能

发布2015-09-17浏览7341次

详情内容

欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。

欢迎跳转到本文的原文链接:https://honeypps.com/java/spring-mvc-apache-poi-web-excel-download/

项目中需要将web页面中的报表导出成Excel,在网上搜寻了写资料,实现了相关功能,如图1所示:

 

项目后台架构采用的是SpringMVC+Spring+Mybatis,通过引入Apache POI实现excel的下载功能。

导出效果如图2所示:

 

首先页面中点击“导出Excel”按钮就会触发如下js代码:

  1. function getXls()
  2. {
  3. var selectVal = dijit.byId('DRSSelectFacId').get('value');
  4. var beginTimeVal = dijit.byId('DRSBeginTime').get('displayedValue');
  5. var endTimeVal = dijit.byId('DRSEndTime').get('displayedValue');
  6. var url = "report/getDRSExcel.do?"+"fac_id="+selectVal+"&beginTime="+beginTimeVal+"&endTime="+endTimeVal;
  7. window.open(url,"_self");
  8. }

这段js代码的主要功能是将选择条件返回给后台,请求相应的数据并生成excel。

jsp相关代码如下:

  1. <div style="margin-top:10px;">
  2. <label for="DRSSelectFacId">选择电场:</label><span id="DRSSelectFacId" ></span>    
  3. <label for="DRSBeginTime">起始日期:</label><span id="DRSBeginTime" ></span>    
  4. <label for="DRSEndTime">截止日期:</label><span id="DRSEndTime" ></span>    
  5. <span id="DRSbutton1" ></span>    
  6. <span id="DRSbutton2" ></span>
  7. </div>

 

下面是JAVA后台控制层代码:

  1. @RequestMapping(value = "/report/getDRSExcel.do")
  2. public void getDRSExcel(
  3. @RequestParam(value = "fac_id", required = true) String fac_id,
  4. @RequestParam(value = "beginTime", required = true) String beginTime,
  5. @RequestParam(value = "endTime", required = true) String endTime,
  6. HttpServletRequest request, HttpServletResponse response)
  7. {
  8. logger.info("/report/getDRSExcel.do?fac_id=" + fac_id + "&beginTime="
  9. + beginTime + "&endTime=" + endTime);
  10. try {
  11. this.daliyRepShortService.getXls(fac_id,beginTime,endTime,request,response);
  12. } catch (ParseException e) {
  13. e.printStackTrace();
  14. }
  15. }

这里调用了业务层代码如下:

  1. private List<Map<String, Object>> createExcelRecord(List<Fc_dailyreport> projects) {
  2. List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
  3. Map<String, Object> map = new HashMap<String, Object>();
  4. map.put("sheetName", "短期预测日报");
  5. listmap.add(map);
  6. Fc_dailyreport project=null;
  7. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  8. DecimalFormat fnum = new DecimalFormat("##0.0000");
  9. for (int j = 0; j < projects.size(); j++) {
  10. project=projects.get(j);
  11. Map<String, Object> mapValue = new HashMap<String, Object>();
  12. mapValue.put("dtime", sdf.format(project.getDtime()));
  13. mapValue.put("cap", project.getCap());
  14. mapValue.put("p", project.getP());
  15. mapValue.put("fore_p", project.getFore_p());
  16. mapValue.put("rmse", fnum.format(project.getRmse()*100)+"%");
  17. mapValue.put("mae", fnum.format(project.getMae()*100)+"%");
  18. mapValue.put("qualified_rate", project.getQualified_rate()+"%");
  19. mapValue.put("colrel", project.getColrel());
  20. mapValue.put("uploadrate", project.getUploadrate()+"%");
  21. mapValue.put("qxuploadrate", project.getQxuploadrate()+"%");
  22. listmap.add(mapValue);
  23. }
  24. return listmap;
  25. }
  26. public void getXls(String fac_id,String beginTime,String endTime,HttpServletRequest request, HttpServletResponse response)
  27. throws ParseException
  28. {
  29. String fileName="短期预测日报";
  30. //1.
  31. List<Fc_dailyreport> projects = getXlsData(fac_id,beginTime,endTime);
  32. /https://cdn.jxasp.com:9143/image/2.
  33. List<Map<String,Object>> list=createExcelRecord(projects);
  34. //3.
  35. String columnNames[]={"时间","容量(MW)","实际功率(MW)","预测功率(MW)","均方误差(%)","平均绝对误差(%)","合格率(%)","相关系数","上传率(%)","气象上传率(%)"};//列名
  36. String keys[] = {"dtime","cap","p","fore_p","rmse","mae","qualified_rate","colrel","uploadrate","qxuploadrate"};//map中的key
  37. //4.
  38. ExcelUtil.ExcelSingleOutputStream(list,keys,columnNames,fileName,request,response);
  39. }

在getXls方法中,getXlsData(fac_id,beginTime,endTime);主要是根据前端的查询条件参数获取所要的数据,这里采用的是mybatis实现,由于本文的主旨是与excel相关的,这里就不说明mybatis如何实现数据的获取。

第二步是创建excel的数据,如方法createExcelRecord(projects);所示。list中第一项的sheetName用来命名Excel中的sheet。剩余list中的数据数excel中的没一行的数据。在getXls方法中的columnNames对应excel的第一行的列名,可参考图2. keys与createExcelRecord中的相关名字一一对应(这里也与DAO值的pojo类的属性名字一一对应)。

接下来就需要了解ExcelUtil.ExcelSingleOutputStream(list,keys,columnNames,fileName,request,response);这一段代码是做什么的了。

首选看类ExcelUtil:

  1. package com.shr.util;
  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedOutputStream;
  4. import java.io.ByteArrayInputStream;
  5. import java.io.ByteArrayOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.io.UnsupportedEncodingException;
  9. import java.util.List;
  10. import java.util.Map;
  11. import javax.servlet.ServletOutputStream;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  15. import org.apache.poi.ss.usermodel.Cell;
  16. import org.apache.poi.ss.usermodel.CellStyle;
  17. import org.apache.poi.ss.usermodel.Font;
  18. import org.apache.poi.ss.usermodel.IndexedColors;
  19. import org.apache.poi.ss.usermodel.Row;
  20. import org.apache.poi.ss.usermodel.Sheet;
  21. import org.apache.poi.ss.usermodel.Workbook;
  22. public class ExcelUtil {
  23. public static Workbook createSingleWorkBook(List<Map<String, Object>> list,String []keys,String columnNames[]) {
  24. Workbook wb = new HSSFWorkbook();
  25. Sheet sheet = wb.createSheet(list.get(0).get("sheetName").toString());
  26. for(int i=0;i<keys.length;i++)
  27. {
  28. sheet.setColumnWidth((short) i, (short) (35.7 * 150));
  29. }
  30. Row row = sheet.createRow((short) 0);
  31. CellStyle cs = wb.createCellStyle();
  32. CellStyle cs2 = wb.createCellStyle();
  33. Font f = wb.createFont();
  34. Font f2 = wb.createFont();
  35. f.setFontHeightInPoints((short) 10);
  36. f.setColor(IndexedColors.BLACK.getIndex());
  37. f.setBoldweight(Font.BOLDWEIGHT_BOLD);
  38. f2.setFontHeightInPoints((short) 10);
  39. f2.setColor(IndexedColors.BLACK.getIndex());
  40. cs.setFont(f);
  41. cs.setFillForegroundColor(IndexedColors.AQUA.getIndex());
  42. cs.setFillPattern(CellStyle.SOLID_FOREGROUND);
  43. cs.setBorderLeft(CellStyle.BORDER_THIN);
  44. cs.setBorderRight(CellStyle.BORDER_THIN);
  45. cs.setBorderTop(CellStyle.BORDER_THIN);
  46. cs.setBorderBottom(CellStyle.BORDER_THIN);
  47. cs.setAlignment(CellStyle.ALIGN_CENTER);
  48. cs2.setFont(f2);
  49. cs2.setBorderLeft(CellStyle.BORDER_THIN);
  50. cs2.setBorderRight(CellStyle.BORDER_THIN);
  51. cs2.setBorderTop(CellStyle.BORDER_THIN);
  52. cs2.setBorderBottom(CellStyle.BORDER_THIN);
  53. cs2.setAlignment(CellStyle.ALIGN_CENTER);
  54. for(int i=0;i<columnNames.length;i++){
  55. Cell cell = row.createCell(i);
  56. cell.setCellValue(columnNames[i]);
  57. cell.setCellStyle(cs);
  58. }
  59. for (short i = 1; i < list.size(); i++) {
  60. Row row1 = sheet.createRow((short) i);
  61. for(short j=0;j<keys.length;j++){
  62. Cell cell = row1.createCell(j);
  63. cell.setCellValue(list.get(i).get(keys[j]) == null?" ": list.get(i).get(keys[j]).toString());
  64. cell.setCellStyle(cs2);
  65. }
  66. }
  67. return wb;
  68. }
  69. public static void ExcelSingleOutputStream(List<Map<String, Object>> list,String []keys,String columnNames[],
  70. String fileName, HttpServletRequest request, HttpServletResponse response)
  71. {
  72. ByteArrayOutputStream os = new ByteArrayOutputStream();
  73. try {
  74. createSingleWorkBook(list,keys,columnNames).write(os);
  75. } catch (IOException e2) {
  76. e2.printStackTrace();
  77. }
  78. ExcelOutputStream(fileName,request,response,os);
  79. }
  80. private static void ExcelOutputStream( String fileName, HttpServletRequest request, HttpServletResponse response,ByteArrayOutputStream os)
  81. {
  82. byte[] content = os.toByteArray();
  83. InputStream is = new ByteArrayInputStream(content);
  84. response.reset();
  85. response.setContentType("application/vnd.ms-excel;charset=utf-8");
  86. try {
  87. response.setHeader("Content-Disposition", "attachment;filename="+ new String((fileName + ".xls").getBytes(), "iso-8859-1"));
  88. } catch (UnsupportedEncodingException e1) {
  89. e1.printStackTrace();
  90. }
  91. ServletOutputStream out = null;
  92. try {
  93. out = response.getOutputStream();
  94. } catch (IOException e1) {
  95. e1.printStackTrace();
  96. }
  97. BufferedInputStream bis = null;
  98. BufferedOutputStream bos = null;
  99. try {
  100. bis = new BufferedInputStream(is);
  101. bos = new BufferedOutputStream(out);
  102. byte[] buff = new byte[2048];
  103. int bytesRead;
  104. while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
  105. bos.write(buff, 0, bytesRead);
  106. }
  107. } catch ( IOException e) {
  108. e.printStackTrace();
  109. } finally {
  110. if (bis != null)
  111. try {
  112. bis.close();
  113. } catch (IOException e) {
  114. e.printStackTrace();
  115. }
  116. if (bos != null)
  117. try {
  118. bos.close();
  119. } catch (IOException e) {
  120. e.printStackTrace();
  121. }
  122. }
  123. }
  124. }

 

这里的createSingleWorkBook方法用来根据业务层中的相关数据生成的excel,这时候生成的excel是驻留在内存中的,所以需要其输出,请参照方法ExcelSingleOutputStream和ExcelOutputStream(这里将一个方法拆分成两个是因为原项目中还有其他的情况考虑,本文只罗列出一种相对简单的情况,所以这样不要差异,可以将这两个方法看成一个也无妨,主要是向页面输出这个生成的Excel。

 

欢迎跳转到本文的原文链接:https://honeypps.com/java/spring-mvc-apache-poi-web-excel-download/

 

欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


 


 

 

 

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载