poi做多行合并,一定需要先绘制单元格,然后写入数据,最后合并,不然各种坑啊。
合并单元格所使用的方法:
sheet.addMergedRegion( CellRangeAddress cellRangeAddress );
CellRangeAddress 对象的构造方法需要传入合并单元格的首行、最后一行、首列、最后一列。
CellRangeAddress cra=new CellRangeAddress(0, 3, 3, 9);
怎样把数据写入合并后的单元格中
- 首先要查看你 CellRangeAddress 构造方法的firstcol index
- 创建firstcol cell对象
- cell 的set 方法写数据
在合并单元格的后一个位置写数据
- 查看 CellRangeAddress 构造方法的lastcol index
- 创建lastcol+1 cell
- cell 的set方法写数据
附上一个例子:
public static void test() { String beginTime = "2017-10-08"; String endTime = "2017-10-11"; HSSFWorkbook wb = new HSSFWorkbook(); Date b = DateUtil.parse(beginTime, "yyyy-MM-dd"); Date e = DateUtil.parse(endTime, "yyyy-MM-dd"); String bs = DateUtil.format(b, "MM.dd"); String es = DateUtil.format(e, "MM.dd"); String sheetName = bs + "-" + es; HSSFSheet sheet = wb.createSheet(sheetName); HSSFRow row = sheet.createRow((short) 0);// 第一行 // 定制表头 List<String> header = new ArrayList<>(); header.add("部门"); header.add("岗位"); header.add("员工编号"); header.add("姓名"); header.add("服务中心名称"); header.add("时间段"); header.add("次数"); header.add("走访日期"); header.add("到店时段"); header.add("时长(分钟)"); HSSFCellStyle style = wb.createCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_LEFT);// 水平居中 style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中 style.setWrapText(true);// 自动换行 style.setIndention((short) 5);// 缩进 for (int i = 0; i < header.size(); i++) { HSSFCell cell = row.createCell(i); cell.setCellValue(header.get(i)); } // List<OaPunchVisitDataDto> // dtos=oaReportDao.findPunchVisitData(beginTime, endTime, departName, // name); List<OaPunchVisitDataDto> dtos = Lists.newArrayList(); OaPunchVisitDataDto dto = new OaPunchVisitDataDto(); dto.setNAMES("张三"); dto.setDEPARTNAME("开发部"); dto.setLOCATION_TITLE("五里店"); dto.setUSERID("10000"); dto.setPOSITION("员工"); dto.setCHECK_TIME("2017-10-09"); dto.setCHECK_ATS("2017-10-09 09:54,2017-10-09 17:54"); OaPunchVisitDataDto dto1 = new OaPunchVisitDataDto(); dto1.setNAMES("张三"); dto1.setDEPARTNAME("开发部"); dto1.setLOCATION_TITLE("五里店1"); dto1.setUSERID("10000"); dto1.setPOSITION("员工"); dto1.setCHECK_TIME("2017-10-10"); dto1.setCHECK_ATS("2017-10-10 09:54,2017-10-10 17:54"); OaPunchVisitDataDto dto3 = new OaPunchVisitDataDto(); dto3.setNAMES("张三2"); dto3.setDEPARTNAME("开发部"); dto3.setLOCATION_TITLE("五里店"); dto3.setUSERID("10001"); dto3.setPOSITION("员工"); dto3.setCHECK_TIME("2017-10-10,2017-10-11"); dto3.setCHECK_ATS("2017-10-10 09:54,2017-10-10 17:54,2017-10-11 09:54,2017-10-11 17:54"); OaPunchVisitDataDto dto5 = new OaPunchVisitDataDto(); dto5.setNAMES("张三2"); dto5.setDEPARTNAME("开发部"); dto5.setLOCATION_TITLE("五里店1"); dto5.setUSERID("10001"); dto5.setPOSITION("员工"); dto5.setCHECK_TIME("2017-10-08"); dto5.setCHECK_ATS("2017-10-08 09:54,2017-10-08 17:54"); dtos.add(dto); dtos.add(dto1); dtos.add(dto3); dtos.add(dto5); Multimap<String, OaPunchVisitDataDto> multimap = ArrayListMultimap.create(); Set<String> keySet = new HashSet<>(); for (OaPunchVisitDataDto data : dtos) { keySet.add(data.getUSERID()); multimap.put(data.getUSERID(), data); } // 数据行----合并数据最多行 if (keySet != null && keySet.size() > 0) { int i = 0; int temp = 0; for (String key : keySet) { int maxRow = 0; for (OaPunchVisitDataDto a : multimap.get(key)) { // 获取最大合并行数 if (a.getCHECK_TIME() != null) { maxRow += Arrays.asList(a.getCHECK_TIME().split(",")).size(); } } for (int c = 1 + temp; c < i + 1 + maxRow; c++) {// 4 hang HSSFRow rows = sheet.createRow(c);// for (int x = 0; x < header.size(); x++) { rows.createCell(x); logger.info("row:"+c+",cloum:"+x); System.out.println("row:"+c+",cloum:"+x); } } temp = i + maxRow; i = i + maxRow; } // 赋值 int xx = 0; int cloumcount5 = 0;// 第五列计数 int cloumcount7 = 0; for (String key : keySet) { int maxRow = 0; Multimap<String,OaPunchSiteDataTempDto> localtionsMap = ArrayListMultimap.create();//访问日期集合 Set<String> localtions = Sets.newHashSet();// 访问位置集合 for (OaPunchVisitDataDto a : multimap.get(key)) { // 获取最大合并行数 if (a.getCHECK_TIME() != null) { maxRow += Arrays.asList(a.getCHECK_TIME().split(",")).size(); } List<String> visitDates = Lists.newArrayList(); if (a.getCHECK_TIME() != null) { visitDates = Arrays.asList(a.getCHECK_TIME().split(",")); } OaPunchSiteDataTempDto tdto=new OaPunchSiteDataTempDto(); tdto.setDates(visitDates); tdto.setDatesAt(a.getCHECK_ATS()); // 用于确定第5列(服务中心)需要合并的行数 localtionsMap.put(a.getLOCATION_TITLE(), tdto); localtions.add(a.getLOCATION_TITLE()); } String departname = multimap.get(key).iterator().next().getDEPARTNAME() == null ? "" : multimap.get(key).iterator().next().getDEPARTNAME(); String position = multimap.get(key).iterator().next().getPOSITION() == null ? "" : multimap.get(key).iterator().next().getPOSITION(); String userid = key; String username = multimap.get(key).iterator().next().getNAMES() == null ? "" : multimap.get(key).iterator().next().getNAMES(); logger.info("xx+1:"+(xx+1)); HSSFCell cell0 = sheet.getRow(xx + 1).getCell(0); HSSFCell cell1 = sheet.getRow(xx + 1).getCell(1); HSSFCell cell2 = sheet.getRow(xx + 1).getCell(2); HSSFCell cell3 = sheet.getRow(xx + 1).getCell(3); cell0.setCellValue(departname); cell1.setCellValue(position); cell2.setCellValue(userid); cell3.setCellValue(username); cell0.setCellStyle(style); cell1.setCellStyle(style); cell2.setCellStyle(style); cell3.setCellStyle(style); /** * 合并前4列 */ System.out.println("xx+1:"+(xx+1)); System.out.println("xx + 1+maxRow:"+(xx + 1+maxRow)); /** * 合并前4列 */ sheet.addMergedRegion( new CellRangeAddress((xx + 1), (xx+maxRow), 0, 0) ); sheet.addMergedRegion( new CellRangeAddress((xx + 1), (xx+maxRow), 1, 1) ); sheet.addMergedRegion( new CellRangeAddress((xx + 1), (xx+maxRow), 2, 2) ); sheet.addMergedRegion( new CellRangeAddress((xx + 1), (xx+maxRow), 3, 3) ); for (String localtionKey : localtions) { int size = localtionsMap.get(localtionKey).iterator().next().getDates().size(); //第5列进行赋值 HSSFCell cell4 = sheet.getRow(cloumcount5 + 1).getCell(4); cell4.setCellValue(localtionKey); cell4.setCellStyle(style); //第6列进行赋值 HSSFCell cell5 = sheet.getRow(cloumcount5 + 1).getCell(5); cell5.setCellValue(beginTime+"--"+endTime); //cell5.setCellStyle(style); //第七列进行赋值 HSSFCell cell6 = sheet.getRow(cloumcount5 + 1).getCell(6); cell6.setCellValue(size); cell6.setCellStyle(style); /** * 合并5--7列数据 */ sheet.addMergedRegion( new CellRangeAddress(cloumcount5 + 1, cloumcount5+size, 4, 4) ); sheet.addMergedRegion( new CellRangeAddress(cloumcount5 + 1, cloumcount5+size, 5, 5) ); sheet.addMergedRegion( new CellRangeAddress(cloumcount5 + 1, cloumcount5+size, 6, 6) ); System.out.println("size:"+size); cloumcount5 = cloumcount5 + size; Iterator<OaPunchSiteDataTempDto> iterator = localtionsMap.get(localtionKey).iterator(); int m = 0; while (iterator.hasNext()) { OaPunchSiteDataTempDto po=iterator.next(); List<String> visitDates = po.getDates(); String[] visitDatesAts= po.getDatesAt().split(","); for (String visitDate : visitDates) { HSSFCell cell7 = sheet.getRow((m + 1 + cloumcount7)).getCell(7); cell7.setCellValue(visitDate); cell7.setCellStyle(style); Map<String, String> map=JayCommonUtil.getTimeAtAndMinByDate(visitDate, visitDatesAts); HSSFCell cell8 = sheet.getRow((m + 1 + cloumcount7)).getCell(8); cell8.setCellValue(map.get("timeAt")); cell8.setCellStyle(style); HSSFCell cell9 = sheet.getRow((m + 1 + cloumcount7)).getCell(9); cell9.setCellValue(map.get("min")); cell9.setCellStyle(style); m++; } } cloumcount7 = cloumcount7 + size; } xx = xx + maxRow; } sheet.setDefaultColumnWidth(20); FileOutputStream fileOut; try { fileOut = new FileOutputStream("f://workbook6.xls"); wb.write(fileOut); fileOut.close(); } catch (Exception e1) { e1.printStackTrace(); } System.out.print("OK"); } }
public class OaPunchVisitDataDto { private String DEPARTNAME; private String POSITION; private String USERID; private String NAMES; private String LOCATION_TITLE; private String CHECK_ATS; private String CHECK_TIME; public String getDEPARTNAME() { return DEPARTNAME; } public void setDEPARTNAME(String dEPARTNAME) { DEPARTNAME = dEPARTNAME; } public String getPOSITION() { return POSITION; } public void setPOSITION(String pOSITION) { POSITION = pOSITION; } public String getUSERID() { return USERID; } public void setUSERID(String uSERID) { USERID = uSERID; } public String getNAMES() { return NAMES; } public void setNAMES(String nAMES) { NAMES = nAMES; } public String getLOCATION_TITLE() { return LOCATION_TITLE; } public void setLOCATION_TITLE(String lOCATION_TITLE) { LOCATION_TITLE = lOCATION_TITLE; } public String getCHECK_ATS() { return CHECK_ATS; } public void setCHECK_ATS(String cHECK_ATS) { CHECK_ATS = cHECK_ATS; } public String getCHECK_TIME() { return CHECK_TIME; } public void setCHECK_TIME(String cHECK_TIME) { CHECK_TIME = cHECK_TIME; } }
poi做多行合并,一定需要先绘制单元格,然后写入数据,最后合并,不然各种坑啊。