poi 多行合并

poi做多行合并,一定需要先绘制单元格,然后写入数据,最后合并,不然各种坑啊。

合并单元格所使用的方法:

sheet.addMergedRegion( CellRangeAddress  cellRangeAddress  );
 
CellRangeAddress  对象的构造方法需要传入合并单元格的首行、最后一行、首列、最后一列。
CellRangeAddress cra=new CellRangeAddress(0, 3, 3, 9);
 
怎样把数据写入合并后的单元格中
  1. 首先要查看你 CellRangeAddress 构造方法的firstcol index
  2. 创建firstcol cell对象
  3. cell 的set 方法写数据
在合并单元格的后一个位置写数据
  1. 查看  CellRangeAddress 构造方法的lastcol index     
  2. 创建lastcol+1  cell
  3. 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做多行合并,一定需要先绘制单元格,然后写入数据,最后合并,不然各种坑啊。

原文地址:https://www.cnblogs.com/huzi007/p/7656283.html