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做多行合并,一定需要先绘制单元格,然后写入数据,最后合并,不然各种坑啊。

poi 多行合并的更多相关文章

  1. Java利用poi生成word(包含插入图片,动态表格,行合并)

    转(小改): Java利用poi生成word(包含插入图片,动态表格,行合并) 2018年12月20日 09:06:51 wjw_11093010 阅读数:70 Java利用poi生成word(包含插 ...

  2. knockoutjs+jquery.gridgroup 实现table数据加载和行合并

    目标 使用ajax获取到json数据后,通过ko绑定到表格,然后通过jquery.gridgroup插件实现行合并,效果如下: 步骤 1.引入插件 <script src="~/Scr ...

  3. mysql 多行合并一列

    mysql  多行合并一列 使用的函数为: GROUP_CONCAT(exp) 其中exp 的参数类似如下: (field order  by field   desc  separator ';') ...

  4. Firebird 同一字段的多行合并为一行

    Firebird 同一字段的多行合并为一行用LIST函数类似于MYSQL的GROUP_CONCAT. 具体用法如下: SELECT  LIST(a.GG_NAME||':'||a.GG_VALUE) ...

  5. (转载)按行合并两个sql的查询结果

    (转载)http://blog.csdn.net/wxwstrue/article/details/6784774 Union all join 是平行合并 为水平连接 Union all 是垂直合并 ...

  6. Datagridview 实现二维表头和行合并【转载】

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; u ...

  7. JS行合并处理方法

    //行合并 function _w_table_rowspan(col){ _w_table_firsttd = ""; _w_table_currenttd = "&q ...

  8. SQL实现多行合并一行 .

    ORACLE纯SQL实现多行合并一行[转] 项目中遇到一个需求,需要将多行合并为一行.表结构如下:NAME                            Null           Type ...

  9. 小师妹问 easyUI mergeCells 行合并后表头和内容对不齐

    公司来了一个做easyUI的妹子,恰好那妹子是和我一个学校的,有一天下班妹子在超时买东西正好巧遇,然后妹子就问了问题,随便说手机卡需要我帮忙刷机,然后就问手机买了多久, 多少钱,刚买的时候好用不,然后 ...

随机推荐

  1. 国外物联网平台(7):FogHorn

    国外物联网平台(7) ——FogHorn 马智 引言: 据外媒在本月20日报道,硅谷初创公司FogHorn正在与谷歌合作以简化工业物联网应用的部署.本文对FogHorn的技术.产品.应用和生态进行了分 ...

  2. LSI SAS3008 RAID配置方法

    7.1  概述 LSI SAS3008 RAID 控制卡(以下简称LSI SAS3008)是基于Fusion-MPT™ (消息传递技术)架构的8端口12Gbit/s SAS控制器,并采用PCIe3.0 ...

  3. 死磕Java之聊聊LinkedList源码(基于JDK1.8)

    工作快一年了,近期打算研究一下JDK的源码,也就因此有了死磕java系列 LinkedList 是一个继承于AbstractSequentialList的双向链表,链表不需要capacity的设定,它 ...

  4. 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计

    类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...

  5. vs2015+opencv3.3.1 +Eigen 3.3.4 c++ 实现 泊松图像编辑(无缝融合)

    #define EIGEN_USE_MKL_ALL #define EIGEN_VECTORIZE_SSE4_2 #include <iostream> #include "co ...

  6. 基于Haar特征的Adaboost级联人脸检测分类器

    基于Haar特征的Adaboost级联人脸检测分类器基于Haar特征的Adaboost级联人脸检测分类器,简称haar分类器.通过这个算法的名字,我们可以看到这个算法其实包含了几个关键点:Haar特征 ...

  7. 【bzoj4720】[Noip2016]换教室 期望dp+最短路

    Description 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节 课程安排在n个时间段上.在第i(1≤i≤n)个时间段上,两节内容相同的 ...

  8. 题解 CF950B 【Intercepted Message】

    题目链接 先吐槽一番:本宝宝好久没写过题解了...首先我们想一个贪心策咯.就是我们预处理出前缀和,然后一边扫过去,记录一个l1,l2和一个n1,n2.分别表示我们现在第一个数组切到l1,上一次切是在n ...

  9. logging、hashlib、collections模块

    一.hashlib模块(加密模块) 1.什么叫hash:hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 , ...

  10. count distinct 组合使用

    SELECT COUNT(DISTINCT Lbox_Sn) FROM Tab_History_Info