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方法写数据

附上一个例子:

  1. public static void test() {
  2. String beginTime = "2017-10-08";
  3. String endTime = "2017-10-11";
  4. HSSFWorkbook wb = new HSSFWorkbook();
  5. Date b = DateUtil.parse(beginTime, "yyyy-MM-dd");
  6. Date e = DateUtil.parse(endTime, "yyyy-MM-dd");
  7. String bs = DateUtil.format(b, "MM.dd");
  8. String es = DateUtil.format(e, "MM.dd");
  9. String sheetName = bs + "-" + es;
  10. HSSFSheet sheet = wb.createSheet(sheetName);
  11.  
  12. HSSFRow row = sheet.createRow((short) 0);// 第一行
  13. // 定制表头
  14. List<String> header = new ArrayList<>();
  15. header.add("部门");
  16. header.add("岗位");
  17. header.add("员工编号");
  18. header.add("姓名");
  19. header.add("服务中心名称");
  20. header.add("时间段");
  21. header.add("次数");
  22. header.add("走访日期");
  23. header.add("到店时段");
  24. header.add("时长(分钟)");
  25.  
  26. HSSFCellStyle style = wb.createCellStyle();
  27. style.setAlignment(HSSFCellStyle.ALIGN_LEFT);// 水平居中
  28. style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
  29. style.setWrapText(true);// 自动换行
  30. style.setIndention((short) 5);// 缩进
  31.  
  32. for (int i = 0; i < header.size(); i++) {
  33. HSSFCell cell = row.createCell(i);
  34. cell.setCellValue(header.get(i));
  35. }
  36.  
  37. // List<OaPunchVisitDataDto>
  38. // dtos=oaReportDao.findPunchVisitData(beginTime, endTime, departName,
  39. // name);
  40. List<OaPunchVisitDataDto> dtos = Lists.newArrayList();
  41. OaPunchVisitDataDto dto = new OaPunchVisitDataDto();
  42. dto.setNAMES("张三");
  43. dto.setDEPARTNAME("开发部");
  44. dto.setLOCATION_TITLE("五里店");
  45. dto.setUSERID("10000");
  46. dto.setPOSITION("员工");
  47. dto.setCHECK_TIME("2017-10-09");
  48. dto.setCHECK_ATS("2017-10-09 09:54,2017-10-09 17:54");
  49. OaPunchVisitDataDto dto1 = new OaPunchVisitDataDto();
  50. dto1.setNAMES("张三");
  51. dto1.setDEPARTNAME("开发部");
  52. dto1.setLOCATION_TITLE("五里店1");
  53. dto1.setUSERID("10000");
  54. dto1.setPOSITION("员工");
  55. dto1.setCHECK_TIME("2017-10-10");
  56. dto1.setCHECK_ATS("2017-10-10 09:54,2017-10-10 17:54");
  57.  
  58. OaPunchVisitDataDto dto3 = new OaPunchVisitDataDto();
  59. dto3.setNAMES("张三2");
  60. dto3.setDEPARTNAME("开发部");
  61. dto3.setLOCATION_TITLE("五里店");
  62. dto3.setUSERID("10001");
  63. dto3.setPOSITION("员工");
  64. dto3.setCHECK_TIME("2017-10-10,2017-10-11");
  65. dto3.setCHECK_ATS("2017-10-10 09:54,2017-10-10 17:54,2017-10-11 09:54,2017-10-11 17:54");
  66.  
  67. OaPunchVisitDataDto dto5 = new OaPunchVisitDataDto();
  68. dto5.setNAMES("张三2");
  69. dto5.setDEPARTNAME("开发部");
  70. dto5.setLOCATION_TITLE("五里店1");
  71. dto5.setUSERID("10001");
  72. dto5.setPOSITION("员工");
  73. dto5.setCHECK_TIME("2017-10-08");
  74. dto5.setCHECK_ATS("2017-10-08 09:54,2017-10-08 17:54");
  75.  
  76. dtos.add(dto);
  77. dtos.add(dto1);
  78. dtos.add(dto3);
  79. dtos.add(dto5);
  80.  
  81. Multimap<String, OaPunchVisitDataDto> multimap = ArrayListMultimap.create();
  82. Set<String> keySet = new HashSet<>();
  83. for (OaPunchVisitDataDto data : dtos) {
  84. keySet.add(data.getUSERID());
  85. multimap.put(data.getUSERID(), data);
  86.  
  87. }
  88.  
  89. // 数据行----合并数据最多行
  90. if (keySet != null && keySet.size() > 0) {
  91. int i = 0;
  92. int temp = 0;
  93. for (String key : keySet) {
  94. int maxRow = 0;
  95. for (OaPunchVisitDataDto a : multimap.get(key)) {
  96. // 获取最大合并行数
  97. if (a.getCHECK_TIME() != null) {
  98. maxRow += Arrays.asList(a.getCHECK_TIME().split(",")).size();
  99. }
  100. }
  101.  
  102. for (int c = 1 + temp; c < i + 1 + maxRow; c++) {// 4 hang
  103. HSSFRow rows = sheet.createRow(c);//
  104. for (int x = 0; x < header.size(); x++) {
  105. rows.createCell(x);
  106. logger.info("row:"+c+",cloum:"+x);
  107. System.out.println("row:"+c+",cloum:"+x);
  108. }
  109.  
  110. }
  111. temp = i + maxRow;
  112. i = i + maxRow;
  113. }
  114.  
  115. // 赋值
  116. int xx = 0;
  117. int cloumcount5 = 0;// 第五列计数
  118. int cloumcount7 = 0;
  119. for (String key : keySet) {
  120. int maxRow = 0;
  121. Multimap<String,OaPunchSiteDataTempDto> localtionsMap = ArrayListMultimap.create();//访问日期集合
  122. Set<String> localtions = Sets.newHashSet();// 访问位置集合
  123. for (OaPunchVisitDataDto a : multimap.get(key)) {
  124. // 获取最大合并行数
  125. if (a.getCHECK_TIME() != null) {
  126. maxRow += Arrays.asList(a.getCHECK_TIME().split(",")).size();
  127.  
  128. }
  129. List<String> visitDates = Lists.newArrayList();
  130. if (a.getCHECK_TIME() != null) {
  131. visitDates = Arrays.asList(a.getCHECK_TIME().split(","));
  132. }
  133. OaPunchSiteDataTempDto tdto=new OaPunchSiteDataTempDto();
  134. tdto.setDates(visitDates);
  135. tdto.setDatesAt(a.getCHECK_ATS());
  136. // 用于确定第5列(服务中心)需要合并的行数
  137. localtionsMap.put(a.getLOCATION_TITLE(), tdto);
  138. localtions.add(a.getLOCATION_TITLE());
  139. }
  140. String departname = multimap.get(key).iterator().next().getDEPARTNAME() == null ? ""
  141. : multimap.get(key).iterator().next().getDEPARTNAME();
  142. String position = multimap.get(key).iterator().next().getPOSITION() == null ? ""
  143. : multimap.get(key).iterator().next().getPOSITION();
  144. String userid = key;
  145. String username = multimap.get(key).iterator().next().getNAMES() == null ? ""
  146. : multimap.get(key).iterator().next().getNAMES();
  147.  
  148. logger.info("xx+1:"+(xx+1));
  149. HSSFCell cell0 = sheet.getRow(xx + 1).getCell(0);
  150. HSSFCell cell1 = sheet.getRow(xx + 1).getCell(1);
  151. HSSFCell cell2 = sheet.getRow(xx + 1).getCell(2);
  152. HSSFCell cell3 = sheet.getRow(xx + 1).getCell(3);
  153.  
  154. cell0.setCellValue(departname);
  155. cell1.setCellValue(position);
  156. cell2.setCellValue(userid);
  157. cell3.setCellValue(username);
  158. cell0.setCellStyle(style);
  159. cell1.setCellStyle(style);
  160. cell2.setCellStyle(style);
  161. cell3.setCellStyle(style);
  162.  
  163. /**
  164. * 合并前4列
  165. */
  166. System.out.println("xx+1:"+(xx+1));
  167. System.out.println("xx + 1+maxRow:"+(xx + 1+maxRow));
  168. /**
  169. * 合并前4列
  170. */
  171. sheet.addMergedRegion( new CellRangeAddress((xx + 1), (xx+maxRow), 0, 0) );
  172.  
  173. sheet.addMergedRegion( new CellRangeAddress((xx + 1), (xx+maxRow), 1, 1) );
  174. sheet.addMergedRegion( new CellRangeAddress((xx + 1), (xx+maxRow), 2, 2) );
  175. sheet.addMergedRegion( new CellRangeAddress((xx + 1), (xx+maxRow), 3, 3) );
  176.  
  177. for (String localtionKey : localtions) {
  178.  
  179. int size = localtionsMap.get(localtionKey).iterator().next().getDates().size();
  180.  
  181. //第5列进行赋值
  182. HSSFCell cell4 = sheet.getRow(cloumcount5 + 1).getCell(4);
  183. cell4.setCellValue(localtionKey);
  184. cell4.setCellStyle(style);
  185. //第6列进行赋值
  186. HSSFCell cell5 = sheet.getRow(cloumcount5 + 1).getCell(5);
  187. cell5.setCellValue(beginTime+"--"+endTime);
  188. //cell5.setCellStyle(style);
  189. //第七列进行赋值
  190. HSSFCell cell6 = sheet.getRow(cloumcount5 + 1).getCell(6);
  191. cell6.setCellValue(size);
  192. cell6.setCellStyle(style);
  193.  
  194. /**
  195. * 合并5--7列数据
  196. */
  197. sheet.addMergedRegion( new CellRangeAddress(cloumcount5 + 1, cloumcount5+size, 4, 4) );
  198. sheet.addMergedRegion( new CellRangeAddress(cloumcount5 + 1, cloumcount5+size, 5, 5) );
  199. sheet.addMergedRegion( new CellRangeAddress(cloumcount5 + 1, cloumcount5+size, 6, 6) );
  200.  
  201. System.out.println("size:"+size);
  202. cloumcount5 = cloumcount5 + size;
  203.  
  204. Iterator<OaPunchSiteDataTempDto> iterator = localtionsMap.get(localtionKey).iterator();
  205. int m = 0;
  206. while (iterator.hasNext()) {
  207. OaPunchSiteDataTempDto po=iterator.next();
  208. List<String> visitDates = po.getDates();
  209. String[] visitDatesAts= po.getDatesAt().split(",");
  210. for (String visitDate : visitDates) {
  211. HSSFCell cell7 = sheet.getRow((m + 1 + cloumcount7)).getCell(7);
  212. cell7.setCellValue(visitDate);
  213. cell7.setCellStyle(style);
  214.  
  215. Map<String, String> map=JayCommonUtil.getTimeAtAndMinByDate(visitDate, visitDatesAts);
  216.  
  217. HSSFCell cell8 = sheet.getRow((m + 1 + cloumcount7)).getCell(8);
  218. cell8.setCellValue(map.get("timeAt"));
  219. cell8.setCellStyle(style);
  220.  
  221. HSSFCell cell9 = sheet.getRow((m + 1 + cloumcount7)).getCell(9);
  222. cell9.setCellValue(map.get("min"));
  223. cell9.setCellStyle(style);
  224.  
  225. m++;
  226. }
  227.  
  228. }
  229.  
  230. cloumcount7 = cloumcount7 + size;
  231. }
  232. xx = xx + maxRow;
  233.  
  234. }
  235.  
  236. sheet.setDefaultColumnWidth(20);
  237.  
  238. FileOutputStream fileOut;
  239. try {
  240. fileOut = new FileOutputStream("f://workbook6.xls");
  241. wb.write(fileOut);
  242. fileOut.close();
  243. } catch (Exception e1) {
  244. e1.printStackTrace();
  245. }
  246. System.out.print("OK");
  247. }
  248.  
  249. }
  1. public class OaPunchVisitDataDto {
  2.  
  3. private String DEPARTNAME;
  4.  
  5. private String POSITION;
  6.  
  7. private String USERID;
  8.  
  9. private String NAMES;
  10.  
  11. private String LOCATION_TITLE;
  12.  
  13. private String CHECK_ATS;
  14.  
  15. private String CHECK_TIME;
  16.  
  17. public String getDEPARTNAME() {
  18. return DEPARTNAME;
  19. }
  20.  
  21. public void setDEPARTNAME(String dEPARTNAME) {
  22. DEPARTNAME = dEPARTNAME;
  23. }
  24.  
  25. public String getPOSITION() {
  26. return POSITION;
  27. }
  28.  
  29. public void setPOSITION(String pOSITION) {
  30. POSITION = pOSITION;
  31. }
  32.  
  33. public String getUSERID() {
  34. return USERID;
  35. }
  36.  
  37. public void setUSERID(String uSERID) {
  38. USERID = uSERID;
  39. }
  40.  
  41. public String getNAMES() {
  42. return NAMES;
  43. }
  44.  
  45. public void setNAMES(String nAMES) {
  46. NAMES = nAMES;
  47. }
  48.  
  49. public String getLOCATION_TITLE() {
  50. return LOCATION_TITLE;
  51. }
  52.  
  53. public void setLOCATION_TITLE(String lOCATION_TITLE) {
  54. LOCATION_TITLE = lOCATION_TITLE;
  55. }
  56.  
  57. public String getCHECK_ATS() {
  58. return CHECK_ATS;
  59. }
  60.  
  61. public void setCHECK_ATS(String cHECK_ATS) {
  62. CHECK_ATS = cHECK_ATS;
  63. }
  64.  
  65. public String getCHECK_TIME() {
  66. return CHECK_TIME;
  67. }
  68.  
  69. public void setCHECK_TIME(String cHECK_TIME) {
  70. CHECK_TIME = cHECK_TIME;
  71. }
  72.  
  73. }

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. Asp.net负载均衡之Session

    在WEB场中,动态网页往往会因为几台主机做了负载而产生SESSION丢失的问题,网上也有很多的介绍,我这里只将我经历的过程给大家分享一下: 系统要运行在负载平衡的 Web 场环境中,而系统配置文件we ...

  2. 个人JS体系整理(三)

    一. 严格模式 JavaScript 严格模式(strict mode)即在严格的条件下运行.首先声明,严格模式是ES5中提出来的,准确来说就是一句指令Use strict,它的目的是指定代码在严格条 ...

  3. Size Assertion

    Size Assertion每一个响应包含的字节大小,可以设置大小等于,大于,小于,不等于给定的字节数. Apply to:应用范围,一般勾选Main samle only即可. Response S ...

  4. xp/win7中系统安装memcached服务,卸载memcached服务,以及删除memcached服务

    1.安装到系统服务中: 在doc中:执行此软件 memcached.exe -d install(如果提示错误,要找到cmd.exe用管理员身份打开) 2.卸载: 在doc中:执行此软件 memcac ...

  5. 【转】winform回车变为tab

    源地址:http://www.cnblogs.com/wohexiaocai/p/4302200.html

  6. 【转】C# String 与 Char[] 数组 相互转换

    源地址:http://blog.csdn.net/razilfelix/article/details/52289663 string 转换成 Char[] string ss = "abc ...

  7. vmware vSphere虚拟网络(一)

    为了更好的了解vSphere网络虚拟化解决方案,这里引入了一些概念,以便我们更好的了解虚拟网络. 一.网卡: 物理网卡称为vmnic,在ESXi中,第一块物理网卡叫做vmnic0,第二块叫做vmnic ...

  8. sublime text3文本字体大小设置

    1.perferences->settings-user 4·将以下代码粘贴进入即可 { "font_face": "source code pro, " ...

  9. Andriod ListView组件的使用

    1.介绍 总结:ListView 是一个可以以垂直滚动的方式展示条目内容的一个列表,条目的内容来自于ListAdapter(适配器). 2.操作步骤 3.内存溢出问题(快速拖到条目) 利用getVie ...

  10. 洛谷 [TJOI2010]中位数

    题目链接 题解 比较水.. 常见套路,维护两个堆 Code #include<bits/stdc++.h> #define LL long long #define RG register ...