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.

BaseTestSheetShiftColumns.java 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /*
  2. * ====================================================================
  3. * Licensed to the Apache Software Foundation (ASF) under one or more
  4. * contributor license agreements. See the NOTICE file distributed with
  5. * this work for additional information regarding copyright ownership.
  6. * The ASF licenses this file to You under the Apache License, Version 2.0
  7. * (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. * ====================================================================
  18. */
  19. package org.apache.poi.ss.usermodel;
  20. import static org.junit.Assert.assertEquals;
  21. import static org.junit.Assert.assertNotNull;
  22. import static org.junit.Assert.assertNull;
  23. import static org.junit.Assert.assertTrue;
  24. import java.io.IOException;
  25. import org.apache.poi.common.usermodel.HyperlinkType;
  26. import org.apache.poi.ss.ITestDataProvider;
  27. import org.apache.poi.ss.util.CellAddress;
  28. import org.apache.poi.ss.util.CellRangeAddress;
  29. import org.apache.poi.ss.util.CellUtil;
  30. import org.junit.Before;
  31. import org.junit.Test;
  32. public abstract class BaseTestSheetShiftColumns {
  33. protected Sheet sheet1;
  34. protected Sheet sheet2;
  35. protected Workbook workbook;
  36. protected ITestDataProvider _testDataProvider;
  37. @Before
  38. public void init() {
  39. int rowIndex = 0;
  40. sheet1 = workbook.createSheet("sheet1");
  41. Row row = sheet1.createRow(rowIndex++);
  42. row.createCell(0, CellType.NUMERIC).setCellValue(0);
  43. row.createCell(1, CellType.NUMERIC).setCellValue(1);
  44. row.createCell(2, CellType.NUMERIC).setCellValue(2);
  45. row = sheet1.createRow(rowIndex++);
  46. row.createCell(0, CellType.NUMERIC).setCellValue(0.1);
  47. row.createCell(1, CellType.NUMERIC).setCellValue(1.1);
  48. row.createCell(2, CellType.NUMERIC).setCellValue(2.1);
  49. row = sheet1.createRow(rowIndex++);
  50. row.createCell(0, CellType.NUMERIC).setCellValue(0.2);
  51. row.createCell(1, CellType.NUMERIC).setCellValue(1.2);
  52. row.createCell(2, CellType.NUMERIC).setCellValue(2.2);
  53. row = sheet1.createRow(rowIndex++);
  54. row.createCell(0, CellType.FORMULA).setCellFormula("A2*B3");
  55. row.createCell(1, CellType.NUMERIC).setCellValue(1.3);
  56. row.createCell(2, CellType.FORMULA).setCellFormula("B1-B3");
  57. row = sheet1.createRow(rowIndex++);
  58. row.createCell(0, CellType.FORMULA).setCellFormula("SUM(C1:C4)");
  59. row.createCell(1, CellType.FORMULA).setCellFormula("SUM(A3:C3)");
  60. row.createCell(2, CellType.FORMULA).setCellFormula("$C1+C$2");
  61. row = sheet1.createRow(rowIndex++);
  62. row.createCell(1, CellType.NUMERIC).setCellValue(1.5);
  63. row = sheet1.createRow(rowIndex);
  64. row.createCell(1, CellType.BOOLEAN).setCellValue(false);
  65. Cell textCell = row.createCell(2, CellType.STRING);
  66. textCell.setCellValue("TEXT");
  67. textCell.setCellStyle(newCenterBottomStyle());
  68. sheet2 = workbook.createSheet("sheet2");
  69. row = sheet2.createRow(0); row.createCell(0, CellType.NUMERIC).setCellValue(10);
  70. row.createCell(1, CellType.NUMERIC).setCellValue(11);
  71. row.createCell(2, CellType.FORMULA).setCellFormula("SUM(sheet1!B3:C3)");
  72. row = sheet2.createRow(1);
  73. row.createCell(0, CellType.NUMERIC).setCellValue(21);
  74. row.createCell(1, CellType.NUMERIC).setCellValue(22);
  75. row.createCell(2, CellType.NUMERIC).setCellValue(23);
  76. row = sheet2.createRow(2);
  77. row.createCell(0, CellType.FORMULA).setCellFormula("sheet1!A4+sheet1!C2+A2");
  78. row.createCell(1, CellType.FORMULA).setCellFormula("SUM(sheet1!A3:$C3)");
  79. row = sheet2.createRow(3);
  80. row.createCell(0, CellType.STRING).setCellValue("dummy");
  81. }
  82. private CellStyle newCenterBottomStyle() {
  83. CellStyle style = workbook.createCellStyle();
  84. style.setAlignment(HorizontalAlignment.CENTER);
  85. style.setVerticalAlignment(VerticalAlignment.BOTTOM);
  86. return style;
  87. }
  88. @Test
  89. public void testShiftOneColumnRight() {
  90. sheet1.shiftColumns(1, 2, 1);
  91. double c1Value = sheet1.getRow(0).getCell(2).getNumericCellValue();
  92. assertEquals(1d, c1Value, 0.01);
  93. String formulaA4 = sheet1.getRow(3).getCell(0).getCellFormula();
  94. assertEquals("A2*C3", formulaA4);
  95. String formulaC4 = sheet1.getRow(3).getCell(3).getCellFormula();
  96. assertEquals("C1-C3", formulaC4);
  97. String formulaB5 = sheet1.getRow(4).getCell(2).getCellFormula();
  98. assertEquals("SUM(A3:D3)", formulaB5);
  99. String formulaD5 = sheet1.getRow(4).getCell(3).getCellFormula(); // $C1+C$2
  100. assertEquals("$D1+D$2", formulaD5);
  101. Cell newb5Null = sheet1.getRow(4).getCell(1);
  102. assertEquals(newb5Null, null);
  103. boolean logicalValue = sheet1.getRow(6).getCell(2).getBooleanCellValue();
  104. assertEquals(logicalValue, false);
  105. Cell textCell = sheet1.getRow(6).getCell(3);
  106. assertEquals(textCell.getStringCellValue(), "TEXT");
  107. assertEquals(textCell.getCellStyle().getAlignment(), HorizontalAlignment.CENTER);
  108. // other sheet
  109. String formulaC1 = sheet2.getRow(0).getCell(2).getCellFormula(); // SUM(sheet1!B3:C3)
  110. assertEquals("SUM(sheet1!C3:D3)", formulaC1);
  111. String formulaA3 = sheet2.getRow(2).getCell(0).getCellFormula(); // sheet1!A4+sheet1!C2+A2
  112. assertEquals("sheet1!A4+sheet1!D2+A2", formulaA3);
  113. }
  114. @Test
  115. public void testShiftTwoColumnsRight() {
  116. sheet1.shiftColumns(1, 2, 2);
  117. String formulaA4 = sheet1.getRow(3).getCell(0).getCellFormula();
  118. assertEquals("A2*D3", formulaA4);
  119. String formulaD4 = sheet1.getRow(3).getCell(4).getCellFormula();
  120. assertEquals("D1-D3", formulaD4);
  121. String formulaD5 = sheet1.getRow(4).getCell(3).getCellFormula();
  122. assertEquals("SUM(A3:E3)", formulaD5);
  123. Cell b5Null = sheet1.getRow(4).getCell(1);
  124. assertEquals(b5Null, null);
  125. Object c6Null = sheet1.getRow(5).getCell(2); // null cell A5 is shifted
  126. // for 2 columns, so now
  127. // c5 should be null
  128. assertEquals(c6Null, null);
  129. }
  130. @Test
  131. public void testShiftOneColumnLeft() {
  132. sheet1.shiftColumns(1, 2, -1);
  133. String formulaA5 = sheet1.getRow(4).getCell(0).getCellFormula();
  134. assertEquals("SUM(A3:B3)", formulaA5);
  135. String formulaB4 = sheet1.getRow(3).getCell(1).getCellFormula();
  136. assertEquals("A1-A3", formulaB4);
  137. String formulaB5 = sheet1.getRow(4).getCell(1).getCellFormula();
  138. assertEquals("$B1+B$2", formulaB5);
  139. Cell newb6Null = sheet1.getRow(5).getCell(1);
  140. assertEquals(newb6Null, null);
  141. }
  142. @Test(expected = IllegalStateException.class)
  143. public void testShiftTwoColumnsLeft() {
  144. sheet1.shiftColumns(1, 2, -2);
  145. }
  146. @Test
  147. public void testShiftHyperlinks() throws IOException {
  148. Workbook wb = _testDataProvider.createWorkbook();
  149. Sheet sheet = wb.createSheet("test");
  150. Row row = sheet.createRow(0);
  151. // How to create hyperlinks
  152. // https://poi.apache.org/spreadsheet/quick-guide.html#Hyperlinks
  153. CreationHelper helper = wb.getCreationHelper();
  154. CellStyle hlinkStyle = wb.createCellStyle();
  155. Font hlinkFont = wb.createFont();
  156. hlinkFont.setUnderline(Font.U_SINGLE);
  157. hlinkFont.setColor(IndexedColors.BLUE.getIndex());
  158. hlinkStyle.setFont(hlinkFont);
  159. // 3D relative document link
  160. // CellAddress=A1, shifted to A4
  161. Cell cell = row.createCell(0);
  162. cell.setCellStyle(hlinkStyle);
  163. createHyperlink(helper, cell, HyperlinkType.DOCUMENT, "test!E1");
  164. // URL
  165. cell = row.createCell(1);
  166. // CellAddress=B1, shifted to B4
  167. cell.setCellStyle(hlinkStyle);
  168. createHyperlink(helper, cell, HyperlinkType.URL, "http://poi.apache.org/");
  169. // row0 will be shifted on top of row1, so this URL should be removed
  170. // from the workbook
  171. Row overwrittenRow = sheet.createRow(3);
  172. cell = overwrittenRow.createCell(2);
  173. // CellAddress=C4, will be overwritten (deleted)
  174. cell.setCellStyle(hlinkStyle);
  175. createHyperlink(helper, cell, HyperlinkType.EMAIL, "mailto:poi@apache.org");
  176. Row unaffectedRow = sheet.createRow(20);
  177. cell = unaffectedRow.createCell(3);
  178. // CellAddress=D21, will be unaffected
  179. cell.setCellStyle(hlinkStyle);
  180. createHyperlink(helper, cell, HyperlinkType.FILE, "54524.xlsx");
  181. cell = wb.createSheet("other").createRow(0).createCell(0);
  182. // CellAddress=Other!A1, will be unaffected
  183. cell.setCellStyle(hlinkStyle);
  184. createHyperlink(helper, cell, HyperlinkType.URL, "http://apache.org/");
  185. int startRow = 0;
  186. int endRow = 4;
  187. int n = 3;
  188. sheet.shiftColumns(startRow, endRow, n);
  189. Workbook read = _testDataProvider.writeOutAndReadBack(wb);
  190. wb.close();
  191. Sheet sh = read.getSheet("test");
  192. Row shiftedRow = sh.getRow(0);
  193. // document link anchored on a shifted cell should be moved
  194. // Note that hyperlinks do not track what they point to, so this
  195. // hyperlink should still refer to test!E1
  196. verifyHyperlink(shiftedRow.getCell(3), HyperlinkType.DOCUMENT, "test!E1");
  197. // URL, EMAIL, and FILE links anchored on a shifted cell should be moved
  198. verifyHyperlink(shiftedRow.getCell(4), HyperlinkType.URL, "http://poi.apache.org/");
  199. // Make sure hyperlinks were moved and not copied
  200. assertNull("Document hyperlink should be moved, not copied", sh.getHyperlink(0, 0));
  201. assertNull("URL hyperlink should be moved, not copied", sh.getHyperlink(1, 0));
  202. assertEquals(4, sh.getHyperlinkList().size());
  203. read.close();
  204. }
  205. private void createHyperlink(CreationHelper helper, Cell cell, HyperlinkType linkType, String ref) {
  206. cell.setCellValue(ref);
  207. Hyperlink link = helper.createHyperlink(linkType);
  208. link.setAddress(ref);
  209. cell.setHyperlink(link);
  210. }
  211. private void verifyHyperlink(Cell cell, HyperlinkType linkType, String ref) {
  212. assertTrue(cellHasHyperlink(cell));
  213. if (cell != null) {
  214. Hyperlink link = cell.getHyperlink();
  215. assertEquals(linkType, link.getType());
  216. assertEquals(ref, link.getAddress());
  217. }
  218. }
  219. private boolean cellHasHyperlink(Cell cell) {
  220. return (cell != null) && (cell.getHyperlink() != null);
  221. }
  222. @Test
  223. public void shiftMergedColumnsToMergedColumnsRight() throws IOException {
  224. Workbook wb = _testDataProvider.createWorkbook();
  225. Sheet sheet = wb.createSheet("test");
  226. // populate sheet cells
  227. populateSheetCells(sheet);
  228. CellRangeAddress A1_A5 = new CellRangeAddress(0, 4, 0, 0); // NOSONAR, it's more readable this way
  229. CellRangeAddress B1_B3 = new CellRangeAddress(0, 2, 1, 1); // NOSONAR, it's more readable this way
  230. sheet.addMergedRegion(B1_B3);
  231. sheet.addMergedRegion(A1_A5);
  232. // A1:A5 should be moved to B1:B5
  233. // B1:B3 will be removed
  234. sheet.shiftColumns(0, 0, 1);
  235. assertEquals(1, sheet.getNumMergedRegions());
  236. assertEquals(CellRangeAddress.valueOf("B1:B5"), sheet.getMergedRegion(0));
  237. wb.close();
  238. }
  239. @Test
  240. public void shiftMergedColumnsToMergedColumnsLeft() throws IOException {
  241. Workbook wb = _testDataProvider.createWorkbook();
  242. Sheet sheet = wb.createSheet("test");
  243. populateSheetCells(sheet);
  244. CellRangeAddress A1_A5 = new CellRangeAddress(0, 4, 0, 0); // NOSONAR, it's more readable this way
  245. CellRangeAddress B1_B3 = new CellRangeAddress(0, 2, 1, 1); // NOSONAR, it's more readable this way
  246. sheet.addMergedRegion(A1_A5);
  247. sheet.addMergedRegion(B1_B3);
  248. // A1:E1 should be removed
  249. // B1:B3 will be A1:A3
  250. sheet.shiftColumns(1, 5, -1);
  251. assertEquals(1, sheet.getNumMergedRegions());
  252. assertEquals(CellRangeAddress.valueOf("A1:A3"), sheet.getMergedRegion(0));
  253. wb.close();
  254. }
  255. private void populateSheetCells(Sheet sheet) {
  256. // populate sheet cells
  257. for (int i = 0; i < 2; i++) {
  258. Row row = sheet.createRow(i);
  259. for (int j = 0; j < 5; j++) {
  260. Cell cell = row.createCell(j);
  261. cell.setCellValue(i + "x" + j);
  262. }
  263. }
  264. }
  265. @Test
  266. public void testShiftWithMergedRegions() throws IOException {
  267. Workbook wb = _testDataProvider.createWorkbook();
  268. Sheet sheet = wb.createSheet();
  269. Row row = sheet.createRow(0);
  270. row.createCell(0).setCellValue(1.1);
  271. row = sheet.createRow(1);
  272. row.createCell(0).setCellValue(2.2);
  273. CellRangeAddress region = new CellRangeAddress(0, 2, 0, 0);
  274. assertEquals("A1:A3", region.formatAsString());
  275. sheet.addMergedRegion(region);
  276. sheet.shiftColumns(0, 1, 2);
  277. region = sheet.getMergedRegion(0);
  278. assertEquals("C1:C3", region.formatAsString());
  279. wb.close();
  280. }
  281. protected abstract Workbook openWorkbook(String spreadsheetFileName) throws IOException;
  282. protected abstract Workbook getReadBackWorkbook(Workbook wb) throws IOException;
  283. protected static final String AMDOCS = "Amdocs";
  284. protected static final String AMDOCS_TEST = "Amdocs:\ntest\n";
  285. @Test
  286. public void testCommentsShifting() throws IOException {
  287. Workbook inputWb = openWorkbook("56017.xlsx");
  288. Sheet sheet = inputWb.getSheetAt(0);
  289. Comment comment = sheet.getCellComment(new CellAddress(0, 0));
  290. assertNotNull(comment);
  291. assertEquals(AMDOCS, comment.getAuthor());
  292. assertEquals(AMDOCS_TEST, comment.getString().getString());
  293. sheet.shiftColumns(0, 1, 1);
  294. // comment in column 0 is gone
  295. comment = sheet.getCellComment(new CellAddress(0, 0));
  296. assertNull(comment);
  297. // comment is column in column 1
  298. comment = sheet.getCellComment(new CellAddress(0, 1));
  299. assertNotNull(comment);
  300. assertEquals(AMDOCS, comment.getAuthor());
  301. assertEquals(AMDOCS_TEST, comment.getString().getString());
  302. Workbook wbBack = getReadBackWorkbook(inputWb);
  303. inputWb.close();
  304. assertNotNull(wbBack);
  305. Sheet sheetBack = wbBack.getSheetAt(0);
  306. // comment in column 0 is gone
  307. comment = sheetBack.getCellComment(new CellAddress(0, 0));
  308. assertNull(comment);
  309. // comment is now in column 1
  310. comment = sheetBack.getCellComment(new CellAddress(0, 1));
  311. assertNotNull(comment);
  312. assertEquals(AMDOCS, comment.getAuthor());
  313. assertEquals(AMDOCS_TEST, comment.getString().getString());
  314. wbBack.close();
  315. }
  316. // transposed version of TestXSSFSheetShiftRows.testBug54524()
  317. @Test
  318. public void testBug54524() throws IOException {
  319. Workbook wb = _testDataProvider.createWorkbook();
  320. Sheet sheet = wb.createSheet();
  321. Row firstRow = sheet.createRow(0);
  322. firstRow.createCell(0).setCellValue("");
  323. firstRow.createCell(1).setCellValue(1);
  324. firstRow.createCell(2).setCellValue(2);
  325. firstRow.createCell(3).setCellFormula("SUM(B1:C1)");
  326. firstRow.createCell(4).setCellValue("X");
  327. sheet.shiftColumns(3, 5, -1);
  328. Cell cell = CellUtil.getCell(sheet.getRow(0), 1);
  329. assertEquals(1.0, cell.getNumericCellValue(), 0);
  330. cell = CellUtil.getCell(sheet.getRow(0), 2);
  331. assertEquals("SUM(B1:B1)", cell.getCellFormula());
  332. cell = CellUtil.getCell(sheet.getRow(0), 3);
  333. assertEquals("X", cell.getStringCellValue());
  334. wb.close();
  335. }
  336. }