你的位置:首页 > 软件开发 > Java > 使用POI导出Excel

使用POI导出Excel

发布时间:2017-11-09 23:00:32
先分享几个链接:(POI的中文API,别人总结的拿来用特别方便)    https://www.cnblogs.com/fqfanqi/p/6172223.html 我在项目中做这个功能的时候,其实项目中是有现成代码的,本来我以为我只需要修改一下,后来看过 ...

先分享几个链接:(POI的中文API,别人总结的拿来用特别方便)

      

  https://www.cnblogs.com/fqfanqi/p/6172223.html

 

我在项目中做这个功能的时候,其实项目中是有现成代码的,本来我以为我只需要修改一下,后来看过代码才发现和我要的不一样,于是只能重写一个。

 

导出功能:

  1、在action层拿到要导出的数据  --  results

  2、同样在action层拿到要导出数据的字段集,即列   --  exportFields

    解释一下,一般我们在获取数据的时候,往往会把一些表中的冗余字段或者一些我不需要的字段也获取了,我们不可能也把它们导出来。其实这个字段集,就是我们在Excel表中要显示的列。在现成的功能中支持在页面选择要导出的字段,而我的导出功能不支持选择,导出的字段是写死的。

  3、拿到导出时一张表中存多少条数据  --  rowNum

    在现成的功能中还支持这个由用户选,就是导出到一张表,要太多条数据,然后我们根据这个值去划分数据,比如这个值是5000,然后我们就每5000条数据新建一个工作表,再继续存放数据。我的功能……这个值同样写死的。

  4、调用Service层方法,传入上面的参数和HttpServletResponse 。传哪些参数大家随意,当然  results是肯定不能少的。

  5、在Service层写方法,接受刚才的四个参数

 1  @Override 2  public void createExcelWorkBookInfo(HttpServletResponse response, List<BaseAlumni> results, String exportFields, 3    Integer rowNum) { 4   String nowStr = new Date().getTime() + ""; 5   //这个out我还不太了解就不给你们说了,大致意思就是导出动作吧 6   OutputStream out = null; 7   try { 8    out = response.getOutputStream(); 9    response.reset();10    //设置表名11    response.setHeader("content-disposition",12      "attachment;filename=" + new String(("校友信息" + nowStr).getBytes("gb2312"), "ISO8859-1") + ".xls");13    response.setContentType("APPLICATION/msexcel");14    //创建Excel表15    HSSFWorkbook workbook = new HSSFWorkbook();16    //调用导出方法17    excelSrv.export(results, exportFields, workbook, rowNum);18    workbook.write(out);19   } catch (IOException e) {20    e.printStackTrace();21   } finally {22    try {23     // 强行将响应缓存中的内容发送到目的地24     response.flushBuffer();25     if (out != null) {26      out.flush();27      out.close();28     }29    } catch (IOException e) {30     LOGGER.error(e);31    }32   }33  }

  5、写export方法,在现成的方法中,封装好了一个方法,行,列的生成都是通过foreach,很高大上。在这里,我先附上我写的,后面再附上现成的,给自己做一个对比。

 1  @Override 2  public void alumniBranchExport(List<BaseAlumniBranch> results, Map<String, String> fildsMap, HSSFWorkbook wb) { 3   //因为之前没有传,所以在这写死,这个功能大家不想要也是可以的 -- rowMaxNum = 10000 4   Integer rowNum = rowMaxNum; 5   for (int i = 0; i < results.size(); i += rowNum) { 6    List<BaseAlumniBranch> newlist = new ArrayList<>(); 7    if ((i + rowNum) < results.size()) { 8     //数据的截取 9     newlist = results.subList(i, i + rowNum);10    } else {11     newlist = results.subList(i, results.size());12    }13    //创建工作表14    HSSFSheet sheet = wb.createSheet();15    for (int j = 0; j < fildsMap.size(); j++) {16     //设置列宽,第一个参数是列,第二个参数是宽值17     sheet.setColumnWidth(i, 5000);18    }19    //填充表头20    this.fillClubExcelHeader(wb, sheet, fildsMap);21    //填充内容22    this.fillClubExcelBody(newlist, sheet, wb, fildsMap);23   }24  }

6、其实现成的代码和我这个是差不多一样的,不一样的地方就是在填充的那两个方法里面

  这是现成的header填充:

 1  private void fillCommonHeader(HSSFWorkbook wb, HSSFSheet sheet, Map<String, String> fildsMap) { 2   //创建样式 3   HSSFCellStyle style = wb.createCellStyle(); 4   style.setAlignment(HSSFCellStyle.ALIGN_CENTER); 5   //字体的颜色,大小 6   HSSFFont font = wb.createFont(); 7   font.setColor(HSSFColor.BLACK.index); 8   font.setFontHeightInPoints((short) 18); 9   style.setFont(font);10   //创建第一行,从0开始,参数是第几行的索引,第一行是011   HSSFRow row = sheet.createRow(0);12   //在这里说一下,foreach是拿不到index的,这里在外面声明一个i,在表示第几列13   int i = 0;14   //循环传过来的字段集15   for (String key : fildsMap.keySet()) {16    //创建一个单元格,创建完后i自增117    HSSFCell cell = row.createCell(i++);18    String value = fildsMap.get(key);19    //给单元格赋值20    cell.setCellValue(value);21    //给单元格设置样式22    cell.setCellStyle(style);23   }24   //在这里有一个顺序的问题,我也是用传参的方式,但是我的fildsMap的顺序就是乱了,我又不会调,尴尬25  }

  这是我的header填充:

 1  private void fillClubExcelHeader(HSSFWorkbook wb, HSSFSheet sheet, Map<String, String> fildsMap) { 2   HSSFCellStyle style = wb.createCellStyle(); 3   style.setAlignment(HSSFCellStyle.ALIGN_CENTER); 4   HSSFFont font = wb.createFont(); 5   font.setColor(HSSFColor.BLACK.index); 6   font.setFontHeightInPoints((short) 18); 7   style.setFont(font); 8   // 创建第一行 9   HSSFRow row = sheet.createRow(0);10   // 创建第一列11   HSSFCell cell = row.createCell(0);12   // 赋值13   cell.setCellValue(fildsMap.get("clubName"));14   cell.setCellStyle(style);15   // 创建第二列,在这里不能再出现HSSFCell声明,为什么……我也是一知半解,就不说了16   cell = row.createCell(1);17   cell.setCellValue(fildsMap.get("clubWechatId"));18   cell.setCellStyle(style);19   // 创建第三列……20   cell = row.createCell(2);21   cell.setCellValue(fildsMap.get("clubAddress"));22   cell.setCellStyle(style);23   cell = row.createCell(3);24   cell.setCellValue(fildsMap.get("clubEmail"));25   cell.setCellStyle(style);26   cell = row.createCell(4);27   cell.setCellValue(fildsMap.get("clubEstablishedTime"));28   cell.setCellStyle(style);29   cell = row.createCell(5);30   cell.setCellValue(fildsMap.get("name"));31   cell.setCellStyle(style);32   cell = row.createCell(6);33   cell.setCellValue(fildsMap.get("staff"));34   cell.setCellStyle(style);35   cell = row.createCell(7);36   cell.setCellValue(fildsMap.get("phone"));37   cell.setCellStyle(style);38   cell = row.createCell(8);39   cell.setCellValue(fildsMap.get("email"));40   cell.setCellStyle(style);41  }

  这是现成的body填充:

 1  private <T> void fillCommonBody(List<T> results, HSSFSheet sheet, HSSFWorkbook wb, Map<String, String> fildsMap) { 2   HSSFCellStyle style = wb.createCellStyle(); 3   style.setAlignment(HSSFCellStyle.ALIGN_CENTER); 4   HSSFFont font = wb.createFont(); 5   font.setColor(HSSFColor.BLACK.index); 6   font.setFontHeightInPoints((short) 16); 7   style.setFont(font); 8   int i = 1; 9   for (T inst : results) {10    HSSFRow row = sheet.createRow(i++);11    row.setRowStyle(style);12    int j = 0;13    for (String key : fildsMap.keySet()) {14     HSSFCell cell = row.createCell(j++);15     String val = setCell(key, inst); //在里我这差点被骗了,也不知道是谁命名的,还以为单元格带有的get,set方法16     cell.setCellValue(val);17    }18   }19  }

  这个方法主要是写如何从results中拿值的,我看了半天没看懂

 1  @SuppressWarnings("rawtypes") 2  private <T> String setCell(String field, T data) { 3   String val = ""; 4  5   Class clazz = data.getClass(); 6   Field[] fields = ArrayUtils.addAll(clazz.getDeclaredFields(), clazz.getSuperclass().getDeclaredFields()); 7   for (int i = 0; i < fields.length; i++) { 8    if (fields[i].getName().equals(field)) { 9     try {10      Object resultObject = invokeMethod(data, fields[i].getName(), null);11      if (resultObject == null) {12       resultObject = "";13      }14      val = resultObject.toString();15      break;16     } catch (SecurityException | NoSuchMethodException | IllegalArgumentException | IllegalAccessException17       | InvocationTargetException e) {18      e.printStackTrace();19     }20    }21   }22 23   return val;24  }

  我的body方法:

 1  private <T> void fillClubExcelBody(List<BaseAlumniBranch> results, HSSFSheet sheet, HSSFWorkbook wb, 2    Map<String, String> fildsMap) { 3   HSSFCellStyle style = wb.createCellStyle(); 4   style.setAlignment(HSSFCellStyle.ALIGN_CENTER); 5   HSSFFont font = wb.createFont(); 6   font.setColor(HSSFColor.BLACK.index); 7   font.setFontHeightInPoints((short) 16); 8   style.setFont(font); 9   int k = 1;10   if (results.size() < 2 || "null".equals(results.size())) {11    LOGGER.error("alumniBranchExport but results is empty !");12    return;13   }14   for (int i = 0; i < results.size(); i++) {15    BaseAlumniBranch inst = results.get(i);16    if (inst.getStaffList().size() < 1 || "null".equals(inst.getStaffList().size())) {17     HSSFRow row = sheet.createRow(k++);18     row.setRowStyle(style);19     HSSFCell cell = row.createCell(0);20     cell.setCellValue(inst.getName());21     cell.setCellStyle(style);22     cell = row.createCell(1);23     cell.setCellValue(inst.getWechatId());24     cell.setCellStyle(style);25     cell = row.createCell(2);26     cell.setCellValue(inst.getAddress());27     cell.setCellStyle(style);28     cell = row.createCell(3);29     cell.setCellValue(inst.getEmail());30     cell.setCellStyle(style);31     cell = row.createCell(4);32     cell.setCellValue(inst.getEstablishedTime());33     cell.setCellStyle(style);34     cell = row.createCell(5);35     cell.setCellValue("");36     cell.setCellStyle(style);37     cell = row.createCell(6);38     cell.setCellValue("");39     cell.setCellStyle(style);40     cell = row.createCell(7);41     cell.setCellValue("");42     cell.setCellStyle(style);43     cell = row.createCell(8);44     cell.setCellValue("");45     cell.setCellStyle(style);46    } else {47     for (int j = 0; j < inst.getStaffList().size(); j++) {48      HSSFRow row = sheet.createRow(k++);49      row.setRowStyle(style);50      HSSFCell cell = row.createCell(0);51      cell.setCellValue(inst.getName());52      cell.setCellStyle(style);53      cell = row.createCell(1);54      cell.setCellValue(inst.getWechatId());55      cell.setCellStyle(style);56      cell = row.createCell(2);57      cell.setCellValue(inst.getAddress());58      cell.setCellStyle(style);59      cell = row.createCell(3);60      cell.setCellValue(inst.getEmail());61      cell.setCellStyle(style);62      cell = row.createCell(4);63      cell.setCellValue(inst.getEstablishedTime());64      cell.setCellStyle(style);65      cell = row.createCell(5);66      cell.setCellValue(inst.getStaffList().get(j).getName());67      cell.setCellStyle(style);68      cell = row.createCell(6);69      cell.setCellValue(inst.getStaffList().get(j).getStaff());70      cell.setCellStyle(style);71      cell = row.createCell(7);72      cell.setCellValue(inst.getStaffList().get(j).getPhone());73      cell.setCellStyle(style);74      cell = row.createCell(8);75      cell.setCellValue(inst.getStaffList().get(j).getEmail());76      cell.setCellStyle(style);77     }78     for (int column = 0; column < 5; column++) {79      mergeCell(sheet, k - inst.getStaffList().size(), k - 1, column, column);80     }81 82    }83   }84  }

  7、我在方法的最后做了合并单元格,这是在原方法上改不动的,所以我必须再写一个方法。

    传的参数中,从左到右:工作表名,起始行,结束行,起始列,结束行

    就是要合并单元格,合并从哪行开始到哪行,从哪列开始到哪列

1  public void mergeCell(HSSFSheet sheet, int rolStart, int rolEnd, int cowStart, int cowEnd) {2   CellRangeAddress region = new CellRangeAddress(rolStart, rolEnd, cowStart, cowEnd);3   sheet.addMergedRegion(region);4  }

  8、到此,导出结束。

  9、过程中碰到的坎坷:

    Excel表我声明了两次,导致到后来导出的内容是没有行的,如图:(要注意,不止是表,行,列也不能重复,否则就会出错)

  使用POI导出Excel

 

  10、最后的成功:

使用POI导出Excel

 

原标题:使用POI导出Excel

关键词:excel

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录