当前位置:   article > 正文

Java 使用POI导出数据到 excel,单 sheet 和多 sheet_poi多sheet

poi多sheet

        前段时间,写(shui)了一个上传文件的博客(Java 上传附件后端接口大体流程和逻辑),今天做项目时,刚好又遇到导出excel的功能,前期就一直想做个归纳记录,但一直都是被各种各样的事(tuo)情(yan)耽搁了,今天刚好遇到导出数据到多 sheet的需求,开发完后,顺手来记录一下。

       凡事都是由简入繁,我们首先从Java导出excel 单sheet开始,这个场景遇到的比较多,比较普遍。

前期准备:

单 sheet 和 多 sheet,用到的jar都是一样的,无非就是多创建一个 sheet的问题,以下是需要用到的jar包,在对应模块的pom.xml 中引入即可

  1. <dependency>
  2. <groupId>org.apache.poi</groupId>
  3. <artifactId>poi</artifactId>
  4. <version>3.9</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.poi</groupId>
  8. <artifactId>poi-ooxml</artifactId>
  9. <version>3.9</version>
  10. </dependency>

导出开始:

从前到后,首先我们要在controller 层中开放一个GET请求接口,因为当前场景设定为列表导出,会涉及到页面查询条件,所以controller 层代码如下:

  1. /**
  2. * 导出列表
  3. * @return
  4. */
  5. @RequestMapping(value = "/export", method = RequestMethod.GET)
  6. public String selectExport(@RequestParam(name = "name", required = false) String name,
  7. @RequestParam(value = "ids", required = false) String ids,
  8. HttpServletRequest request, HttpServletResponse response) {
  9. Map dataMap = new HashMap();
  10. dataMap.put("name", name);
  11. dataMap.put("ids", ids);
  12. return getResult(Result.OK,iProService.selectExportList(dataMap, request, response));
  13. }

如上述代码所示, @RequestMapping 中设置当前请求为 GET请求,方便前端调用,方法参数中使用 @RequetParam 设置入参名称,并使用 required=false 设置当前参数非必填。

底部的 getResult(***) 这个为我们当前项目封装的返回值方法,cmsPropertyModelService.selectExportCmsPropertyModelList 为处理当前导出任务的接口。

service层接口:

  1. /**
  2. * 导出列表
  3. * @return
  4. */
  5. public boolean selectExportList(Map dataMap, HttpServletRequest request, HttpServletResponse response);

讲了那么多,接下来是重点部分,导出接口的实现类,处理我们的业务逻辑和导出逻辑

单 sheet 导出 serviceImpl:

  1. /**
  2. * 导出列表
  3. *
  4. * @param dataMap
  5. * @param request
  6. * @param response
  7. * @return
  8. */
  9. @Override
  10. public boolean selectExportList(Map dataMap, HttpServletRequest request, HttpServletResponse response) {
  11. String ids = MapUtils.getString(dataMap, "ids");
  12. if (StringUtils.isNotEmpty(ids)) {
  13. dataMap.put("ids", ids.split(","));
  14. }
  15. //查询需要导出的数据
  16. List<CmsPropertyModel> cmsPropertyModelList = Mapper层数据库查询;
  17. //第一步:创建一个webbook,对应一个Excel文件
  18. HSSFWorkbook wb = new HSSFWorkbook();
  19. //第一步:创建单元格,并设置值表头 设置表头居中
  20. HSSFCellStyle style = wb.createCellStyle();
  21. style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
  22. //表头加粗
  23. HSSFFont titleFont = wb.createFont();
  24. titleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
  25. style.setFont(titleFont);
  26. //第三步:创建 sheet,并分别设置 标题
  27. HSSFSheet sheet1 = wb.createSheet("父级sheet");
  28. HSSFRow row1 = sheet1.createRow(0);
  29. String[] sheet1Title = {"名称", "备注"};
  30. //创建sheet1标题
  31. for (int i = 0 ; i < sheet1Title.length; i ++) {
  32. Cell cell = row1.createCell(i);
  33. cell.setCellStyle(style); //设置标题样式
  34. cell.setCellValue(sheet1Title[i]);
  35. sheet1.setColumnWidth(i, 10000); //设置列宽
  36. }
  37. //第四步:往sheet中设置值
  38. if (null != cmsPropertyModelList && cmsPropertyModelList.size() > 0) {
  39. for (int i = 0; i < cmsPropertyModelList.size(); i ++) {
  40. CmsPropertyModel cmsPropertyModel = cmsPropertyModelList.get(i);
  41. row1 = sheet1.createRow(sheet1.getLastRowNum() + 1); //获取当前行下一行
  42. row1.createCell(0).setCellValue(cmsPropertyModel.getName());
  43. row1.createCell(1).setCellValue(cmsPropertyModel.getDescription());
  44. }
  45. }
  46. //第五步:导出
  47. try {
  48. //excel文件名
  49. String fileName = "列表_" + DateFormatUtils.format(new Date(), "yyyyMMdd_HHmmss") + ".xls";
  50. //导出设置
  51. fileName = new String(fileName.getBytes(), "ISO8859-1");
  52. response.setContentType("application/octet-stream;charset=ISO8859-1");
  53. response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
  54. response.addHeader("Pargam", "no-cache");
  55. response.addHeader("Cache-Control", "no-cache");
  56. //开始导出
  57. OutputStream os = response.getOutputStream();
  58. wb.write(os);
  59. os.flush();
  60. os.close();
  61. } catch (Exception e) {
  62. e.printStackTrace();
  63. logger.error(">>> 导出列表发生异常!" + e.getMessage());
  64. }
  65. return true;
  66. }

以上就是单个 sheet 的excel导出,查询出数据后,开始创建 excel 对象等操作,里面首先设置sheet页标题,设置好后,通过循环我们数据库查询到的数据,一条一条一次追加,其中  sheet1.createRow(sheet1.getLastRowNum() + 1); 这句代码中的 sheet1.getLastRowNum() 是获取当前sheet 最新的一行,获取后 + 1 ,表示创建在当前最新一下后面创建一行,一次来保证行连续,且我们可以不用去管具体行号是多少,当然如果具体业务有需要,可以修改这个跟当前循环次数进行关联。

DateFormatUtils.java 是 apache commons-langs 公共包中的工具类,maven导包如下:
  1. <dependency>
  2. <groupId>org.apache.commons</groupId>
  3. <artifactId>commons-lang3</artifactId>
  4. <version>3.4</version>
  5. <scope>provided</scope>
  6. </dependency>

 以上就是单 sheet execl 导出过程,接下来是多个的,我这边用两个sheet来演示,其余的以此类推,我们的数据结构是父级中带有子集列表,如下所示:

  1. {
  2. "name":"父级名称",
  3. "description":"描述",
  4. "cmsPropertyList":[ //子集列表
  5. {
  6. "proName":"子集名称",
  7. ......
  8. ]
  9. }

大家每个人的实际业务需求不同,处理和实现的逻辑也会有不用,这里只是介绍一个我遇到的,应该是比较常见的场景,好了,不废话了,直接上代码。

多 sheet 导出 serviceImpl:

  1. /**
  2. * 导出列表
  3. *
  4. * @param dataMap
  5. * @param request
  6. * @param response
  7. * @return
  8. */
  9. @Override
  10. public boolean selectExportList(Map dataMap, HttpServletRequest request, HttpServletResponse response) {
  11. String ids = MapUtils.getString(dataMap, "ids");
  12. if (StringUtils.isNotEmpty(ids)) {
  13. dataMap.put("ids", ids.split(","));
  14. }
  15. //查询需要导出的数据
  16. List<CmsPropertyModel> cmsPropertyModelList = Mapper层数据库查询数据
  17. //第一步:创建一个webbook,对应一个Excel文件
  18. HSSFWorkbook wb = new HSSFWorkbook();
  19. //第一步:创建单元格,并设置值表头 设置表头居中
  20. HSSFCellStyle style = wb.createCellStyle();
  21. style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
  22. //表头加粗
  23. HSSFFont titleFont = wb.createFont();
  24. titleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
  25. style.setFont(titleFont);
  26. //第三步:分别创建 sheet,并分别设置 标题
  27. //创建sheet1
  28. HSSFSheet sheet1 = wb.createSheet("父级sheet");
  29. HSSFRow row1 = sheet1.createRow(0);
  30. String[] sheet1Title = {"名称", "备注"};
  31. //设置sheet1标题
  32. for (int i = 0 ; i < sheet1Title.length; i ++) {
  33. Cell cell = row1.createCell(i);
  34. cell.setCellStyle(style); //设置标题样式
  35. cell.setCellValue(sheet1Title[i]);
  36. sheet1.setColumnWidth(i, 10000); //设置列宽
  37. }
  38. //创建sheet1
  39. HSSFSheet sheet2 = wb.createSheet("子级sheet");
  40. HSSFRow row2 = sheet2.createRow(0);
  41. String[] sheet2Title = {"父级名称", "子集名称", ……};
  42. //设置sheet2标题
  43. for (int i = 0 ; i < sheet2Title.length; i ++) {
  44. Cell cell = row2.createCell(i);
  45. cell.setCellStyle(style); //设置标题样式
  46. cell.setCellValue(sheet2Title[i]);
  47. sheet2.setColumnWidth(i, 10000); //设置列宽
  48. }
  49. //第四步:往sheet中设置值
  50. if (null != cmsPropertyModelList && cmsPropertyModelList.size() > 0) {
  51. for (int i = 0; i < cmsPropertyModelList.size(); i ++) {
  52. CmsPropertyModel cmsPropertyModel = cmsPropertyModelList.get(i);
  53. //设置 sheet1 中的值
  54. row1 = sheet1.createRow(sheet1.getLastRowNum() + 1); //获取当前行下一行
  55. row1.createCell(0).setCellValue(cmsPropertyModel.getName()); //父级名称
  56. row1.createCell(1).setCellValue(cmsPropertyModel.getDescription()); //父级备注
  57. //设置 sheet2 中的值
  58. List<CmsProperty> cmsPropertyList = cmsPropertyModel.getCmsPropertyList();
  59. if (null != cmsPropertyList && cmsPropertyList.size() > 0) {
  60. for (int j = 0; j < cmsPropertyList.size(); j ++) {
  61. CmsProperty cmsProperty = cmsPropertyList.get(j);
  62. String proSeq = (null == cmsProperty.getProSeq()) ? "" : String.valueOf(cmsProperty.getProSeq());
  63. row2 = sheet2.createRow(sheet2.getLastRowNum() + 1); //获取sheet2当前行下一行
  64. row2.createCell(0).setCellValue(cmsProperty.getProModelName()); //子集名称
  65. ……………… 往 sheet2 当前行的单元格中设值 …………
  66. }
  67. }
  68. }
  69. }
  70. //第五步:导出
  71. try {
  72. //excel文件名
  73. String fileName = "列表_" + DateFormatUtils.format(new Date(), "yyyyMMdd_HHmmss") + ".xls";
  74. //导出设置
  75. fileName = new String(fileName.getBytes(), "ISO8859-1");
  76. response.setContentType("application/octet-stream;charset=ISO8859-1");
  77. response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
  78. response.addHeader("Pargam", "no-cache");
  79. response.addHeader("Cache-Control", "no-cache");
  80. //开始设置
  81. OutputStream os = response.getOutputStream();
  82. wb.write(os);
  83. os.flush();
  84. os.close();
  85. } catch (Exception e) {
  86. e.printStackTrace();
  87. logger.error(">>> 导出列表发生异常!" + e.getMessage());
  88. }
  89. return true;
  90. }

单个sheet 和多个 sheet 其实差别并不大,无非就是多创建一个 sheet,并进行设值而已。

需要声明的是:这只是简单的excel导出,适用于普通的导出,并没有涉及到过多的excel样式设置,如果项目中对excel样式有要求,可以在前面几步,创建 HSSFWork对象 和 创建单元格对象时进行设置,复杂的我也没有进行深入研究,后续如果有遇到,我们再进行拓展补充。

好了,以上就是本文的全部内容,我有个臭毛病,不是很擅长言语表达,动不动就是直接上代码,直来直去,码文字,权当记录和锻炼,如果觉得还可以,给个回复或给个赞,感谢。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/272944
推荐阅读
相关标签
  

闽ICP备14008679号