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.

TestXSSFColGrouping.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  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 static org.junit.jupiter.api.Assertions.assertEquals;
  17. import static org.junit.jupiter.api.Assertions.assertFalse;
  18. import static org.junit.jupiter.api.Assertions.assertTrue;
  19. import java.io.IOException;
  20. import org.apache.logging.log4j.LogManager;
  21. import org.apache.logging.log4j.Logger;
  22. import org.apache.poi.xssf.XSSFTestDataSamples;
  23. import org.junit.jupiter.api.Test;
  24. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
  25. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
  26. /**
  27. * Test asserts the POI produces <cols> element that could be read and properly interpreted by the MS Excel.
  28. * For specification of the "cols" element see the chapter 3.3.1.16 of the "Office Open XML Part 4 - Markup Language Reference.pdf".
  29. * The specification can be downloaded at https://www.ecma-international.org/publications/files/ECMA-ST/Office%20Open%20XML%201st%20edition%20Part%204%20(PDF).zip.
  30. *
  31. * <p><em>
  32. * The test saves xlsx file on a disk if the system property is set:
  33. * -Dpoi.test.xssf.output.dir=${workspace_loc}/poi/build/xssf-output
  34. * </em>
  35. *
  36. */
  37. class TestXSSFColGrouping {
  38. private static final Logger LOG = LogManager.getLogger(TestXSSFColGrouping.class);
  39. /**
  40. * Tests that POI doesn't produce "col" elements without "width" attribute.
  41. * POI-52186
  42. */
  43. @Test
  44. void testNoColsWithoutWidthWhenGrouping() throws IOException {
  45. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  46. XSSFSheet sheet = wb1.createSheet("test");
  47. sheet.setColumnWidth(4, 5000);
  48. sheet.setColumnWidth(5, 5000);
  49. sheet.groupColumn((short) 4, (short) 7);
  50. sheet.groupColumn((short) 9, (short) 12);
  51. try (XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testNoColsWithoutWidthWhenGrouping")) {
  52. sheet = wb2.getSheet("test");
  53. CTCols cols = sheet.getCTWorksheet().getColsArray(0);
  54. LOG.atDebug().log("test52186/cols:{}", cols);
  55. for (CTCol col : cols.getColArray()) {
  56. assertTrue(col.isSetWidth(), "Col width attribute is unset: " + col);
  57. }
  58. }
  59. }
  60. }
  61. /**
  62. * Tests that POI doesn't produce "col" elements without "width" attribute.
  63. * POI-52186
  64. */
  65. @Test
  66. void testNoColsWithoutWidthWhenGroupingAndCollapsing() throws IOException {
  67. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  68. XSSFSheet sheet = wb1.createSheet("test");
  69. sheet.setColumnWidth(4, 5000);
  70. sheet.setColumnWidth(5, 5000);
  71. sheet.groupColumn((short) 4, (short) 5);
  72. sheet.setColumnGroupCollapsed(4, true);
  73. CTCols cols = sheet.getCTWorksheet().getColsArray(0);
  74. LOG.atDebug().log("test52186_2/cols:{}", cols);
  75. try (XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testNoColsWithoutWidthWhenGroupingAndCollapsing")) {
  76. sheet = wb2.getSheet("test");
  77. for (int i = 4; i <= 5; i++) {
  78. assertEquals(5000, sheet.getColumnWidth(i), "Unexpected width of column " + i);
  79. }
  80. cols = sheet.getCTWorksheet().getColsArray(0);
  81. for (CTCol col : cols.getColArray()) {
  82. assertTrue(col.isSetWidth(), "Col width attribute is unset: " + col);
  83. }
  84. }
  85. }
  86. }
  87. /**
  88. * Test the cols element is correct in case of NumericRanges.OVERLAPS_2_WRAPS
  89. */
  90. @Test
  91. void testMergingOverlappingCols_OVERLAPS_2_WRAPS() throws IOException {
  92. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  93. XSSFSheet sheet = wb1.createSheet("test");
  94. CTCols cols = sheet.getCTWorksheet().getColsArray(0);
  95. CTCol col = cols.addNewCol();
  96. col.setMin(1 + 1);
  97. col.setMax(4 + 1);
  98. col.setWidth(20);
  99. col.setCustomWidth(true);
  100. sheet.groupColumn((short) 2, (short) 3);
  101. sheet.getCTWorksheet().getColsArray(0);
  102. LOG.atDebug().log("testMergingOverlappingCols_OVERLAPS_2_WRAPS/cols:{}", cols);
  103. assertEquals(0, cols.getColArray(0).getOutlineLevel());
  104. assertEquals(2, cols.getColArray(0).getMin()); // 1 based
  105. assertEquals(2, cols.getColArray(0).getMax()); // 1 based
  106. assertTrue(cols.getColArray(0).getCustomWidth());
  107. assertEquals(1, cols.getColArray(1).getOutlineLevel());
  108. assertEquals(3, cols.getColArray(1).getMin()); // 1 based
  109. assertEquals(4, cols.getColArray(1).getMax()); // 1 based
  110. assertTrue(cols.getColArray(1).getCustomWidth());
  111. assertEquals(0, cols.getColArray(2).getOutlineLevel());
  112. assertEquals(5, cols.getColArray(2).getMin()); // 1 based
  113. assertEquals(5, cols.getColArray(2).getMax()); // 1 based
  114. assertTrue(cols.getColArray(2).getCustomWidth());
  115. assertEquals(3, cols.sizeOfColArray());
  116. try (XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_2_WRAPS")) {
  117. sheet = wb2.getSheet("test");
  118. for (int i = 1; i <= 4; i++) {
  119. assertEquals(20 * 256, sheet.getColumnWidth(i), "Unexpected width of column " + i);
  120. }
  121. }
  122. }
  123. }
  124. /**
  125. * Test the cols element is correct in case of NumericRanges.OVERLAPS_1_WRAPS
  126. */
  127. @Test
  128. void testMergingOverlappingCols_OVERLAPS_1_WRAPS() throws IOException {
  129. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  130. XSSFSheet sheet = wb1.createSheet("test");
  131. CTCols cols = sheet.getCTWorksheet().getColsArray(0);
  132. CTCol col = cols.addNewCol();
  133. col.setMin(2 + 1);
  134. col.setMax(4 + 1);
  135. col.setWidth(20);
  136. col.setCustomWidth(true);
  137. sheet.groupColumn((short) 1, (short) 5);
  138. cols = sheet.getCTWorksheet().getColsArray(0);
  139. LOG.atDebug().log("testMergingOverlappingCols_OVERLAPS_1_WRAPS/cols:{}", cols);
  140. assertEquals(1, cols.getColArray(0).getOutlineLevel());
  141. assertEquals(2, cols.getColArray(0).getMin()); // 1 based
  142. assertEquals(2, cols.getColArray(0).getMax()); // 1 based
  143. assertFalse(cols.getColArray(0).getCustomWidth());
  144. assertEquals(1, cols.getColArray(1).getOutlineLevel());
  145. assertEquals(3, cols.getColArray(1).getMin()); // 1 based
  146. assertEquals(5, cols.getColArray(1).getMax()); // 1 based
  147. assertTrue(cols.getColArray(1).getCustomWidth());
  148. assertEquals(1, cols.getColArray(2).getOutlineLevel());
  149. assertEquals(6, cols.getColArray(2).getMin()); // 1 based
  150. assertEquals(6, cols.getColArray(2).getMax()); // 1 based
  151. assertFalse(cols.getColArray(2).getCustomWidth());
  152. assertEquals(3, cols.sizeOfColArray());
  153. try (XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_1_WRAPS")) {
  154. sheet = wb2.getSheet("test");
  155. for (int i = 2; i <= 4; i++) {
  156. assertEquals(20 * 256, sheet.getColumnWidth(i), "Unexpected width of column " + i);
  157. }
  158. }
  159. }
  160. }
  161. /**
  162. * Test the cols element is correct in case of NumericRanges.OVERLAPS_1_MINOR
  163. */
  164. @Test
  165. void testMergingOverlappingCols_OVERLAPS_1_MINOR() throws IOException {
  166. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  167. XSSFSheet sheet = wb1.createSheet("test");
  168. CTCols cols = sheet.getCTWorksheet().getColsArray(0);
  169. CTCol col = cols.addNewCol();
  170. col.setMin(2 + 1);
  171. col.setMax(4 + 1);
  172. col.setWidth(20);
  173. col.setCustomWidth(true);
  174. sheet.groupColumn((short) 3, (short) 5);
  175. cols = sheet.getCTWorksheet().getColsArray(0);
  176. LOG.atDebug().log("testMergingOverlappingCols_OVERLAPS_1_MINOR/cols:{}", cols);
  177. assertEquals(0, cols.getColArray(0).getOutlineLevel());
  178. assertEquals(3, cols.getColArray(0).getMin()); // 1 based
  179. assertEquals(3, cols.getColArray(0).getMax()); // 1 based
  180. assertTrue(cols.getColArray(0).getCustomWidth());
  181. assertEquals(1, cols.getColArray(1).getOutlineLevel());
  182. assertEquals(4, cols.getColArray(1).getMin()); // 1 based
  183. assertEquals(5, cols.getColArray(1).getMax()); // 1 based
  184. assertTrue(cols.getColArray(1).getCustomWidth());
  185. assertEquals(1, cols.getColArray(2).getOutlineLevel());
  186. assertEquals(6, cols.getColArray(2).getMin()); // 1 based
  187. assertEquals(6, cols.getColArray(2).getMax()); // 1 based
  188. assertFalse(cols.getColArray(2).getCustomWidth());
  189. assertEquals(3, cols.sizeOfColArray());
  190. try (XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_1_MINOR")) {
  191. sheet = wb2.getSheet("test");
  192. for (int i = 2; i <= 4; i++) {
  193. assertEquals(20 * 256L, sheet.getColumnWidth(i), "Unexpected width of column " + i);
  194. }
  195. assertEquals(sheet.getDefaultColumnWidth() * 256L, sheet.getColumnWidth(5), "Unexpected width of column " + 5);
  196. }
  197. }
  198. }
  199. /**
  200. * Test the cols element is correct in case of NumericRanges.OVERLAPS_2_MINOR
  201. */
  202. @Test
  203. void testMergingOverlappingCols_OVERLAPS_2_MINOR() throws IOException {
  204. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  205. XSSFSheet sheet = wb1.createSheet("test");
  206. CTCols cols = sheet.getCTWorksheet().getColsArray(0);
  207. CTCol col = cols.addNewCol();
  208. col.setMin(2 + 1);
  209. col.setMax(4 + 1);
  210. col.setWidth(20);
  211. col.setCustomWidth(true);
  212. sheet.groupColumn((short) 1, (short) 3);
  213. cols = sheet.getCTWorksheet().getColsArray(0);
  214. LOG.atDebug().log("testMergingOverlappingCols_OVERLAPS_2_MINOR/cols:{}", cols);
  215. assertEquals(1, cols.getColArray(0).getOutlineLevel());
  216. assertEquals(2, cols.getColArray(0).getMin()); // 1 based
  217. assertEquals(2, cols.getColArray(0).getMax()); // 1 based
  218. assertFalse(cols.getColArray(0).getCustomWidth());
  219. assertEquals(1, cols.getColArray(1).getOutlineLevel());
  220. assertEquals(3, cols.getColArray(1).getMin()); // 1 based
  221. assertEquals(4, cols.getColArray(1).getMax()); // 1 based
  222. assertTrue(cols.getColArray(1).getCustomWidth());
  223. assertEquals(0, cols.getColArray(2).getOutlineLevel());
  224. assertEquals(5, cols.getColArray(2).getMin()); // 1 based
  225. assertEquals(5, cols.getColArray(2).getMax()); // 1 based
  226. assertTrue(cols.getColArray(2).getCustomWidth());
  227. assertEquals(3, cols.sizeOfColArray());
  228. try (XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_2_MINOR")) {
  229. sheet = wb2.getSheet("test");
  230. for (int i = 2; i <= 4; i++) {
  231. assertEquals(20 * 256L, sheet.getColumnWidth(i), "Unexpected width of column " + i);
  232. }
  233. assertEquals(sheet.getDefaultColumnWidth() * 256L, sheet.getColumnWidth(1), "Unexpected width of column " + 1);
  234. }
  235. }
  236. }
  237. }