最近碰到一个需求,后台有个台账导出的功能,以前所有数据都是导出到excel的一个sheet中集中显示的,这次的需求是要根据列表中的签单机构名称来分sheet导出,即签单机构相同的台账在同一个sheet中显示。把完成这个需求的核心代码去掉业务逻辑后就变成了下面这样的代码。需要说明的一点是,像这样的需求不可以真的是根据“名称”来分sheet导出的,你应该根据id这种不会重复的字段来作为分类依据,“名称”理论上是存在同名的可能性的。Talk is cheap, show you the code right now:
// 数字类型 List<String> numericList = null; /** * 根据原始列表中的TYPE字段分sheet导出(生成一个含有多个sheet的excel文件,相同TYPE值的条目对应一个sheet) * @param templetePath 模板文件地址(该模板文件第一个sheet里提供了要生成的excel文件表头部分的内容) * @param columns excel列表中要显示的各个列对应的名字 * @param statisticList 原始列表数据,每条里都含有一个TYPE字段 * @param worksheet 要输出的excel文件工作表名 * @param os 通过response.getOutputStream获得的东西 * @param cellSize 列数(比如32) */ public void helloMultipleSheetExport(String templetePath, String[] columns, List<Map<String, Object>> statisticList, String worksheet, OutputStream os, int cellSize) { // 新文件写入数据 File newFile = createNewFileByPath(templetePath); // 写入行的起始行. Long startRow = 4L; Long maxRows = 60000L; InputStream is = null; XSSFWorkbook workbook = null; XSSFSheet sheet = null; // 按TYPEID机构重新组织statisticList里的数据 Map<String, Boolean> backup = new HashMap<>(); List<List<Map<String, Object>>> typesList = new ArrayList<>(); for (Map<String, Object> item : statisticList) { Object oTypeId = item.get("TYPEID"); String sTypeId = (String) oTypeId; if (!backup.containsKey(orgName)) { List<Map<String, Object>> ordersByCurType = new ArrayList<>(); for (Map<String, Object> order : statisticList) { if (order.get("TYPE").equals(oTypeId)) { ordersByCurType.add(order); } } typesList.add(ordersByCurType); backup.put(sTypeId, true); } } try { // 将excel文件转为输入流 is = new FileInputStream(newFile); // 创建一个workbook workbook = new XSSFWorkbook(is); // 清空workbook中的所有sheet(除了模板excel中的第一个sheet,里面有表头内容,需要拷贝到其他sheet中) for (int i = workbook.getNumberOfSheets(); i > 1; i--) { workbook.removeSheetAt(i - 1); } // 复制第一个sheet的表头 int numOfOrgs = typesList.size(); for (int n = 1; n < numOfOrgs; n++) { workbook.cloneSheet(0); } // 每个TYPEID单独一个sheet for (int n = 0; n < numOfOrgs; n++) { List<Map<String, Object>> ordersByCurType = typesList.get(n); sheet = workbook.getSheetAt(n); workbook.setSheetName(n, ordersByCurType.get(0).get("TYPENAME").toString()); int rowSize = ordersByCurType.size(); for (int m = 0; m < rowSize; m++) { Map<String, Object> map = ordersByCurType.get(m); XSSFRow row = sheet.createRow(m + startRow.intValue()); for (int i = 0; i < cellSize; i++) { String column = columns[i]; if (StringUtils.isBlank(column)) { continue; } String value = map.get(column) + ""; if(!"null".equals(value) && StringUtils.isNotBlank(value)){ setCellDataType(cell, column, value); }else{ cell.setCellValue(""); } } } } workbook.write(os); } catch (Exception e) { e.printStackTrace(); logger.error("数据导出失败!失败原因为:" + e.getMessage()); } finally { try { if (null != is) { is.close(); } // 删除生成的临时文件 newFile.delete(); } catch (Exception e) { e.printStackTrace(); } } } private void setCellDataType(Cell cell,String columnName,String value) { if (CollectionUtils.isEmpty(numericList)) { numericList = new ArrayList<>(); numericList.add("VC2BIPREMIUM"); numericList.add("VC2CIPREMIUM"); numericList.add("VC2TAX"); numericList.add("VC2TOTALPRICE"); numericList.add("VC2PAYPRICE"); numericList.add("VC2TRANSAMOUNT"); numericList.add("VC2ADVANCE"); numericList.add("VC2CMISCASH"); } if (StringUtils.isNotBlank(columnName) && numericList.contains(columnName)) { cell.setCellValue(Double.parseDouble(value)); } else { cell.setCellValue(value); } } /** * 根据excel模板文件创建要下载的文件 * @param sysPath excel模板文件路径 * @return 文件 */ public File createNewFileByPath(String sysPath) { // 文件模板路径 String path = sysPath + "xls/hello.xls"; File file = new File(path); // 保存文件的路径 String realPath = (sysPath + "xls/temp"); // 新的文件名 String newFileName = "hello" + System.currentTimeMillis() + ".xlsx"; // 判断路径是否存在 File dir = new File(realPath); if (!dir.exists()) { dir.mkdirs(); } // 写入到新的excel File newFile = new File(realPath, newFileName); try { newFile.createNewFile(); // 复制模板到新文件 fileChannelCopy(file, newFile); } catch (Exception e) { e.printStackTrace(); } return newFile; } private void setCellDataType(Cell cell, String columnName, String value) { if (CollectionUtils.isEmpty(numericList)) { numericList = new ArrayList<>(); numericList.add("COLUMNNAME1"); numericList.add("COLUMNNAME2"); numericList.add("COLUMNNAME3"); numericList.add("COLUMNNAME4"); numericList.add("COLUMNNAME5"); numericList.add("COLUMNNAME6"); numericList.add("COLUMNNAME7"); numericList.add("COLUMNNAME8"); } if (StringUtils.isNotBlank(columnName) && numericList.contains(columnName)) { cell.setCellValue(Double.parseDouble(value)); }else{ cell.setCellValue(value); } }