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.

TestXSSFWorkbook.java 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  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.File;
  17. import java.io.FileOutputStream;
  18. import java.io.OutputStream;
  19. import java.util.List;
  20. import java.util.zip.CRC32;
  21. import org.apache.poi.POIXMLProperties;
  22. import org.apache.poi.hssf.HSSFTestDataSamples;
  23. import org.apache.poi.openxml4j.opc.*;
  24. import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
  25. import org.apache.poi.ss.usermodel.*;
  26. import org.apache.poi.util.TempFile;
  27. import org.apache.poi.xssf.XSSFITestDataProvider;
  28. import org.apache.poi.xssf.XSSFTestDataSamples;
  29. import org.apache.poi.xssf.model.StylesTable;
  30. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr;
  31. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
  32. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr;
  33. import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode;
  34. public final class TestXSSFWorkbook extends BaseTestWorkbook {
  35. public TestXSSFWorkbook() {
  36. super(XSSFITestDataProvider.instance);
  37. }
  38. /**
  39. * Tests that we can save, and then re-load a new document
  40. */
  41. public void testSaveLoadNew() throws Exception {
  42. XSSFWorkbook workbook = new XSSFWorkbook();
  43. //check that the default date system is set to 1900
  44. CTWorkbookPr pr = workbook.getCTWorkbook().getWorkbookPr();
  45. assertNotNull(pr);
  46. assertTrue(pr.isSetDate1904());
  47. assertFalse("XSSF must use the 1900 date system", pr.getDate1904());
  48. Sheet sheet1 = workbook.createSheet("sheet1");
  49. Sheet sheet2 = workbook.createSheet("sheet2");
  50. workbook.createSheet("sheet3");
  51. RichTextString rts = workbook.getCreationHelper().createRichTextString("hello world");
  52. sheet1.createRow(0).createCell((short)0).setCellValue(1.2);
  53. sheet1.createRow(1).createCell((short)0).setCellValue(rts);
  54. sheet2.createRow(0);
  55. assertEquals(0, workbook.getSheetAt(0).getFirstRowNum());
  56. assertEquals(1, workbook.getSheetAt(0).getLastRowNum());
  57. assertEquals(0, workbook.getSheetAt(1).getFirstRowNum());
  58. assertEquals(0, workbook.getSheetAt(1).getLastRowNum());
  59. assertEquals(0, workbook.getSheetAt(2).getFirstRowNum());
  60. assertEquals(0, workbook.getSheetAt(2).getLastRowNum());
  61. File file = TempFile.createTempFile("poi-", ".xlsx");
  62. OutputStream out = new FileOutputStream(file);
  63. workbook.write(out);
  64. out.close();
  65. // Check the package contains what we'd expect it to
  66. OPCPackage pkg = OPCPackage.open(file.toString());
  67. PackagePart wbRelPart =
  68. pkg.getPart(PackagingURIHelper.createPartName("/xl/_rels/workbook.xml.rels"));
  69. assertNotNull(wbRelPart);
  70. assertTrue(wbRelPart.isRelationshipPart());
  71. assertEquals(ContentTypes.RELATIONSHIPS_PART, wbRelPart.getContentType());
  72. PackagePart wbPart =
  73. pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
  74. // Links to the three sheets, shared strings and styles
  75. assertTrue(wbPart.hasRelationships());
  76. assertEquals(5, wbPart.getRelationships().size());
  77. // Load back the XSSFWorkbook
  78. workbook = new XSSFWorkbook(pkg);
  79. assertEquals(3, workbook.getNumberOfSheets());
  80. assertNotNull(workbook.getSheetAt(0));
  81. assertNotNull(workbook.getSheetAt(1));
  82. assertNotNull(workbook.getSheetAt(2));
  83. assertNotNull(workbook.getSharedStringSource());
  84. assertNotNull(workbook.getStylesSource());
  85. assertEquals(0, workbook.getSheetAt(0).getFirstRowNum());
  86. assertEquals(1, workbook.getSheetAt(0).getLastRowNum());
  87. assertEquals(0, workbook.getSheetAt(1).getFirstRowNum());
  88. assertEquals(0, workbook.getSheetAt(1).getLastRowNum());
  89. assertEquals(0, workbook.getSheetAt(2).getFirstRowNum());
  90. assertEquals(0, workbook.getSheetAt(2).getLastRowNum());
  91. sheet1 = workbook.getSheetAt(0);
  92. assertEquals(1.2, sheet1.getRow(0).getCell(0).getNumericCellValue(), 0.0001);
  93. assertEquals("hello world", sheet1.getRow(1).getCell(0).getRichStringCellValue().getString());
  94. }
  95. public void testExisting() throws Exception {
  96. XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("Formatting.xlsx");
  97. assertNotNull(workbook.getSharedStringSource());
  98. assertNotNull(workbook.getStylesSource());
  99. // And check a few low level bits too
  100. OPCPackage pkg = OPCPackage.open(HSSFTestDataSamples.openSampleFileStream("Formatting.xlsx"));
  101. PackagePart wbPart =
  102. pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
  103. // Links to the three sheets, shared, styles and themes
  104. assertTrue(wbPart.hasRelationships());
  105. assertEquals(6, wbPart.getRelationships().size());
  106. }
  107. public void testGetCellStyleAt(){
  108. XSSFWorkbook workbook = new XSSFWorkbook();
  109. short i = 0;
  110. //get default style
  111. CellStyle cellStyleAt = workbook.getCellStyleAt(i);
  112. assertNotNull(cellStyleAt);
  113. //get custom style
  114. StylesTable styleSource = workbook.getStylesSource();
  115. XSSFCellStyle customStyle = new XSSFCellStyle(styleSource);
  116. XSSFFont font = new XSSFFont();
  117. font.setFontName("Verdana");
  118. customStyle.setFont(font);
  119. int x = styleSource.putStyle(customStyle);
  120. cellStyleAt = workbook.getCellStyleAt((short)x);
  121. assertNotNull(cellStyleAt);
  122. }
  123. public void testGetFontAt(){
  124. XSSFWorkbook workbook = new XSSFWorkbook();
  125. StylesTable styleSource = workbook.getStylesSource();
  126. short i = 0;
  127. //get default font
  128. Font fontAt = workbook.getFontAt(i);
  129. assertNotNull(fontAt);
  130. //get customized font
  131. XSSFFont customFont = new XSSFFont();
  132. customFont.setItalic(true);
  133. int x = styleSource.putFont(customFont);
  134. fontAt = workbook.getFontAt((short)x);
  135. assertNotNull(fontAt);
  136. }
  137. public void testGetNumCellStyles(){
  138. XSSFWorkbook workbook = new XSSFWorkbook();
  139. short i = workbook.getNumCellStyles();
  140. //get default cellStyles
  141. assertEquals(1, i);
  142. }
  143. public void testLoadSave() {
  144. XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("Formatting.xlsx");
  145. assertEquals(3, workbook.getNumberOfSheets());
  146. assertEquals("dd/mm/yyyy", workbook.getSheetAt(0).getRow(1).getCell(0).getRichStringCellValue().getString());
  147. assertNotNull(workbook.getSharedStringSource());
  148. assertNotNull(workbook.getStylesSource());
  149. // Write out, and check
  150. // Load up again, check all still there
  151. XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  152. assertEquals(3, wb2.getNumberOfSheets());
  153. assertNotNull(wb2.getSheetAt(0));
  154. assertNotNull(wb2.getSheetAt(1));
  155. assertNotNull(wb2.getSheetAt(2));
  156. assertEquals("dd/mm/yyyy", wb2.getSheetAt(0).getRow(1).getCell(0).getRichStringCellValue().getString());
  157. assertEquals("yyyy/mm/dd", wb2.getSheetAt(0).getRow(2).getCell(0).getRichStringCellValue().getString());
  158. assertEquals("yyyy-mm-dd", wb2.getSheetAt(0).getRow(3).getCell(0).getRichStringCellValue().getString());
  159. assertEquals("yy/mm/dd", wb2.getSheetAt(0).getRow(4).getCell(0).getRichStringCellValue().getString());
  160. assertNotNull(wb2.getSharedStringSource());
  161. assertNotNull(wb2.getStylesSource());
  162. }
  163. public void testStyles() {
  164. XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("Formatting.xlsx");
  165. StylesTable ss = workbook.getStylesSource();
  166. assertNotNull(ss);
  167. StylesTable st = ss;
  168. // Has 8 number formats
  169. assertEquals(8, st._getNumberFormatSize());
  170. // Has 2 fonts
  171. assertEquals(2, st.getFonts().size());
  172. // Has 2 fills
  173. assertEquals(2, st.getFills().size());
  174. // Has 1 border
  175. assertEquals(1, st.getBorders().size());
  176. // Add two more styles
  177. assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 8,
  178. st.putNumberFormat("testFORMAT"));
  179. assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 8,
  180. st.putNumberFormat("testFORMAT"));
  181. assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 9,
  182. st.putNumberFormat("testFORMAT2"));
  183. assertEquals(10, st._getNumberFormatSize());
  184. // Save, load back in again, and check
  185. workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  186. ss = workbook.getStylesSource();
  187. assertNotNull(ss);
  188. assertEquals(10, st._getNumberFormatSize());
  189. assertEquals(2, st.getFonts().size());
  190. assertEquals(2, st.getFills().size());
  191. assertEquals(1, st.getBorders().size());
  192. }
  193. public void testIncrementSheetId() {
  194. XSSFWorkbook wb = new XSSFWorkbook();
  195. int sheetId = (int)wb.createSheet().sheet.getSheetId();
  196. assertEquals(1, sheetId);
  197. sheetId = (int)wb.createSheet().sheet.getSheetId();
  198. assertEquals(2, sheetId);
  199. //test file with gaps in the sheetId sequence
  200. wb = XSSFTestDataSamples.openSampleWorkbook("47089.xlsm");
  201. int lastSheetId = (int)wb.getSheetAt(wb.getNumberOfSheets() - 1).sheet.getSheetId();
  202. sheetId = (int)wb.createSheet().sheet.getSheetId();
  203. assertEquals(lastSheetId+1, sheetId);
  204. }
  205. /**
  206. * Test setting of core properties such as Title and Author
  207. */
  208. public void testWorkbookProperties() {
  209. XSSFWorkbook workbook = new XSSFWorkbook();
  210. POIXMLProperties props = workbook.getProperties();
  211. assertNotNull(props);
  212. //the Application property must be set for new workbooks, see Bugzilla #47559
  213. assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication());
  214. PackagePropertiesPart opcProps = props.getCoreProperties().getUnderlyingProperties();
  215. assertNotNull(opcProps);
  216. opcProps.setTitleProperty("Testing Bugzilla #47460");
  217. assertEquals("Apache POI", opcProps.getCreatorProperty().getValue());
  218. opcProps.setCreatorProperty("poi-dev@poi.apache.org");
  219. workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  220. assertEquals("Apache POI", workbook.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
  221. opcProps = workbook.getProperties().getCoreProperties().getUnderlyingProperties();
  222. assertEquals("Testing Bugzilla #47460", opcProps.getTitleProperty().getValue());
  223. assertEquals("poi-dev@poi.apache.org", opcProps.getCreatorProperty().getValue());
  224. }
  225. /**
  226. * Verify that the attached test data was not modified. If this test method
  227. * fails, the test data is not working properly.
  228. */
  229. public void testBug47668() throws Exception {
  230. XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("47668.xlsx");
  231. List<XSSFPictureData> allPictures = workbook.getAllPictures();
  232. assertEquals(1, allPictures.size());
  233. PackagePartName imagePartName = PackagingURIHelper
  234. .createPartName("/xl/media/image1.jpeg");
  235. PackagePart imagePart = workbook.getPackage().getPart(imagePartName);
  236. assertNotNull(imagePart);
  237. for (XSSFPictureData pictureData : allPictures) {
  238. PackagePart picturePart = pictureData.getPackagePart();
  239. assertSame(imagePart, picturePart);
  240. }
  241. XSSFSheet sheet0 = workbook.getSheetAt(0);
  242. XSSFDrawing drawing0 = sheet0.createDrawingPatriarch();
  243. XSSFPictureData pictureData0 = (XSSFPictureData) drawing0.getRelations().get(0);
  244. byte[] data0 = pictureData0.getData();
  245. CRC32 crc0 = new CRC32();
  246. crc0.update(data0);
  247. XSSFSheet sheet1 = workbook.getSheetAt(1);
  248. XSSFDrawing drawing1 = sheet1.createDrawingPatriarch();
  249. XSSFPictureData pictureData1 = (XSSFPictureData) drawing1.getRelations().get(0);
  250. byte[] data1 = pictureData1.getData();
  251. CRC32 crc1 = new CRC32();
  252. crc1.update(data1);
  253. assertEquals(crc0.getValue(), crc1.getValue());
  254. }
  255. /**
  256. * When deleting a sheet make sure that we adjust sheet indices of named ranges
  257. */
  258. public void testBug47737() {
  259. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47737.xlsx");
  260. assertEquals(2, wb.getNumberOfNames());
  261. assertNotNull(wb.getCalculationChain());
  262. XSSFName nm0 = wb.getNameAt(0);
  263. assertTrue(nm0.getCTName().isSetLocalSheetId());
  264. assertEquals(0, nm0.getCTName().getLocalSheetId());
  265. XSSFName nm1 = wb.getNameAt(1);
  266. assertTrue(nm1.getCTName().isSetLocalSheetId());
  267. assertEquals(1, nm1.getCTName().getLocalSheetId());
  268. wb.removeSheetAt(0);
  269. assertEquals(1, wb.getNumberOfNames());
  270. XSSFName nm2 = wb.getNameAt(0);
  271. assertTrue(nm2.getCTName().isSetLocalSheetId());
  272. assertEquals(0, nm2.getCTName().getLocalSheetId());
  273. //calculation chain is removed as well
  274. assertNull(wb.getCalculationChain());
  275. }
  276. /**
  277. * Problems with XSSFWorkbook.removeSheetAt when workbook contains charts
  278. */
  279. public void testBug47813() {
  280. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47813.xlsx");
  281. assertEquals(3, wb.getNumberOfSheets());
  282. assertNotNull(wb.getCalculationChain());
  283. assertEquals("Numbers", wb.getSheetName(0));
  284. //the second sheet is of type 'chartsheet'
  285. assertEquals("Chart", wb.getSheetName(1));
  286. assertTrue(wb.getSheetAt(1) instanceof XSSFChartSheet);
  287. assertEquals("SomeJunk", wb.getSheetName(2));
  288. wb.removeSheetAt(2);
  289. assertEquals(2, wb.getNumberOfSheets());
  290. assertNull(wb.getCalculationChain());
  291. wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  292. assertEquals(2, wb.getNumberOfSheets());
  293. assertNull(wb.getCalculationChain());
  294. assertEquals("Numbers", wb.getSheetName(0));
  295. assertEquals("Chart", wb.getSheetName(1));
  296. }
  297. /**
  298. * Problems with the count of the number of styles
  299. * coming out wrong
  300. */
  301. public void testBug49702() throws Exception {
  302. // First try with a new file
  303. XSSFWorkbook wb = new XSSFWorkbook();
  304. // Should have one style
  305. assertEquals(1, wb.getNumCellStyles());
  306. wb.getCellStyleAt((short)0);
  307. try {
  308. wb.getCellStyleAt((short)1);
  309. fail("Shouldn't be able to get style at 1 that doesn't exist");
  310. } catch(IndexOutOfBoundsException e) {}
  311. // Add another one
  312. CellStyle cs = wb.createCellStyle();
  313. cs.setDataFormat((short)11);
  314. // Re-check
  315. assertEquals(2, wb.getNumCellStyles());
  316. wb.getCellStyleAt((short)0);
  317. wb.getCellStyleAt((short)1);
  318. try {
  319. wb.getCellStyleAt((short)2);
  320. fail("Shouldn't be able to get style at 2 that doesn't exist");
  321. } catch(IndexOutOfBoundsException e) {}
  322. // Save and reload
  323. XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  324. assertEquals(2, nwb.getNumCellStyles());
  325. nwb.getCellStyleAt((short)0);
  326. nwb.getCellStyleAt((short)1);
  327. try {
  328. nwb.getCellStyleAt((short)2);
  329. fail("Shouldn't be able to get style at 2 that doesn't exist");
  330. } catch(IndexOutOfBoundsException e) {}
  331. // Now with an existing file
  332. wb = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx");
  333. assertEquals(3, wb.getNumCellStyles());
  334. wb.getCellStyleAt((short)0);
  335. wb.getCellStyleAt((short)1);
  336. wb.getCellStyleAt((short)2);
  337. try {
  338. wb.getCellStyleAt((short)3);
  339. fail("Shouldn't be able to get style at 3 that doesn't exist");
  340. } catch(IndexOutOfBoundsException e) {}
  341. }
  342. public void testRecalcId() {
  343. XSSFWorkbook wb = new XSSFWorkbook();
  344. assertFalse(wb.getForceFormulaRecalculation());
  345. CTWorkbook ctWorkbook = wb.getCTWorkbook();
  346. assertFalse(ctWorkbook.isSetCalcPr());
  347. wb.setForceFormulaRecalculation(true); // resets the EngineId flag to zero
  348. CTCalcPr calcPr = ctWorkbook.getCalcPr();
  349. assertNotNull(calcPr);
  350. assertEquals(0, (int) calcPr.getCalcId());
  351. calcPr.setCalcId(100);
  352. assertTrue(wb.getForceFormulaRecalculation());
  353. wb.setForceFormulaRecalculation(true); // resets the EngineId flag to zero
  354. assertEquals(0, (int) calcPr.getCalcId());
  355. assertFalse(wb.getForceFormulaRecalculation());
  356. // calcMode="manual" is unset when forceFormulaRecalculation=true
  357. calcPr.setCalcMode(STCalcMode.MANUAL);
  358. wb.setForceFormulaRecalculation(true);
  359. assertEquals(STCalcMode.AUTO, calcPr.getCalcMode());
  360. }
  361. public void testChangeSheetNameWithSharedFormulas() {
  362. changeSheetNameWithSharedFormulas("shared_formulas.xlsx");
  363. }
  364. public void testSetTabColor() {
  365. XSSFWorkbook wb = new XSSFWorkbook();
  366. XSSFSheet sh = wb.createSheet();
  367. assertTrue(sh.getCTWorksheet().getSheetPr() == null || !sh.getCTWorksheet().getSheetPr().isSetTabColor());
  368. sh.setTabColor(IndexedColors.RED.index);
  369. assertTrue(sh.getCTWorksheet().getSheetPr().isSetTabColor());
  370. assertEquals(IndexedColors.RED.index,
  371. sh.getCTWorksheet().getSheetPr().getTabColor().getIndexed());
  372. }
  373. }