You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TestXSSFSheetRowGrouping.java 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.xssf.usermodel;
  16. import java.io.IOException;
  17. import junit.framework.TestCase;
  18. import org.apache.poi.ss.usermodel.Cell;
  19. import org.apache.poi.ss.usermodel.Row;
  20. import org.apache.poi.ss.usermodel.Sheet;
  21. import org.apache.poi.ss.usermodel.Workbook;
  22. import org.apache.poi.xssf.XSSFTestDataSamples;
  23. public final class TestXSSFSheetRowGrouping extends TestCase {
  24. private static final int ROWS_NUMBER = 200;
  25. private static final int GROUP_SIZE = 5;
  26. //private int o_groupsNumber = 0;
  27. public void test55640() throws IOException {
  28. //long startTime = System.currentTimeMillis();
  29. Workbook wb = new XSSFWorkbook();
  30. fillData(wb);
  31. writeToFile(wb);
  32. //System.out.println("Number of groups: " + o_groupsNumber);
  33. //System.out.println("Execution time: " + (System.currentTimeMillis()-startTime) + " ms");
  34. }
  35. private void fillData(Workbook p_wb) {
  36. Sheet sheet = p_wb.createSheet("sheet123");
  37. sheet.setRowSumsBelow(false);
  38. for (int i = 0; i < ROWS_NUMBER; i++) {
  39. Row row = sheet.createRow(i);
  40. Cell cell = row.createCell(0);
  41. cell.setCellValue(i+1);
  42. }
  43. int i = 1;
  44. while (i < ROWS_NUMBER) {
  45. int end = i+(GROUP_SIZE-2);
  46. int start = i; // natural order
  47. // int start = end - 1; // reverse order
  48. while (start < end) { // natural order
  49. // while (start >= i) { // reverse order
  50. sheet.groupRow(start, end);
  51. //o_groupsNumber++;
  52. boolean collapsed = isCollapsed();
  53. //System.out.println("Set group " + start + "->" + end + " to " + collapsed);
  54. sheet.setRowGroupCollapsed(start, collapsed);
  55. start++; // natural order
  56. // start--; // reverse order
  57. }
  58. i += GROUP_SIZE;
  59. }
  60. }
  61. private boolean isCollapsed() {
  62. return Math.random() > 0.5d;
  63. }
  64. private void writeToFile(Workbook p_wb) throws IOException {
  65. // FileOutputStream fileOut = new FileOutputStream("/tmp/55640.xlsx");
  66. // try {
  67. // p_wb.write(fileOut);
  68. // } finally {
  69. // fileOut.close();
  70. // }
  71. assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(p_wb));
  72. }
  73. public void test55640reduce1() throws IOException {
  74. Workbook wb = new XSSFWorkbook();
  75. Sheet sheet = wb.createSheet("sheet123");
  76. sheet.setRowSumsBelow(false);
  77. for (int i = 0; i < ROWS_NUMBER; i++) {
  78. Row row = sheet.createRow(i);
  79. Cell cell = row.createCell(0);
  80. cell.setCellValue(i+1);
  81. }
  82. int i = 1;
  83. while (i < ROWS_NUMBER) {
  84. int end = i+(GROUP_SIZE-2);
  85. int start = i; // natural order
  86. while (start < end) { // natural order
  87. sheet.groupRow(start, end);
  88. //o_groupsNumber++;
  89. boolean collapsed = start % 2 == 0 ? false : true;
  90. //System.out.println("Set group " + start + "->" + end + " to " + collapsed);
  91. sheet.setRowGroupCollapsed(start, collapsed);
  92. start++; // natural order
  93. }
  94. i += GROUP_SIZE;
  95. }
  96. writeToFile(wb);
  97. }
  98. public void test55640_VerifyCases() throws IOException {
  99. // NOTE: This is currently based on current behavior of POI, somehow
  100. // what POI returns in the calls to collapsed/hidden is not fully matching
  101. // the examples in the spec or I did not fully understand how POI stores the data internally...
  102. // all expanded
  103. verifyGroupCollapsed(
  104. // level1, level2, level3
  105. false, false, false,
  106. // collapsed:
  107. new Boolean[] { false, false, false, false, false},
  108. // hidden:
  109. new boolean[] { false, false, false, false, false},
  110. // outlineLevel
  111. new int[] { 1, 2, 3, 3, 3 }
  112. );
  113. // Level 1 collapsed, others expanded, should only have 4 rows, all hidden:
  114. verifyGroupCollapsed(
  115. // level1, level2, level3
  116. true, false, false,
  117. // collapsed:
  118. new Boolean[] { false, false, false, false, false},
  119. // hidden:
  120. new boolean[] { true, true, true, true, true},
  121. // outlineLevel
  122. new int[] { 1, 2, 3, 3, 3 }
  123. );
  124. // Level 1 and 2 collapsed, Level 3 expanded,
  125. verifyGroupCollapsed(
  126. // level1, level2, level3
  127. true, true, false,
  128. // collapsed:
  129. new Boolean[] { false, false, false, false, true, false},
  130. // hidden:
  131. new boolean[] { true, true, true, true, true, false},
  132. // outlineLevel
  133. new int[] { 1, 2, 3, 3, 3, 0 }
  134. );
  135. // Level 1 collapsed, Level 2 expanded, Level 3 collapsed
  136. verifyGroupCollapsed(
  137. // level1, level2, level3
  138. true, false, true,
  139. // collapsed:
  140. new Boolean[] { false, false, false, false, false, true},
  141. // hidden:
  142. new boolean[] { true, true, true, true, true, false},
  143. // outlineLevel
  144. new int[] { 1, 2, 3, 3, 3, 0 }
  145. );
  146. // Level 2 collapsed, others expanded:
  147. verifyGroupCollapsed(
  148. // level1, level2, level3
  149. false, true, false,
  150. // collapsed:
  151. new Boolean[] { false, false, false, false, false, false},
  152. // hidden:
  153. new boolean[] { false, true, true, true, true, false},
  154. // outlineLevel
  155. new int[] { 1, 2, 3, 3, 3, 0 }
  156. );
  157. // Level 3 collapsed, others expanded
  158. verifyGroupCollapsed(
  159. // level1, level2, level3
  160. false, false, true,
  161. // collapsed:
  162. new Boolean[] { false, false, false, false, false, true},
  163. // hidden:
  164. new boolean[] { false, false, true, true, true, false},
  165. // outlineLevel
  166. new int[] { 1, 2, 3, 3, 3, 0 }
  167. );
  168. // All collapsed
  169. verifyGroupCollapsed(
  170. // level1, level2, level3
  171. true, true, true,
  172. // collapsed:
  173. new Boolean[] { false, false, false, false, true, true},
  174. // hidden:
  175. new boolean[] { true, true, true, true, true, false},
  176. // outlineLevel
  177. new int[] { 1, 2, 3, 3, 3, 0 }
  178. );
  179. }
  180. private void verifyGroupCollapsed(boolean level1, boolean level2, boolean level3,
  181. Boolean[] collapsed, boolean[] hidden, int[] outlineLevel) throws IOException {
  182. Workbook wb = new XSSFWorkbook();
  183. Sheet sheet = wb.createSheet("sheet123");
  184. for (int i = 0; i < 4; i++) {
  185. sheet.createRow(i);
  186. }
  187. sheet.groupRow(0, 4);
  188. sheet.groupRow(1, 4);
  189. sheet.groupRow(2, 4);
  190. sheet.setRowGroupCollapsed(0, level1);
  191. sheet.setRowGroupCollapsed(1, level2);
  192. sheet.setRowGroupCollapsed(2, level3);
  193. checkWorkbookGrouping(wb, collapsed, hidden, outlineLevel);
  194. }
  195. public void test55640_VerifyCasesSpec() throws IOException {
  196. // NOTE: This is currently based on current behavior of POI, somehow
  197. // what POI returns in the calls to collapsed/hidden is not fully matching
  198. // the examples in the spec or I did not fully understand how POI stores the data internally...
  199. // all expanded
  200. verifyGroupCollapsedSpec(
  201. // level3, level2, level1
  202. false, false, false,
  203. // collapsed:
  204. new Boolean[] { false, false, false, false},
  205. // hidden:
  206. new boolean[] { false, false, false, false},
  207. // outlineLevel
  208. new int[] { 3, 3, 2, 1 }
  209. );
  210. verifyGroupCollapsedSpec(
  211. // level3, level2, level1
  212. false, false, true,
  213. // collapsed:
  214. new Boolean[] { false, false, false, true},
  215. // hidden:
  216. new boolean[] { true, true, true, false},
  217. // outlineLevel
  218. new int[] { 3, 3, 2, 1 }
  219. );
  220. verifyGroupCollapsedSpec(
  221. // level3, level2, level1
  222. false, true, false,
  223. // collapsed:
  224. new Boolean[] { false, false, true, false},
  225. // hidden:
  226. new boolean[] { true, true, true, false},
  227. // outlineLevel
  228. new int[] { 3, 3, 2, 1 }
  229. );
  230. verifyGroupCollapsedSpec(
  231. // level3, level2, level1
  232. false, true, true,
  233. // collapsed:
  234. new Boolean[] { false, false, true, true},
  235. // hidden:
  236. new boolean[] { true, true, true, false},
  237. // outlineLevel
  238. new int[] { 3, 3, 2, 1 }
  239. );
  240. }
  241. private void verifyGroupCollapsedSpec(boolean level1, boolean level2, boolean level3,
  242. Boolean[] collapsed, boolean[] hidden, int[] outlineLevel) throws IOException {
  243. Workbook wb = new XSSFWorkbook();
  244. Sheet sheet = wb.createSheet("sheet123");
  245. for (int i = 5; i < 9; i++) {
  246. sheet.createRow(i);
  247. }
  248. sheet.groupRow(5, 6);
  249. sheet.groupRow(5, 7);
  250. sheet.groupRow(5, 8);
  251. sheet.setRowGroupCollapsed(6, level1);
  252. sheet.setRowGroupCollapsed(7, level2);
  253. sheet.setRowGroupCollapsed(8, level3);
  254. checkWorkbookGrouping(wb, collapsed, hidden, outlineLevel);
  255. }
  256. private void checkWorkbookGrouping(Workbook wb, Boolean[] collapsed, boolean[] hidden, int[] outlineLevel) throws IOException {
  257. printWorkbook(wb);
  258. Sheet sheet = wb.getSheetAt(0);
  259. assertEquals(collapsed.length, hidden.length);
  260. assertEquals(collapsed.length, outlineLevel.length);
  261. assertEquals("Expected " + collapsed.length + " rows with collapsed state, but had " + (sheet.getLastRowNum()-sheet.getFirstRowNum()+1) + " rows ("
  262. + sheet.getFirstRowNum() + "-" + sheet.getLastRowNum() + ")",
  263. collapsed.length, sheet.getLastRowNum()-sheet.getFirstRowNum()+1);
  264. for(int i = sheet.getFirstRowNum(); i < sheet.getLastRowNum();i++) {
  265. if(collapsed[i-sheet.getFirstRowNum()] == null) {
  266. continue;
  267. }
  268. XSSFRow row = (XSSFRow) sheet.getRow(i);
  269. assertNotNull("Could not read row " + i, row);
  270. assertNotNull("Could not read row " + i, row.getCTRow());
  271. assertEquals("Row: " + i + ": collapsed", collapsed[i-sheet.getFirstRowNum()].booleanValue(), row.getCTRow().getCollapsed());
  272. assertEquals("Row: " + i + ": hidden", hidden[i-sheet.getFirstRowNum()], row.getCTRow().getHidden());
  273. assertEquals("Row: " + i + ": level", outlineLevel[i-sheet.getFirstRowNum()], row.getCTRow().getOutlineLevel());
  274. }
  275. writeToFile(wb);
  276. }
  277. public void test55640working() throws IOException {
  278. Workbook wb = new XSSFWorkbook();
  279. Sheet sheet = wb.createSheet("sheet123");
  280. sheet.groupRow(1, 4);
  281. sheet.groupRow(2, 5);
  282. sheet.groupRow(3, 6);
  283. sheet.setRowGroupCollapsed(1, true);
  284. sheet.setRowGroupCollapsed(2, false);
  285. sheet.setRowGroupCollapsed(3, false);
  286. writeToFile(wb);
  287. }
  288. // just used for printing out contents of spreadsheets
  289. public void notRuntest55640printSample() {
  290. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55640.xlsx");
  291. printWorkbook(wb);
  292. wb = XSSFTestDataSamples.openSampleWorkbook("GroupTest.xlsx");
  293. printWorkbook(wb);
  294. }
  295. private void printWorkbook(Workbook wb) {
  296. // disable all output for now...
  297. // Sheet sheet = wb.getSheetAt(0);
  298. //
  299. // for(Iterator<Row> it = sheet.rowIterator();it.hasNext();) {
  300. // XSSFRow row = (XSSFRow) it.next();
  301. // boolean collapsed = row.getCTRow().getCollapsed();
  302. // boolean hidden = row.getCTRow().getHidden();
  303. // short level = row.getCTRow().getOutlineLevel();
  304. //
  305. // System.out.println("Row: " + row.getRowNum() + ": Level: " + level + " Collapsed: " + collapsed + " Hidden: " + hidden);
  306. // }
  307. }
  308. public void testGroupingTest() throws IOException {
  309. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("GroupTest.xlsx");
  310. assertEquals(31, wb.getSheetAt(0).getLastRowNum());
  311. // NOTE: This is currently based on current behavior of POI, somehow
  312. // what POI returns in the calls to collapsed/hidden is not fully matching
  313. // the examples in the spec or I did not fully understand how POI stores the data internally...
  314. checkWorkbookGrouping(wb,
  315. new Boolean [] {
  316. // 0-4
  317. false, false, false, false, false, null, null,
  318. // 7-11
  319. false, false, true, true, true, null, null,
  320. // 14-18
  321. false, false, true, false, false, null,
  322. // 20-24
  323. false, false, true, true, false, null, null,
  324. // 27-31
  325. false, false, false, true, false },
  326. new boolean[] {
  327. // 0-4
  328. false, false, false, false, false, false, false,
  329. // 7-11
  330. true, true, true, true, false, false, false,
  331. // 14-18
  332. true, true, false, false, false, false,
  333. // 20-24
  334. true, true, true, false, false, false, false,
  335. // 27-31
  336. true, true, true, true, false },
  337. // outlineLevel
  338. new int[] {
  339. // 0-4
  340. 3, 3, 2, 1, 0, 0, 0,
  341. // 7-11
  342. 3, 3, 2, 1, 0, 0, 0,
  343. // 14-18
  344. 3, 3, 2, 1, 0, 0,
  345. // 20-24
  346. 3, 3, 2, 1, 0, 0, 0,
  347. // 27-31
  348. 3, 3, 2, 1, 0,
  349. }
  350. );
  351. /*
  352. Row: 0: Level: 3 Collapsed: false Hidden: false
  353. Row: 1: Level: 3 Collapsed: false Hidden: false
  354. Row: 2: Level: 2 Collapsed: false Hidden: false
  355. Row: 3: Level: 1 Collapsed: false Hidden: false
  356. Row: 4: Level: 0 Collapsed: false Hidden: false
  357. Row: 7: Level: 3 Collapsed: false Hidden: true
  358. Row: 8: Level: 3 Collapsed: false Hidden: true
  359. Row: 9: Level: 2 Collapsed: true Hidden: true
  360. Row: 10: Level: 1 Collapsed: true Hidden: true
  361. Row: 11: Level: 0 Collapsed: true Hidden: false
  362. Row: 14: Level: 3 Collapsed: false Hidden: true
  363. Row: 15: Level: 3 Collapsed: false Hidden: true
  364. Row: 16: Level: 2 Collapsed: true Hidden: false
  365. Row: 17: Level: 1 Collapsed: false Hidden: false
  366. Row: 18: Level: 0 Collapsed: false Hidden: false
  367. Row: 20: Level: 3 Collapsed: false Hidden: true
  368. Row: 21: Level: 3 Collapsed: false Hidden: true
  369. Row: 22: Level: 2 Collapsed: true Hidden: true
  370. Row: 23: Level: 1 Collapsed: true Hidden: false
  371. Row: 24: Level: 0 Collapsed: false Hidden: false
  372. Row: 27: Level: 3 Collapsed: false Hidden: true
  373. Row: 28: Level: 3 Collapsed: false Hidden: true
  374. Row: 29: Level: 2 Collapsed: false Hidden: true
  375. Row: 30: Level: 1 Collapsed: true Hidden: true
  376. Row: 31: Level: 0 Collapsed: true Hidden: false
  377. */
  378. }
  379. }