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 38KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  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.Assert.assertArrayEquals;
  17. import static org.junit.Assert.assertEquals;
  18. import static org.junit.Assert.assertFalse;
  19. import static org.junit.Assert.assertNotNull;
  20. import static org.junit.Assert.assertNull;
  21. import static org.junit.Assert.assertSame;
  22. import static org.junit.Assert.assertTrue;
  23. import static org.junit.Assert.fail;
  24. import java.io.ByteArrayInputStream;
  25. import java.io.ByteArrayOutputStream;
  26. import java.io.File;
  27. import java.io.FileOutputStream;
  28. import java.io.IOException;
  29. import java.io.OutputStream;
  30. import java.util.Iterator;
  31. import java.util.List;
  32. import java.util.zip.CRC32;
  33. import org.apache.poi.POIXMLProperties;
  34. import org.apache.poi.hssf.HSSFTestDataSamples;
  35. import org.apache.poi.openxml4j.opc.ContentTypes;
  36. import org.apache.poi.openxml4j.opc.OPCPackage;
  37. import org.apache.poi.openxml4j.opc.PackageAccess;
  38. import org.apache.poi.openxml4j.opc.PackagePart;
  39. import org.apache.poi.openxml4j.opc.PackagePartName;
  40. import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
  41. import org.apache.poi.openxml4j.opc.PackagingURIHelper;
  42. import org.apache.poi.openxml4j.opc.internal.FileHelper;
  43. import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
  44. import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
  45. import org.apache.poi.ss.SpreadsheetVersion;
  46. import org.apache.poi.ss.usermodel.BaseTestWorkbook;
  47. import org.apache.poi.ss.usermodel.Cell;
  48. import org.apache.poi.ss.usermodel.CellStyle;
  49. import org.apache.poi.ss.usermodel.Font;
  50. import org.apache.poi.ss.usermodel.IndexedColors;
  51. import org.apache.poi.ss.usermodel.RichTextString;
  52. import org.apache.poi.ss.usermodel.Row;
  53. import org.apache.poi.ss.usermodel.Sheet;
  54. import org.apache.poi.ss.usermodel.Workbook;
  55. import org.apache.poi.ss.usermodel.WorkbookFactory;
  56. import org.apache.poi.ss.util.AreaReference;
  57. import org.apache.poi.ss.util.CellReference;
  58. import org.apache.poi.util.IOUtils;
  59. import org.apache.poi.util.TempFile;
  60. import org.apache.poi.xssf.XSSFITestDataProvider;
  61. import org.apache.poi.xssf.XSSFTestDataSamples;
  62. import org.apache.poi.xssf.model.StylesTable;
  63. import org.junit.Test;
  64. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr;
  65. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCache;
  66. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
  67. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr;
  68. import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode;
  69. public final class TestXSSFWorkbook extends BaseTestWorkbook {
  70. public TestXSSFWorkbook() {
  71. super(XSSFITestDataProvider.instance);
  72. }
  73. /**
  74. * Tests that we can save, and then re-load a new document
  75. */
  76. @Test
  77. public void saveLoadNew() throws Exception {
  78. @SuppressWarnings("resource")
  79. XSSFWorkbook workbook = new XSSFWorkbook();
  80. //check that the default date system is set to 1900
  81. CTWorkbookPr pr = workbook.getCTWorkbook().getWorkbookPr();
  82. assertNotNull(pr);
  83. assertTrue(pr.isSetDate1904());
  84. assertFalse("XSSF must use the 1900 date system", pr.getDate1904());
  85. Sheet sheet1 = workbook.createSheet("sheet1");
  86. Sheet sheet2 = workbook.createSheet("sheet2");
  87. workbook.createSheet("sheet3");
  88. RichTextString rts = workbook.getCreationHelper().createRichTextString("hello world");
  89. sheet1.createRow(0).createCell((short)0).setCellValue(1.2);
  90. sheet1.createRow(1).createCell((short)0).setCellValue(rts);
  91. sheet2.createRow(0);
  92. assertEquals(0, workbook.getSheetAt(0).getFirstRowNum());
  93. assertEquals(1, workbook.getSheetAt(0).getLastRowNum());
  94. assertEquals(0, workbook.getSheetAt(1).getFirstRowNum());
  95. assertEquals(0, workbook.getSheetAt(1).getLastRowNum());
  96. assertEquals(0, workbook.getSheetAt(2).getFirstRowNum());
  97. assertEquals(0, workbook.getSheetAt(2).getLastRowNum());
  98. File file = TempFile.createTempFile("poi-", ".xlsx");
  99. OutputStream out = new FileOutputStream(file);
  100. workbook.write(out);
  101. out.close();
  102. // Check the package contains what we'd expect it to
  103. OPCPackage pkg = OPCPackage.open(file.toString());
  104. PackagePart wbRelPart =
  105. pkg.getPart(PackagingURIHelper.createPartName("/xl/_rels/workbook.xml.rels"));
  106. assertNotNull(wbRelPart);
  107. assertTrue(wbRelPart.isRelationshipPart());
  108. assertEquals(ContentTypes.RELATIONSHIPS_PART, wbRelPart.getContentType());
  109. PackagePart wbPart =
  110. pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
  111. // Links to the three sheets, shared strings and styles
  112. assertTrue(wbPart.hasRelationships());
  113. assertEquals(5, wbPart.getRelationships().size());
  114. workbook.close();
  115. // Load back the XSSFWorkbook
  116. workbook = new XSSFWorkbook(pkg);
  117. assertEquals(3, workbook.getNumberOfSheets());
  118. assertNotNull(workbook.getSheetAt(0));
  119. assertNotNull(workbook.getSheetAt(1));
  120. assertNotNull(workbook.getSheetAt(2));
  121. assertNotNull(workbook.getSharedStringSource());
  122. assertNotNull(workbook.getStylesSource());
  123. assertEquals(0, workbook.getSheetAt(0).getFirstRowNum());
  124. assertEquals(1, workbook.getSheetAt(0).getLastRowNum());
  125. assertEquals(0, workbook.getSheetAt(1).getFirstRowNum());
  126. assertEquals(0, workbook.getSheetAt(1).getLastRowNum());
  127. assertEquals(0, workbook.getSheetAt(2).getFirstRowNum());
  128. assertEquals(0, workbook.getSheetAt(2).getLastRowNum());
  129. sheet1 = workbook.getSheetAt(0);
  130. assertEquals(1.2, sheet1.getRow(0).getCell(0).getNumericCellValue(), 0.0001);
  131. assertEquals("hello world", sheet1.getRow(1).getCell(0).getRichStringCellValue().getString());
  132. pkg.close();
  133. }
  134. @Test
  135. public void existing() throws Exception {
  136. XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("Formatting.xlsx");
  137. assertNotNull(workbook.getSharedStringSource());
  138. assertNotNull(workbook.getStylesSource());
  139. // And check a few low level bits too
  140. OPCPackage pkg = OPCPackage.open(HSSFTestDataSamples.openSampleFileStream("Formatting.xlsx"));
  141. PackagePart wbPart =
  142. pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
  143. // Links to the three sheets, shared, styles and themes
  144. assertTrue(wbPart.hasRelationships());
  145. assertEquals(6, wbPart.getRelationships().size());
  146. pkg.close();
  147. }
  148. @Test
  149. public void getCellStyleAt() throws IOException{
  150. XSSFWorkbook workbook = new XSSFWorkbook();
  151. try {
  152. short i = 0;
  153. //get default style
  154. CellStyle cellStyleAt = workbook.getCellStyleAt(i);
  155. assertNotNull(cellStyleAt);
  156. //get custom style
  157. StylesTable styleSource = workbook.getStylesSource();
  158. XSSFCellStyle customStyle = new XSSFCellStyle(styleSource);
  159. XSSFFont font = new XSSFFont();
  160. font.setFontName("Verdana");
  161. customStyle.setFont(font);
  162. int x = styleSource.putStyle(customStyle);
  163. cellStyleAt = workbook.getCellStyleAt((short)x);
  164. assertNotNull(cellStyleAt);
  165. } finally {
  166. workbook.close();
  167. }
  168. }
  169. @Test
  170. public void getFontAt() throws IOException{
  171. XSSFWorkbook workbook = new XSSFWorkbook();
  172. try {
  173. StylesTable styleSource = workbook.getStylesSource();
  174. short i = 0;
  175. //get default font
  176. Font fontAt = workbook.getFontAt(i);
  177. assertNotNull(fontAt);
  178. //get customized font
  179. XSSFFont customFont = new XSSFFont();
  180. customFont.setItalic(true);
  181. int x = styleSource.putFont(customFont);
  182. fontAt = workbook.getFontAt((short)x);
  183. assertNotNull(fontAt);
  184. } finally {
  185. workbook.close();
  186. }
  187. }
  188. @Test
  189. public void getNumCellStyles() throws IOException{
  190. XSSFWorkbook workbook = new XSSFWorkbook();
  191. try {
  192. short i = workbook.getNumCellStyles();
  193. //get default cellStyles
  194. assertEquals(1, i);
  195. } finally {
  196. workbook.close();
  197. }
  198. }
  199. @Test
  200. public void loadSave() {
  201. XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("Formatting.xlsx");
  202. assertEquals(3, workbook.getNumberOfSheets());
  203. assertEquals("dd/mm/yyyy", workbook.getSheetAt(0).getRow(1).getCell(0).getRichStringCellValue().getString());
  204. assertNotNull(workbook.getSharedStringSource());
  205. assertNotNull(workbook.getStylesSource());
  206. // Write out, and check
  207. // Load up again, check all still there
  208. XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  209. assertEquals(3, wb2.getNumberOfSheets());
  210. assertNotNull(wb2.getSheetAt(0));
  211. assertNotNull(wb2.getSheetAt(1));
  212. assertNotNull(wb2.getSheetAt(2));
  213. assertEquals("dd/mm/yyyy", wb2.getSheetAt(0).getRow(1).getCell(0).getRichStringCellValue().getString());
  214. assertEquals("yyyy/mm/dd", wb2.getSheetAt(0).getRow(2).getCell(0).getRichStringCellValue().getString());
  215. assertEquals("yyyy-mm-dd", wb2.getSheetAt(0).getRow(3).getCell(0).getRichStringCellValue().getString());
  216. assertEquals("yy/mm/dd", wb2.getSheetAt(0).getRow(4).getCell(0).getRichStringCellValue().getString());
  217. assertNotNull(wb2.getSharedStringSource());
  218. assertNotNull(wb2.getStylesSource());
  219. }
  220. @Test
  221. public void styles() {
  222. XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("Formatting.xlsx");
  223. StylesTable ss = workbook.getStylesSource();
  224. assertNotNull(ss);
  225. StylesTable st = ss;
  226. // Has 8 number formats
  227. assertEquals(8, st._getNumberFormatSize());
  228. // Has 2 fonts
  229. assertEquals(2, st.getFonts().size());
  230. // Has 2 fills
  231. assertEquals(2, st.getFills().size());
  232. // Has 1 border
  233. assertEquals(1, st.getBorders().size());
  234. // Add two more styles
  235. assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 8,
  236. st.putNumberFormat("testFORMAT"));
  237. assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 8,
  238. st.putNumberFormat("testFORMAT"));
  239. assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 9,
  240. st.putNumberFormat("testFORMAT2"));
  241. assertEquals(10, st._getNumberFormatSize());
  242. // Save, load back in again, and check
  243. workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  244. ss = workbook.getStylesSource();
  245. assertNotNull(ss);
  246. assertEquals(10, st._getNumberFormatSize());
  247. assertEquals(2, st.getFonts().size());
  248. assertEquals(2, st.getFills().size());
  249. assertEquals(1, st.getBorders().size());
  250. }
  251. @Test
  252. public void incrementSheetId() throws IOException {
  253. XSSFWorkbook wb = new XSSFWorkbook();
  254. try {
  255. int sheetId = (int)wb.createSheet().sheet.getSheetId();
  256. assertEquals(1, sheetId);
  257. sheetId = (int)wb.createSheet().sheet.getSheetId();
  258. assertEquals(2, sheetId);
  259. //test file with gaps in the sheetId sequence
  260. XSSFWorkbook wbBack = XSSFTestDataSamples.openSampleWorkbook("47089.xlsm");
  261. try {
  262. int lastSheetId = (int)wbBack.getSheetAt(wbBack.getNumberOfSheets() - 1).sheet.getSheetId();
  263. sheetId = (int)wbBack.createSheet().sheet.getSheetId();
  264. assertEquals(lastSheetId+1, sheetId);
  265. } finally {
  266. wbBack.close();
  267. }
  268. } finally {
  269. wb.close();
  270. }
  271. }
  272. /**
  273. * Test setting of core properties such as Title and Author
  274. * @throws IOException
  275. */
  276. @Test
  277. public void workbookProperties() throws IOException {
  278. XSSFWorkbook workbook = new XSSFWorkbook();
  279. try {
  280. POIXMLProperties props = workbook.getProperties();
  281. assertNotNull(props);
  282. //the Application property must be set for new workbooks, see Bugzilla #47559
  283. assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication());
  284. PackagePropertiesPart opcProps = props.getCoreProperties().getUnderlyingProperties();
  285. assertNotNull(opcProps);
  286. opcProps.setTitleProperty("Testing Bugzilla #47460");
  287. assertEquals("Apache POI", opcProps.getCreatorProperty().getValue());
  288. opcProps.setCreatorProperty("poi-dev@poi.apache.org");
  289. XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  290. assertEquals("Apache POI", wbBack.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
  291. opcProps = wbBack.getProperties().getCoreProperties().getUnderlyingProperties();
  292. assertEquals("Testing Bugzilla #47460", opcProps.getTitleProperty().getValue());
  293. assertEquals("poi-dev@poi.apache.org", opcProps.getCreatorProperty().getValue());
  294. } finally {
  295. workbook.close();
  296. }
  297. }
  298. /**
  299. * Verify that the attached test data was not modified. If this test method
  300. * fails, the test data is not working properly.
  301. */
  302. @Test
  303. public void bug47668() throws Exception {
  304. XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("47668.xlsx");
  305. List<XSSFPictureData> allPictures = workbook.getAllPictures();
  306. assertEquals(1, allPictures.size());
  307. PackagePartName imagePartName = PackagingURIHelper
  308. .createPartName("/xl/media/image1.jpeg");
  309. PackagePart imagePart = workbook.getPackage().getPart(imagePartName);
  310. assertNotNull(imagePart);
  311. for (XSSFPictureData pictureData : allPictures) {
  312. PackagePart picturePart = pictureData.getPackagePart();
  313. assertSame(imagePart, picturePart);
  314. }
  315. XSSFSheet sheet0 = workbook.getSheetAt(0);
  316. XSSFDrawing drawing0 = sheet0.createDrawingPatriarch();
  317. XSSFPictureData pictureData0 = (XSSFPictureData) drawing0.getRelations().get(0);
  318. byte[] data0 = pictureData0.getData();
  319. CRC32 crc0 = new CRC32();
  320. crc0.update(data0);
  321. XSSFSheet sheet1 = workbook.getSheetAt(1);
  322. XSSFDrawing drawing1 = sheet1.createDrawingPatriarch();
  323. XSSFPictureData pictureData1 = (XSSFPictureData) drawing1.getRelations().get(0);
  324. byte[] data1 = pictureData1.getData();
  325. CRC32 crc1 = new CRC32();
  326. crc1.update(data1);
  327. assertEquals(crc0.getValue(), crc1.getValue());
  328. }
  329. /**
  330. * When deleting a sheet make sure that we adjust sheet indices of named ranges
  331. */
  332. @Test
  333. public void bug47737() {
  334. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47737.xlsx");
  335. assertEquals(2, wb.getNumberOfNames());
  336. assertNotNull(wb.getCalculationChain());
  337. XSSFName nm0 = wb.getNameAt(0);
  338. assertTrue(nm0.getCTName().isSetLocalSheetId());
  339. assertEquals(0, nm0.getCTName().getLocalSheetId());
  340. XSSFName nm1 = wb.getNameAt(1);
  341. assertTrue(nm1.getCTName().isSetLocalSheetId());
  342. assertEquals(1, nm1.getCTName().getLocalSheetId());
  343. wb.removeSheetAt(0);
  344. assertEquals(1, wb.getNumberOfNames());
  345. XSSFName nm2 = wb.getNameAt(0);
  346. assertTrue(nm2.getCTName().isSetLocalSheetId());
  347. assertEquals(0, nm2.getCTName().getLocalSheetId());
  348. //calculation chain is removed as well
  349. assertNull(wb.getCalculationChain());
  350. }
  351. /**
  352. * Problems with XSSFWorkbook.removeSheetAt when workbook contains charts
  353. */
  354. @Test
  355. public void bug47813() {
  356. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47813.xlsx");
  357. assertEquals(3, wb.getNumberOfSheets());
  358. assertNotNull(wb.getCalculationChain());
  359. assertEquals("Numbers", wb.getSheetName(0));
  360. //the second sheet is of type 'chartsheet'
  361. assertEquals("Chart", wb.getSheetName(1));
  362. assertTrue(wb.getSheetAt(1) instanceof XSSFChartSheet);
  363. assertEquals("SomeJunk", wb.getSheetName(2));
  364. wb.removeSheetAt(2);
  365. assertEquals(2, wb.getNumberOfSheets());
  366. assertNull(wb.getCalculationChain());
  367. wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  368. assertEquals(2, wb.getNumberOfSheets());
  369. assertNull(wb.getCalculationChain());
  370. assertEquals("Numbers", wb.getSheetName(0));
  371. assertEquals("Chart", wb.getSheetName(1));
  372. }
  373. /**
  374. * Problems with the count of the number of styles
  375. * coming out wrong
  376. */
  377. @Test
  378. public void bug49702() throws Exception {
  379. // First try with a new file
  380. XSSFWorkbook wb = new XSSFWorkbook();
  381. // Should have one style
  382. assertEquals(1, wb.getNumCellStyles());
  383. wb.getCellStyleAt((short)0);
  384. try {
  385. wb.getCellStyleAt((short)1);
  386. fail("Shouldn't be able to get style at 1 that doesn't exist");
  387. } catch(IndexOutOfBoundsException e) {}
  388. // Add another one
  389. CellStyle cs = wb.createCellStyle();
  390. cs.setDataFormat((short)11);
  391. // Re-check
  392. assertEquals(2, wb.getNumCellStyles());
  393. wb.getCellStyleAt((short)0);
  394. wb.getCellStyleAt((short)1);
  395. try {
  396. wb.getCellStyleAt((short)2);
  397. fail("Shouldn't be able to get style at 2 that doesn't exist");
  398. } catch(IndexOutOfBoundsException e) {}
  399. // Save and reload
  400. XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  401. assertEquals(2, nwb.getNumCellStyles());
  402. nwb.getCellStyleAt((short)0);
  403. nwb.getCellStyleAt((short)1);
  404. try {
  405. nwb.getCellStyleAt((short)2);
  406. fail("Shouldn't be able to get style at 2 that doesn't exist");
  407. } catch(IndexOutOfBoundsException e) {}
  408. // Now with an existing file
  409. wb = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx");
  410. assertEquals(3, wb.getNumCellStyles());
  411. wb.getCellStyleAt((short)0);
  412. wb.getCellStyleAt((short)1);
  413. wb.getCellStyleAt((short)2);
  414. try {
  415. wb.getCellStyleAt((short)3);
  416. fail("Shouldn't be able to get style at 3 that doesn't exist");
  417. } catch(IndexOutOfBoundsException e) {}
  418. }
  419. @Test
  420. public void recalcId() throws IOException {
  421. XSSFWorkbook wb = new XSSFWorkbook();
  422. try {
  423. assertFalse(wb.getForceFormulaRecalculation());
  424. CTWorkbook ctWorkbook = wb.getCTWorkbook();
  425. assertFalse(ctWorkbook.isSetCalcPr());
  426. wb.setForceFormulaRecalculation(true); // resets the EngineId flag to zero
  427. CTCalcPr calcPr = ctWorkbook.getCalcPr();
  428. assertNotNull(calcPr);
  429. assertEquals(0, (int) calcPr.getCalcId());
  430. calcPr.setCalcId(100);
  431. assertTrue(wb.getForceFormulaRecalculation());
  432. wb.setForceFormulaRecalculation(true); // resets the EngineId flag to zero
  433. assertEquals(0, (int) calcPr.getCalcId());
  434. assertFalse(wb.getForceFormulaRecalculation());
  435. // calcMode="manual" is unset when forceFormulaRecalculation=true
  436. calcPr.setCalcMode(STCalcMode.MANUAL);
  437. wb.setForceFormulaRecalculation(true);
  438. assertEquals(STCalcMode.AUTO, calcPr.getCalcMode());
  439. } finally {
  440. wb.close();
  441. }
  442. }
  443. @Test
  444. public void changeSheetNameWithSharedFormulas() {
  445. changeSheetNameWithSharedFormulas("shared_formulas.xlsx");
  446. }
  447. @Test
  448. public void setTabColor() throws IOException {
  449. XSSFWorkbook wb = new XSSFWorkbook();
  450. try {
  451. XSSFSheet sh = wb.createSheet();
  452. assertTrue(sh.getCTWorksheet().getSheetPr() == null || !sh.getCTWorksheet().getSheetPr().isSetTabColor());
  453. sh.setTabColor(IndexedColors.RED.index);
  454. assertTrue(sh.getCTWorksheet().getSheetPr().isSetTabColor());
  455. assertEquals(IndexedColors.RED.index,
  456. sh.getCTWorksheet().getSheetPr().getTabColor().getIndexed());
  457. } finally {
  458. wb.close();
  459. }
  460. }
  461. @Test
  462. public void columnWidthPOI52233() throws Exception {
  463. XSSFWorkbook workbook = new XSSFWorkbook();
  464. XSSFSheet sheet = workbook.createSheet();
  465. XSSFRow row = sheet.createRow(0);
  466. XSSFCell cell = row.createCell(0);
  467. cell.setCellValue("hello world");
  468. sheet = workbook.createSheet();
  469. sheet.setColumnWidth(4, 5000);
  470. sheet.setColumnWidth(5, 5000);
  471. sheet.groupColumn((short) 4, (short) 5);
  472. accessWorkbook(workbook);
  473. ByteArrayOutputStream stream = new ByteArrayOutputStream();
  474. try {
  475. workbook.write(stream);
  476. } finally {
  477. stream.close();
  478. }
  479. accessWorkbook(workbook);
  480. }
  481. private void accessWorkbook(XSSFWorkbook workbook) {
  482. workbook.getSheetAt(1).setColumnGroupCollapsed(4, true);
  483. workbook.getSheetAt(1).setColumnGroupCollapsed(4, false);
  484. assertEquals("hello world", workbook.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());
  485. assertEquals(2048, workbook.getSheetAt(0).getColumnWidth(0)); // <-works
  486. }
  487. @Test
  488. public void bug48495() {
  489. try {
  490. Workbook wb = XSSFTestDataSamples.openSampleWorkbook("48495.xlsx");
  491. assertSheetOrder(wb, "Sheet1");
  492. Sheet sheet = wb.getSheetAt(0);
  493. sheet.shiftRows(2, sheet.getLastRowNum(), 1, true, false);
  494. Row newRow = sheet.getRow(2);
  495. if (newRow == null) newRow = sheet.createRow(2);
  496. newRow.createCell(0).setCellValue(" Another Header");
  497. wb.cloneSheet(0);
  498. assertSheetOrder(wb, "Sheet1", "Sheet1 (2)");
  499. // FileOutputStream fileOut = new FileOutputStream("/tmp/bug48495.xlsx");
  500. // try {
  501. // wb.write(fileOut);
  502. // } finally {
  503. // fileOut.close();
  504. // }
  505. Workbook read = XSSFTestDataSamples.writeOutAndReadBack(wb);
  506. assertNotNull(read);
  507. assertSheetOrder(read, "Sheet1", "Sheet1 (2)");
  508. } catch (Exception e) {
  509. e.printStackTrace();
  510. }
  511. System.out.println("Done");
  512. }
  513. @Test
  514. public void bug47090a() {
  515. Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("47090.xlsx");
  516. assertSheetOrder(workbook, "Sheet1", "Sheet2");
  517. workbook.removeSheetAt(0);
  518. assertSheetOrder(workbook, "Sheet2");
  519. workbook.createSheet();
  520. assertSheetOrder(workbook, "Sheet2", "Sheet1");
  521. Workbook read = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  522. assertSheetOrder(read, "Sheet2", "Sheet1");
  523. }
  524. @Test
  525. public void bug47090b() {
  526. Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("47090.xlsx");
  527. assertSheetOrder(workbook, "Sheet1", "Sheet2");
  528. workbook.removeSheetAt(1);
  529. assertSheetOrder(workbook, "Sheet1");
  530. workbook.createSheet();
  531. assertSheetOrder(workbook, "Sheet1", "Sheet0"); // Sheet0 because it uses "Sheet" + sheets.size() as starting point!
  532. Workbook read = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  533. assertSheetOrder(read, "Sheet1", "Sheet0");
  534. }
  535. @Test
  536. public void bug47090c() {
  537. Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("47090.xlsx");
  538. assertSheetOrder(workbook, "Sheet1", "Sheet2");
  539. workbook.removeSheetAt(0);
  540. assertSheetOrder(workbook, "Sheet2");
  541. workbook.cloneSheet(0);
  542. assertSheetOrder(workbook, "Sheet2", "Sheet2 (2)");
  543. Workbook read = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  544. assertSheetOrder(read, "Sheet2", "Sheet2 (2)");
  545. }
  546. @Test
  547. public void bug47090d() {
  548. Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("47090.xlsx");
  549. assertSheetOrder(workbook, "Sheet1", "Sheet2");
  550. workbook.createSheet();
  551. assertSheetOrder(workbook, "Sheet1", "Sheet2", "Sheet0");
  552. workbook.removeSheetAt(0);
  553. assertSheetOrder(workbook, "Sheet2", "Sheet0");
  554. workbook.createSheet();
  555. assertSheetOrder(workbook, "Sheet2", "Sheet0", "Sheet1");
  556. Workbook read = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  557. assertSheetOrder(read, "Sheet2", "Sheet0", "Sheet1");
  558. }
  559. @Test
  560. public void bug51158() throws IOException {
  561. // create a workbook
  562. final XSSFWorkbook workbook = new XSSFWorkbook();
  563. XSSFSheet sheet = workbook.createSheet("Test Sheet");
  564. XSSFRow row = sheet.createRow(2);
  565. XSSFCell cell = row.createCell(3);
  566. cell.setCellValue("test1");
  567. //XSSFCreationHelper helper = workbook.getCreationHelper();
  568. //cell.setHyperlink(helper.createHyperlink(0));
  569. XSSFComment comment = sheet.createDrawingPatriarch().createCellComment(new XSSFClientAnchor());
  570. assertNotNull(comment);
  571. comment.setString("some comment");
  572. // CellStyle cs = workbook.createCellStyle();
  573. // cs.setShrinkToFit(false);
  574. // row.createCell(0).setCellStyle(cs);
  575. // write the first excel file
  576. XSSFWorkbook readBack = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  577. assertNotNull(readBack);
  578. assertEquals("test1", readBack.getSheetAt(0).getRow(2).getCell(3).getStringCellValue());
  579. assertNull(readBack.getSheetAt(0).getRow(2).getCell(4));
  580. // add a new cell to the sheet
  581. cell = row.createCell(4);
  582. cell.setCellValue("test2");
  583. // write the second excel file
  584. readBack = XSSFTestDataSamples.writeOutAndReadBack(workbook);
  585. assertNotNull(readBack);
  586. assertEquals("test1", readBack.getSheetAt(0).getRow(2).getCell(3).getStringCellValue());
  587. assertEquals("test2", readBack.getSheetAt(0).getRow(2).getCell(4).getStringCellValue());
  588. }
  589. @Test
  590. public void bug51158a() throws IOException {
  591. // create a workbook
  592. final XSSFWorkbook workbook = new XSSFWorkbook();
  593. try {
  594. workbook.createSheet("Test Sheet");
  595. XSSFSheet sheetBack = workbook.getSheetAt(0);
  596. // committing twice did add the XML twice without clearing the part in between
  597. sheetBack.commit();
  598. // ensure that a memory based package part does not have lingering data from previous commit() calls
  599. if(sheetBack.getPackagePart() instanceof MemoryPackagePart) {
  600. ((MemoryPackagePart)sheetBack.getPackagePart()).clear();
  601. }
  602. sheetBack.commit();
  603. String str = new String(IOUtils.toByteArray(sheetBack.getPackagePart().getInputStream()));
  604. System.out.println(str);
  605. assertEquals(1, countMatches(str, "<worksheet"));
  606. } finally {
  607. workbook.close();
  608. }
  609. }
  610. private static final int INDEX_NOT_FOUND = -1;
  611. private static boolean isEmpty(CharSequence cs) {
  612. return cs == null || cs.length() == 0;
  613. }
  614. private static int countMatches(CharSequence str, CharSequence sub) {
  615. if (isEmpty(str) || isEmpty(sub)) {
  616. return 0;
  617. }
  618. int count = 0;
  619. int idx = 0;
  620. while ((idx = indexOf(str, sub, idx)) != INDEX_NOT_FOUND) {
  621. count++;
  622. idx += sub.length();
  623. }
  624. return count;
  625. }
  626. private static int indexOf(CharSequence cs, CharSequence searchChar, int start) {
  627. return cs.toString().indexOf(searchChar.toString(), start);
  628. }
  629. @Test
  630. public void testAddPivotCache() throws IOException {
  631. XSSFWorkbook wb = new XSSFWorkbook();
  632. try {
  633. CTWorkbook ctWb = wb.getCTWorkbook();
  634. CTPivotCache pivotCache = wb.addPivotCache("0");
  635. //Ensures that pivotCaches is initiated
  636. assertTrue(ctWb.isSetPivotCaches());
  637. assertSame(pivotCache, ctWb.getPivotCaches().getPivotCacheArray(0));
  638. assertEquals("0", pivotCache.getId());
  639. } finally {
  640. wb.close();
  641. }
  642. }
  643. public void setPivotData(XSSFWorkbook wb){
  644. XSSFSheet sheet = wb.createSheet();
  645. Row row1 = sheet.createRow(0);
  646. // Create a cell and put a value in it.
  647. Cell cell = row1.createCell(0);
  648. cell.setCellValue("Names");
  649. Cell cell2 = row1.createCell(1);
  650. cell2.setCellValue("#");
  651. Cell cell7 = row1.createCell(2);
  652. cell7.setCellValue("Data");
  653. Row row2 = sheet.createRow(1);
  654. Cell cell3 = row2.createCell(0);
  655. cell3.setCellValue("Jan");
  656. Cell cell4 = row2.createCell(1);
  657. cell4.setCellValue(10);
  658. Cell cell8 = row2.createCell(2);
  659. cell8.setCellValue("Apa");
  660. Row row3 = sheet.createRow(2);
  661. Cell cell5 = row3.createCell(0);
  662. cell5.setCellValue("Ben");
  663. Cell cell6 = row3.createCell(1);
  664. cell6.setCellValue(9);
  665. Cell cell9 = row3.createCell(2);
  666. cell9.setCellValue("Bepa");
  667. AreaReference source = new AreaReference("A1:B2", SpreadsheetVersion.EXCEL2007);
  668. sheet.createPivotTable(source, new CellReference("H5"));
  669. }
  670. @Test
  671. public void testLoadWorkbookWithPivotTable() throws Exception {
  672. File file = TempFile.createTempFile("ooxml-pivottable", ".xlsx");
  673. XSSFWorkbook wb = new XSSFWorkbook();
  674. try {
  675. setPivotData(wb);
  676. FileOutputStream fileOut = new FileOutputStream(file);
  677. wb.write(fileOut);
  678. fileOut.close();
  679. } finally {
  680. wb.close();
  681. }
  682. XSSFWorkbook wb2 = (XSSFWorkbook) WorkbookFactory.create(file);
  683. try {
  684. assertTrue(wb2.getPivotTables().size() == 1);
  685. } finally {
  686. wb2.close();
  687. }
  688. assertTrue(file.delete());
  689. }
  690. @Test
  691. public void testAddPivotTableToWorkbookWithLoadedPivotTable() throws Exception {
  692. File file = TempFile.createTempFile("ooxml-pivottable", ".xlsx");
  693. XSSFWorkbook wb = new XSSFWorkbook();
  694. try {
  695. setPivotData(wb);
  696. FileOutputStream fileOut = new FileOutputStream(file);
  697. try {
  698. wb.write(fileOut);
  699. } finally {
  700. fileOut.close();
  701. }
  702. } finally {
  703. wb.close();
  704. }
  705. XSSFWorkbook wb2 = (XSSFWorkbook) WorkbookFactory.create(file);
  706. try {
  707. setPivotData(wb2);
  708. assertTrue(wb2.getPivotTables().size() == 2);
  709. } finally {
  710. wb2.close();
  711. }
  712. assertTrue(file.delete());
  713. }
  714. @Test
  715. public void testSetFirstVisibleTab_57373() throws IOException {
  716. Workbook wb = new XSSFWorkbook();
  717. try {
  718. /*Sheet sheet1 =*/ wb.createSheet();
  719. Sheet sheet2 = wb.createSheet();
  720. int idx2 = wb.getSheetIndex(sheet2);
  721. Sheet sheet3 = wb.createSheet();
  722. int idx3 = wb.getSheetIndex(sheet3);
  723. // add many sheets so "first visible" is relevant
  724. for(int i = 0; i < 30;i++) {
  725. wb.createSheet();
  726. }
  727. wb.setFirstVisibleTab(idx2);
  728. wb.setActiveSheet(idx3);
  729. //wb.write(new FileOutputStream(new File("C:\\temp\\test.xlsx")));
  730. assertEquals(idx2, wb.getFirstVisibleTab());
  731. assertEquals(idx3, wb.getActiveSheetIndex());
  732. Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
  733. sheet2 = wbBack.getSheetAt(idx2);
  734. sheet3 = wbBack.getSheetAt(idx3);
  735. assertEquals(idx2, wb.getFirstVisibleTab());
  736. assertEquals(idx3, wb.getActiveSheetIndex());
  737. } finally {
  738. wb.close();
  739. }
  740. }
  741. /**
  742. * Tests that we can save a workbook with macros and reload it.
  743. */
  744. @Test
  745. public void testSetVBAProject() throws Exception {
  746. XSSFWorkbook workbook = null;
  747. OutputStream out = null;
  748. File file;
  749. final byte[] allBytes = new byte[256];
  750. for (int i = 0; i < 256; i++) {
  751. allBytes[i] = (byte) (i - 128);
  752. }
  753. try {
  754. workbook = new XSSFWorkbook();
  755. workbook.createSheet();
  756. workbook.setVBAProject(new ByteArrayInputStream(allBytes));
  757. file = TempFile.createTempFile("poi-", ".xlsm");
  758. out = new FileOutputStream(file);
  759. workbook.write(out);
  760. }
  761. finally {
  762. IOUtils.closeQuietly(out);
  763. IOUtils.closeQuietly(workbook);
  764. }
  765. try {
  766. // Check the package contains what we'd expect it to
  767. OPCPackage pkg = OPCPackage.open(file.toString());
  768. PackagePart wbPart = pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
  769. assertTrue(wbPart.hasRelationships());
  770. final PackageRelationshipCollection relationships = wbPart.getRelationships().getRelationships(XSSFRelation.VBA_MACROS.getRelation());
  771. assertEquals(1, relationships.size());
  772. assertEquals(XSSFRelation.VBA_MACROS.getDefaultFileName(), relationships.getRelationship(0).getTargetURI().toString());
  773. PackagePart vbaPart = pkg.getPart(PackagingURIHelper.createPartName(XSSFRelation.VBA_MACROS.getDefaultFileName()));
  774. assertNotNull(vbaPart);
  775. assertFalse(vbaPart.isRelationshipPart());
  776. assertEquals(XSSFRelation.VBA_MACROS.getContentType(), vbaPart.getContentType());
  777. final byte[] fromFile = IOUtils.toByteArray(vbaPart.getInputStream());
  778. assertArrayEquals(allBytes, fromFile);
  779. // Load back the XSSFWorkbook just to check nothing explodes
  780. workbook = new XSSFWorkbook(pkg);
  781. assertEquals(1, workbook.getNumberOfSheets());
  782. assertEquals(XSSFWorkbookType.XLSM, workbook.getWorkbookType());
  783. }
  784. finally {
  785. IOUtils.closeQuietly(workbook);
  786. }
  787. }
  788. @Test
  789. public void testBug54399() throws IOException {
  790. XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("54399.xlsx");
  791. //System.out.println("sheets:" + workbook.getNumberOfSheets());
  792. for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
  793. //System.out.println("i:" + i);
  794. workbook.setSheetName(i, "SheetRenamed" + (i + 1));
  795. }
  796. // FileOutputStream fileOutputStream = new FileOutputStream("/tmp/54399.xlsx");
  797. // workbook.write(fileOutputStream);
  798. // fileOutputStream.close();
  799. }
  800. @SuppressWarnings("unchecked")
  801. @Test
  802. /**
  803. * Iterator<XSSFSheet> XSSFWorkbook.iterator was committed in r700472 on 2008-09-30
  804. * and has been replaced with Iterator<Sheet> XSSFWorkbook.iterator
  805. *
  806. * In order to make code for looping over sheets in workbooks standard, regardless
  807. * of the type of workbook (HSSFWorkbook, XSSFWorkbook, SXSSFWorkbook), the previously
  808. * available Iterator<XSSFSheet> iterator and Iterator<XSSFSheet> sheetIterator
  809. * have been replaced with Iterator<Sheet> {@link #iterator} and
  810. * Iterator<Sheet> {@link #sheetIterator}. This makes iterating over sheets in a workbook
  811. * similar to iterating over rows in a sheet and cells in a row.
  812. *
  813. * Note: this breaks backwards compatibility! Existing codebases will need to
  814. * upgrade their code with either of the following options presented in this test case.
  815. *
  816. */
  817. public void bug58245_XSSFSheetIterator() {
  818. final XSSFWorkbook wb = new XSSFWorkbook();
  819. try {
  820. wb.createSheet();
  821. // =====================================================================
  822. // Case 1: Existing code uses XSSFSheet for-each loop
  823. // =====================================================================
  824. // Original code (no longer valid)
  825. /*
  826. for (XSSFSheet sh : wb) {
  827. sh.createRow(0);
  828. }
  829. */
  830. // Option A:
  831. for (XSSFSheet sh : (Iterable<XSSFSheet>) (Iterable<? extends Sheet>) wb) {
  832. sh.createRow(0);
  833. }
  834. // Option B (preferred for new code):
  835. for (Sheet sh : wb) {
  836. sh.createRow(0);
  837. }
  838. // =====================================================================
  839. // Case 2: Existing code creates an iterator variable
  840. // =====================================================================
  841. // Original code (no longer valid)
  842. /*
  843. Iterator<XSSFSheet> it = wb.iterator();
  844. XSSFSheet sh = it.next();
  845. sh.createRow(0);
  846. */
  847. // Option A:
  848. {
  849. Iterator<XSSFSheet> it = (Iterator<XSSFSheet>) (Iterator<? extends Sheet>) wb.iterator();
  850. XSSFSheet sh = it.next();
  851. sh.createRow(0);
  852. }
  853. // Option B:
  854. {
  855. @SuppressWarnings("deprecation")
  856. Iterator<XSSFSheet> it = wb.xssfSheetIterator();
  857. XSSFSheet sh = it.next();
  858. sh.createRow(0);
  859. }
  860. // Option C (preferred for new code):
  861. {
  862. Iterator<Sheet> it = wb.iterator();
  863. Sheet sh = it.next();
  864. sh.createRow(0);
  865. }
  866. }
  867. finally {
  868. IOUtils.closeQuietly(wb);
  869. }
  870. }
  871. @Test
  872. public void testBug56957CloseWorkbook() throws Exception {
  873. File file = TempFile.createTempFile("TestBug56957_", ".xlsx");
  874. try {
  875. // as the file is written to, we make a copy before actually working on it
  876. FileHelper.copyFile(new File("test-data/spreadsheet/56957.xlsx"), file);
  877. assertTrue(file.exists());
  878. // read-only mode works!
  879. Workbook workbook = WorkbookFactory.create(OPCPackage.open(file, PackageAccess.READ));
  880. System.out.println(workbook.getSheetAt(0).getRow(0).getCell(0, Row.CREATE_NULL_AS_BLANK).getDateCellValue().toString());
  881. workbook.close();
  882. workbook = null;
  883. workbook = WorkbookFactory.create(OPCPackage.open(file, PackageAccess.READ));
  884. System.out.println(workbook.getSheetAt(0).getRow(0).getCell(0, Row.CREATE_NULL_AS_BLANK).getDateCellValue().toString());
  885. workbook.close();
  886. workbook = null;
  887. // now check read/write mode
  888. workbook = WorkbookFactory.create(OPCPackage.open(file, PackageAccess.READ_WRITE));
  889. System.out.println(workbook.getSheetAt(0).getRow(0).getCell(0, Row.CREATE_NULL_AS_BLANK).getDateCellValue().toString());
  890. workbook.close();
  891. workbook = null;
  892. workbook = WorkbookFactory.create(OPCPackage.open(file, PackageAccess.READ_WRITE));
  893. System.out.println(workbook.getSheetAt(0).getRow(0).getCell(0, Row.CREATE_NULL_AS_BLANK).getDateCellValue().toString());
  894. workbook.close();
  895. workbook = null;
  896. } finally {
  897. assertTrue(file.exists());
  898. assertTrue(file.delete());
  899. }
  900. }
  901. }