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

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439
  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 org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
  17. import org.apache.poi.POIDataSamples;
  18. import org.apache.poi.hssf.HSSFTestDataSamples;
  19. import org.apache.poi.ooxml.POIXMLProperties;
  20. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  21. import org.apache.poi.openxml4j.opc.ContentTypes;
  22. import org.apache.poi.openxml4j.opc.OPCPackage;
  23. import org.apache.poi.openxml4j.opc.PackageAccess;
  24. import org.apache.poi.openxml4j.opc.PackagePart;
  25. import org.apache.poi.openxml4j.opc.PackagePartName;
  26. import org.apache.poi.openxml4j.opc.PackageRelationship;
  27. import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
  28. import org.apache.poi.openxml4j.opc.PackagingURIHelper;
  29. import org.apache.poi.openxml4j.opc.ZipPackage;
  30. import org.apache.poi.openxml4j.opc.internal.FileHelper;
  31. import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
  32. import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
  33. import org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource;
  34. import org.apache.poi.ss.tests.usermodel.BaseTestXWorkbook;
  35. import org.apache.poi.ss.usermodel.Cell;
  36. import org.apache.poi.ss.usermodel.CellReferenceType;
  37. import org.apache.poi.ss.usermodel.CellStyle;
  38. import org.apache.poi.ss.usermodel.Comment;
  39. import org.apache.poi.ss.usermodel.DataFormatter;
  40. import org.apache.poi.ss.usermodel.Font;
  41. import org.apache.poi.ss.usermodel.FormulaError;
  42. import org.apache.poi.ss.usermodel.FormulaEvaluator;
  43. import org.apache.poi.ss.usermodel.RichTextString;
  44. import org.apache.poi.ss.usermodel.Row;
  45. import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
  46. import org.apache.poi.ss.usermodel.Sheet;
  47. import org.apache.poi.ss.usermodel.Workbook;
  48. import org.apache.poi.ss.usermodel.WorkbookFactory;
  49. import org.apache.poi.ss.util.AreaReference;
  50. import org.apache.poi.ss.util.CellAddress;
  51. import org.apache.poi.ss.util.CellReference;
  52. import org.apache.poi.util.IOUtils;
  53. import org.apache.poi.util.LocaleUtil;
  54. import org.apache.poi.util.TempFile;
  55. import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData;
  56. import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
  57. import org.apache.poi.xssf.XSSFITestDataProvider;
  58. import org.apache.poi.xssf.model.StylesTable;
  59. import org.junit.jupiter.api.Test;
  60. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr;
  61. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalLink;
  62. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalSheetData;
  63. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCache;
  64. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
  65. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr;
  66. import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode;
  67. import java.io.ByteArrayInputStream;
  68. import java.io.File;
  69. import java.io.FileInputStream;
  70. import java.io.FileOutputStream;
  71. import java.io.IOException;
  72. import java.nio.charset.StandardCharsets;
  73. import java.util.Date;
  74. import java.util.Iterator;
  75. import java.util.List;
  76. import java.util.zip.CRC32;
  77. import static org.apache.commons.io.output.NullOutputStream.NULL_OUTPUT_STREAM;
  78. import static org.apache.poi.hssf.HSSFTestDataSamples.openSampleFileStream;
  79. import static org.apache.poi.xssf.XSSFTestDataSamples.openSampleWorkbook;
  80. import static org.apache.poi.xssf.XSSFTestDataSamples.writeOut;
  81. import static org.apache.poi.xssf.XSSFTestDataSamples.writeOutAndReadBack;
  82. import static org.junit.jupiter.api.Assertions.assertArrayEquals;
  83. import static org.junit.jupiter.api.Assertions.assertEquals;
  84. import static org.junit.jupiter.api.Assertions.assertFalse;
  85. import static org.junit.jupiter.api.Assertions.assertNotNull;
  86. import static org.junit.jupiter.api.Assertions.assertNull;
  87. import static org.junit.jupiter.api.Assertions.assertSame;
  88. import static org.junit.jupiter.api.Assertions.assertThrows;
  89. import static org.junit.jupiter.api.Assertions.assertTrue;
  90. public final class TestXSSFWorkbook extends BaseTestXWorkbook {
  91. public TestXSSFWorkbook() {
  92. super(XSSFITestDataProvider.instance);
  93. }
  94. /**
  95. * Tests that we can save, and then re-load a new document
  96. */
  97. @Test
  98. void saveLoadNew() throws IOException, InvalidFormatException {
  99. File file;
  100. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  101. //check that the default date system is set to 1900
  102. CTWorkbookPr pr = wb1.getCTWorkbook().getWorkbookPr();
  103. assertNotNull(pr);
  104. assertTrue(pr.isSetDate1904());
  105. assertFalse(pr.getDate1904(), "XSSF must use the 1900 date system");
  106. Sheet sheet1 = wb1.createSheet("sheet1");
  107. Sheet sheet2 = wb1.createSheet("sheet2");
  108. wb1.createSheet("sheet3");
  109. RichTextString rts = wb1.getCreationHelper().createRichTextString("hello world");
  110. sheet1.createRow(0).createCell((short) 0).setCellValue(1.2);
  111. sheet1.createRow(1).createCell((short) 0).setCellValue(rts);
  112. sheet2.createRow(0);
  113. assertEquals(0, wb1.getSheetAt(0).getFirstRowNum());
  114. assertEquals(1, wb1.getSheetAt(0).getLastRowNum());
  115. assertEquals(0, wb1.getSheetAt(1).getFirstRowNum());
  116. assertEquals(0, wb1.getSheetAt(1).getLastRowNum());
  117. assertEquals(-1, wb1.getSheetAt(2).getFirstRowNum());
  118. assertEquals(-1, wb1.getSheetAt(2).getLastRowNum());
  119. file = writeOut(wb1, "poi-.xlsx");
  120. }
  121. // Check the package contains what we'd expect it to
  122. try (OPCPackage pkg = OPCPackage.open(file.toString())) {
  123. PackagePart wbRelPart =
  124. pkg.getPart(PackagingURIHelper.createPartName("/xl/_rels/workbook.xml.rels"));
  125. assertNotNull(wbRelPart);
  126. assertTrue(wbRelPart.isRelationshipPart());
  127. assertEquals(ContentTypes.RELATIONSHIPS_PART, wbRelPart.getContentType());
  128. PackagePart wbPart =
  129. pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
  130. // Links to the three sheets, shared strings and styles
  131. assertTrue(wbPart.hasRelationships());
  132. assertEquals(5, wbPart.getRelationships().size());
  133. // Load back the XSSFWorkbook
  134. try (XSSFWorkbook wb2 = new XSSFWorkbook(pkg)) {
  135. assertEquals(3, wb2.getNumberOfSheets());
  136. assertNotNull(wb2.getSheetAt(0));
  137. assertNotNull(wb2.getSheetAt(1));
  138. assertNotNull(wb2.getSheetAt(2));
  139. assertNotNull(wb2.getSharedStringSource());
  140. assertNotNull(wb2.getStylesSource());
  141. assertEquals(0, wb2.getSheetAt(0).getFirstRowNum());
  142. assertEquals(1, wb2.getSheetAt(0).getLastRowNum());
  143. assertEquals(0, wb2.getSheetAt(1).getFirstRowNum());
  144. assertEquals(0, wb2.getSheetAt(1).getLastRowNum());
  145. assertEquals(-1, wb2.getSheetAt(2).getFirstRowNum());
  146. assertEquals(-1, wb2.getSheetAt(2).getLastRowNum());
  147. Sheet sheet1 = wb2.getSheetAt(0);
  148. assertEquals(1.2, sheet1.getRow(0).getCell(0).getNumericCellValue(), 0.0001);
  149. assertEquals("hello world", sheet1.getRow(1).getCell(0).getRichStringCellValue().getString());
  150. }
  151. }
  152. }
  153. @Test
  154. void existing() throws Exception {
  155. try (XSSFWorkbook workbook = openSampleWorkbook("Formatting.xlsx");
  156. OPCPackage pkg = OPCPackage.open(openSampleFileStream("Formatting.xlsx"))) {
  157. assertNotNull(workbook.getSharedStringSource());
  158. assertNotNull(workbook.getStylesSource());
  159. // And check a few low level bits too
  160. PackagePart wbPart = pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
  161. // Links to the three sheets, shared, styles and themes
  162. assertTrue(wbPart.hasRelationships());
  163. assertEquals(6, wbPart.getRelationships().size());
  164. }
  165. }
  166. @Test
  167. void existingWithZipEntryTempFiles() throws Exception {
  168. int defaultThreshold = ZipInputStreamZipEntrySource.getThresholdBytesForTempFiles();
  169. ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(100);
  170. try (XSSFWorkbook workbook = openSampleWorkbook("Formatting.xlsx");
  171. OPCPackage pkg = OPCPackage.open(openSampleFileStream("Formatting.xlsx"))) {
  172. assertNotNull(workbook.getSharedStringSource());
  173. assertNotNull(workbook.getStylesSource());
  174. // And check a few low level bits too
  175. PackagePart wbPart = pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
  176. // Links to the three sheets, shared, styles and themes
  177. assertTrue(wbPart.hasRelationships());
  178. assertEquals(6, wbPart.getRelationships().size());
  179. } finally {
  180. ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(defaultThreshold);
  181. }
  182. }
  183. @Test
  184. void existingWithZipEntryEncryptedTempFiles() throws Exception {
  185. int defaultThreshold = ZipInputStreamZipEntrySource.getThresholdBytesForTempFiles();
  186. boolean defaultEncryptFlag = ZipInputStreamZipEntrySource.shouldEncryptTempFiles();
  187. ZipInputStreamZipEntrySource.setEncryptTempFiles(true);
  188. ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(100);
  189. try (XSSFWorkbook workbook = openSampleWorkbook("Formatting.xlsx");
  190. OPCPackage pkg = OPCPackage.open(openSampleFileStream("Formatting.xlsx"))) {
  191. assertNotNull(workbook.getSharedStringSource());
  192. assertNotNull(workbook.getStylesSource());
  193. // And check a few low level bits too
  194. PackagePart wbPart = pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
  195. // Links to the three sheets, shared, styles and themes
  196. assertTrue(wbPart.hasRelationships());
  197. assertEquals(6, wbPart.getRelationships().size());
  198. } finally {
  199. ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(defaultThreshold);
  200. ZipInputStreamZipEntrySource.setEncryptTempFiles(defaultEncryptFlag);
  201. }
  202. }
  203. @Test
  204. void getCellStyleAt() throws IOException{
  205. try (XSSFWorkbook workbook = new XSSFWorkbook()) {
  206. short i = 0;
  207. //get default style
  208. CellStyle cellStyleAt = workbook.getCellStyleAt(i);
  209. assertNotNull(cellStyleAt);
  210. //get custom style
  211. StylesTable styleSource = workbook.getStylesSource();
  212. XSSFCellStyle customStyle = new XSSFCellStyle(styleSource);
  213. XSSFFont font = new XSSFFont();
  214. font.setFontName("Verdana");
  215. customStyle.setFont(font);
  216. int x = styleSource.putStyle(customStyle);
  217. cellStyleAt = workbook.getCellStyleAt((short) x);
  218. assertNotNull(cellStyleAt);
  219. }
  220. }
  221. @Test
  222. void getFontAt() throws IOException{
  223. try (XSSFWorkbook workbook = new XSSFWorkbook()) {
  224. StylesTable styleSource = workbook.getStylesSource();
  225. short i = 0;
  226. //get default font
  227. Font fontAt = workbook.getFontAt(i);
  228. assertNotNull(fontAt);
  229. //get customized font
  230. XSSFFont customFont = new XSSFFont();
  231. customFont.setItalic(true);
  232. int x = styleSource.putFont(customFont);
  233. fontAt = workbook.getFontAt((short) x);
  234. assertNotNull(fontAt);
  235. }
  236. }
  237. @Test
  238. void getNumCellStyles() throws IOException{
  239. try (XSSFWorkbook workbook = new XSSFWorkbook()) {
  240. //get default cellStyles
  241. assertEquals(1, workbook.getNumCellStyles());
  242. }
  243. }
  244. @Test
  245. void loadSave() throws IOException {
  246. XSSFWorkbook workbook = openSampleWorkbook("Formatting.xlsx");
  247. assertEquals(3, workbook.getNumberOfSheets());
  248. assertEquals("dd/mm/yyyy", workbook.getSheetAt(0).getRow(1).getCell(0).getRichStringCellValue().getString());
  249. assertNotNull(workbook.getSharedStringSource());
  250. assertNotNull(workbook.getStylesSource());
  251. // Write out, and check
  252. // Load up again, check all still there
  253. XSSFWorkbook wb2 = writeOutAndReadBack(workbook);
  254. assertEquals(3, wb2.getNumberOfSheets());
  255. assertNotNull(wb2.getSheetAt(0));
  256. assertNotNull(wb2.getSheetAt(1));
  257. assertNotNull(wb2.getSheetAt(2));
  258. assertEquals("dd/mm/yyyy", wb2.getSheetAt(0).getRow(1).getCell(0).getRichStringCellValue().getString());
  259. assertEquals("yyyy/mm/dd", wb2.getSheetAt(0).getRow(2).getCell(0).getRichStringCellValue().getString());
  260. assertEquals("yyyy-mm-dd", wb2.getSheetAt(0).getRow(3).getCell(0).getRichStringCellValue().getString());
  261. assertEquals("yy/mm/dd", wb2.getSheetAt(0).getRow(4).getCell(0).getRichStringCellValue().getString());
  262. assertNotNull(wb2.getSharedStringSource());
  263. assertNotNull(wb2.getStylesSource());
  264. workbook.close();
  265. wb2.close();
  266. }
  267. @Test
  268. void styles() throws IOException {
  269. try (XSSFWorkbook wb1 = openSampleWorkbook("Formatting.xlsx")) {
  270. StylesTable ss = wb1.getStylesSource();
  271. assertNotNull(ss);
  272. StylesTable st = ss;
  273. // Has 8 number formats
  274. assertEquals(8, st.getNumDataFormats());
  275. // Has 2 fonts
  276. assertEquals(2, st.getFonts().size());
  277. // Has 2 fills
  278. assertEquals(2, st.getFills().size());
  279. // Has 1 border
  280. assertEquals(1, st.getBorders().size());
  281. // Add two more styles
  282. assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 8,
  283. st.putNumberFormat("testFORMAT"));
  284. assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 8,
  285. st.putNumberFormat("testFORMAT"));
  286. assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 9,
  287. st.putNumberFormat("testFORMAT2"));
  288. assertEquals(10, st.getNumDataFormats());
  289. // Save, load back in again, and check
  290. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  291. ss = wb2.getStylesSource();
  292. assertNotNull(ss);
  293. assertEquals(10, st.getNumDataFormats());
  294. assertEquals(2, st.getFonts().size());
  295. assertEquals(2, st.getFills().size());
  296. assertEquals(1, st.getBorders().size());
  297. }
  298. }
  299. }
  300. @Test
  301. void incrementSheetId() throws IOException {
  302. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  303. int sheetId = (int) wb.createSheet().sheet.getSheetId();
  304. assertEquals(1, sheetId);
  305. sheetId = (int) wb.createSheet().sheet.getSheetId();
  306. assertEquals(2, sheetId);
  307. //test file with gaps in the sheetId sequence
  308. try (XSSFWorkbook wbBack = openSampleWorkbook("47089.xlsm")) {
  309. int lastSheetId = (int) wbBack.getSheetAt(wbBack.getNumberOfSheets() - 1).sheet.getSheetId();
  310. sheetId = (int) wbBack.createSheet().sheet.getSheetId();
  311. assertEquals(lastSheetId + 1, sheetId);
  312. }
  313. }
  314. }
  315. /**
  316. * Test setting of core properties such as Title and Author
  317. */
  318. @Test
  319. void workbookProperties() throws IOException {
  320. try (XSSFWorkbook workbook = new XSSFWorkbook()) {
  321. POIXMLProperties props = workbook.getProperties();
  322. assertNotNull(props);
  323. //the Application property must be set for new workbooks, see Bugzilla #47559
  324. assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication());
  325. PackagePropertiesPart opcProps = props.getCoreProperties().getUnderlyingProperties();
  326. assertNotNull(opcProps);
  327. opcProps.setTitleProperty("Testing Bugzilla #47460");
  328. assertEquals("Apache POI", opcProps.getCreatorProperty().orElse(""));
  329. opcProps.setCreatorProperty("poi-dev@poi.apache.org");
  330. try (XSSFWorkbook wbBack = writeOutAndReadBack(workbook)) {
  331. assertEquals("Apache POI", wbBack.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
  332. opcProps = wbBack.getProperties().getCoreProperties().getUnderlyingProperties();
  333. assertEquals("Testing Bugzilla #47460", opcProps.getTitleProperty().orElse(""));
  334. assertEquals("poi-dev@poi.apache.org", opcProps.getCreatorProperty().orElse(""));
  335. }
  336. }
  337. }
  338. /**
  339. * Verify that the attached test data was not modified. If this test method
  340. * fails, the test data is not working properly.
  341. */
  342. @Test
  343. void bug47668() throws Exception {
  344. try (XSSFWorkbook workbook = openSampleWorkbook("47668.xlsx")) {
  345. List<XSSFPictureData> allPictures = workbook.getAllPictures();
  346. assertEquals(1, allPictures.size());
  347. PackagePartName imagePartName = PackagingURIHelper
  348. .createPartName("/xl/media/image1.jpeg");
  349. PackagePart imagePart = workbook.getPackage().getPart(imagePartName);
  350. assertNotNull(imagePart);
  351. for (XSSFPictureData pictureData : allPictures) {
  352. PackagePart picturePart = pictureData.getPackagePart();
  353. assertSame(imagePart, picturePart);
  354. }
  355. XSSFSheet sheet0 = workbook.getSheetAt(0);
  356. XSSFDrawing drawing0 = sheet0.createDrawingPatriarch();
  357. XSSFPictureData pictureData0 = (XSSFPictureData) drawing0.getRelations().get(0);
  358. byte[] data0 = pictureData0.getData();
  359. CRC32 crc0 = new CRC32();
  360. crc0.update(data0);
  361. XSSFSheet sheet1 = workbook.getSheetAt(1);
  362. XSSFDrawing drawing1 = sheet1.createDrawingPatriarch();
  363. XSSFPictureData pictureData1 = (XSSFPictureData) drawing1.getRelations().get(0);
  364. byte[] data1 = pictureData1.getData();
  365. CRC32 crc1 = new CRC32();
  366. crc1.update(data1);
  367. assertEquals(crc0.getValue(), crc1.getValue());
  368. }
  369. }
  370. /**
  371. * When deleting a sheet make sure that we adjust sheet indices of named ranges
  372. */
  373. @SuppressWarnings("deprecation")
  374. @Test
  375. void bug47737() throws IOException {
  376. try (XSSFWorkbook wb = openSampleWorkbook("47737.xlsx")) {
  377. assertEquals(2, wb.getNumberOfNames());
  378. assertNotNull(wb.getCalculationChain());
  379. XSSFName nm0 = wb.getNameAt(0);
  380. assertTrue(nm0.getCTName().isSetLocalSheetId());
  381. assertEquals(0, nm0.getCTName().getLocalSheetId());
  382. XSSFName nm1 = wb.getNameAt(1);
  383. assertTrue(nm1.getCTName().isSetLocalSheetId());
  384. assertEquals(1, nm1.getCTName().getLocalSheetId());
  385. wb.removeSheetAt(0);
  386. assertEquals(1, wb.getNumberOfNames());
  387. XSSFName nm2 = wb.getNameAt(0);
  388. assertTrue(nm2.getCTName().isSetLocalSheetId());
  389. assertEquals(0, nm2.getCTName().getLocalSheetId());
  390. //calculation chain is removed as well
  391. assertNull(wb.getCalculationChain());
  392. }
  393. }
  394. /**
  395. * Problems with XSSFWorkbook.removeSheetAt when workbook contains charts
  396. */
  397. @Test
  398. void bug47813() throws IOException {
  399. try (XSSFWorkbook wb1 = openSampleWorkbook("47813.xlsx")) {
  400. assertEquals(3, wb1.getNumberOfSheets());
  401. assertNotNull(wb1.getCalculationChain());
  402. assertEquals("Numbers", wb1.getSheetName(0));
  403. //the second sheet is of type 'chartsheet'
  404. assertEquals("Chart", wb1.getSheetName(1));
  405. assertTrue(wb1.getSheetAt(1) instanceof XSSFChartSheet);
  406. assertEquals("SomeJunk", wb1.getSheetName(2));
  407. wb1.removeSheetAt(2);
  408. assertEquals(2, wb1.getNumberOfSheets());
  409. assertNull(wb1.getCalculationChain());
  410. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  411. assertEquals(2, wb2.getNumberOfSheets());
  412. assertNull(wb2.getCalculationChain());
  413. assertEquals("Numbers", wb2.getSheetName(0));
  414. assertEquals("Chart", wb2.getSheetName(1));
  415. }
  416. }
  417. }
  418. /**
  419. * Problems with the count of the number of styles
  420. * coming out wrong
  421. */
  422. @Test
  423. void bug49702() throws IOException {
  424. // First try with a new file
  425. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  426. // Should have one style
  427. assertEquals(1, wb1.getNumCellStyles());
  428. wb1.getCellStyleAt((short) 0);
  429. assertNull(wb1.getCellStyleAt((short) 1), "Shouldn't be able to get style at 0 that doesn't exist");
  430. // Add another one
  431. CellStyle cs = wb1.createCellStyle();
  432. cs.setDataFormat((short) 11);
  433. // Re-check
  434. assertEquals(2, wb1.getNumCellStyles());
  435. wb1.getCellStyleAt((short) 0);
  436. wb1.getCellStyleAt((short) 1);
  437. assertNull(wb1.getCellStyleAt((short) 2), "Shouldn't be able to get style at 2 that doesn't exist");
  438. // Save and reload
  439. try (XSSFWorkbook nwb = writeOutAndReadBack(wb1)) {
  440. assertEquals(2, nwb.getNumCellStyles());
  441. nwb.getCellStyleAt((short) 0);
  442. nwb.getCellStyleAt((short) 1);
  443. assertNull(nwb.getCellStyleAt((short) 2), "Shouldn't be able to get style at 2 that doesn't exist");
  444. // Now with an existing file
  445. try (XSSFWorkbook wb2 = openSampleWorkbook("sample.xlsx")) {
  446. assertEquals(3, wb2.getNumCellStyles());
  447. wb2.getCellStyleAt((short) 0);
  448. wb2.getCellStyleAt((short) 1);
  449. wb2.getCellStyleAt((short) 2);
  450. assertNull(wb2.getCellStyleAt((short) 3), "Shouldn't be able to get style at 3 that doesn't exist");
  451. }
  452. }
  453. }
  454. }
  455. @Test
  456. void recalcId() throws IOException {
  457. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  458. assertFalse(wb.getForceFormulaRecalculation());
  459. CTWorkbook ctWorkbook = wb.getCTWorkbook();
  460. assertFalse(ctWorkbook.isSetCalcPr());
  461. wb.setForceFormulaRecalculation(true);
  462. CTCalcPr calcPr = ctWorkbook.getCalcPr();
  463. assertNotNull(calcPr);
  464. assertEquals(0, (int) calcPr.getCalcId());
  465. calcPr.setCalcId(100);
  466. assertTrue(wb.getForceFormulaRecalculation());
  467. wb.setForceFormulaRecalculation(false);
  468. assertFalse(wb.getForceFormulaRecalculation());
  469. // calcMode="manual" is unset when forceFormulaRecalculation=true
  470. calcPr.setCalcMode(STCalcMode.MANUAL);
  471. wb.setForceFormulaRecalculation(true);
  472. assertSame(STCalcMode.AUTO, calcPr.getCalcMode());
  473. assertTrue(wb.getForceFormulaRecalculation());
  474. wb.setForceFormulaRecalculation(false);
  475. assertFalse(wb.getForceFormulaRecalculation());
  476. wb.setForceFormulaRecalculation(true);
  477. assertTrue(wb.getForceFormulaRecalculation());
  478. }
  479. }
  480. @Test
  481. void columnWidthPOI52233() throws Exception {
  482. try (XSSFWorkbook workbook = new XSSFWorkbook()) {
  483. XSSFSheet sheet = workbook.createSheet();
  484. XSSFRow row = sheet.createRow(0);
  485. XSSFCell cell = row.createCell(0);
  486. cell.setCellValue("hello world");
  487. sheet = workbook.createSheet();
  488. sheet.setColumnWidth(4, 5000);
  489. sheet.setColumnWidth(5, 5000);
  490. sheet.groupColumn((short) 4, (short) 5);
  491. accessWorkbook(workbook);
  492. workbook.write(NULL_OUTPUT_STREAM);
  493. accessWorkbook(workbook);
  494. }
  495. }
  496. private void accessWorkbook(XSSFWorkbook workbook) {
  497. workbook.getSheetAt(1).setColumnGroupCollapsed(4, true);
  498. workbook.getSheetAt(1).setColumnGroupCollapsed(4, false);
  499. assertEquals("hello world", workbook.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());
  500. assertEquals(2048, workbook.getSheetAt(0).getColumnWidth(0)); // <-works
  501. }
  502. @Test
  503. void bug48495() throws IOException {
  504. try (Workbook wb = openSampleWorkbook("48495.xlsx")) {
  505. assertSheetOrder(wb, "Sheet1");
  506. Sheet sheet = wb.getSheetAt(0);
  507. sheet.shiftRows(2, sheet.getLastRowNum(), 1, true, false);
  508. Row newRow = sheet.getRow(2);
  509. if (newRow == null) {
  510. newRow = sheet.createRow(2);
  511. }
  512. newRow.createCell(0).setCellValue(" Another Header");
  513. wb.cloneSheet(0);
  514. assertSheetOrder(wb, "Sheet1", "Sheet1 (2)");
  515. try (Workbook read = writeOutAndReadBack(wb)) {
  516. assertNotNull(read);
  517. assertSheetOrder(read, "Sheet1", "Sheet1 (2)");
  518. }
  519. }
  520. }
  521. @Test
  522. void bug47090a() throws IOException {
  523. try (Workbook workbook = openSampleWorkbook("47090.xlsx")) {
  524. assertSheetOrder(workbook, "Sheet1", "Sheet2");
  525. workbook.removeSheetAt(0);
  526. assertSheetOrder(workbook, "Sheet2");
  527. workbook.createSheet();
  528. assertSheetOrder(workbook, "Sheet2", "Sheet1");
  529. try (Workbook read = writeOutAndReadBack(workbook)) {
  530. assertSheetOrder(read, "Sheet2", "Sheet1");
  531. }
  532. }
  533. }
  534. @Test
  535. void bug47090b() throws IOException {
  536. try (Workbook workbook = openSampleWorkbook("47090.xlsx")) {
  537. assertSheetOrder(workbook, "Sheet1", "Sheet2");
  538. workbook.removeSheetAt(1);
  539. assertSheetOrder(workbook, "Sheet1");
  540. workbook.createSheet();
  541. assertSheetOrder(workbook, "Sheet1", "Sheet0"); // Sheet0 because it uses "Sheet" + sheets.size() as starting point!
  542. try (Workbook read = writeOutAndReadBack(workbook)) {
  543. assertSheetOrder(read, "Sheet1", "Sheet0");
  544. }
  545. }
  546. }
  547. @Test
  548. void bug47090c() throws IOException {
  549. try (Workbook workbook = openSampleWorkbook("47090.xlsx")) {
  550. assertSheetOrder(workbook, "Sheet1", "Sheet2");
  551. workbook.removeSheetAt(0);
  552. assertSheetOrder(workbook, "Sheet2");
  553. workbook.cloneSheet(0);
  554. assertSheetOrder(workbook, "Sheet2", "Sheet2 (2)");
  555. try (Workbook read = writeOutAndReadBack(workbook)) {
  556. assertSheetOrder(read, "Sheet2", "Sheet2 (2)");
  557. }
  558. }
  559. }
  560. @Test
  561. void bug47090d() throws IOException {
  562. try (Workbook workbook = openSampleWorkbook("47090.xlsx")) {
  563. assertSheetOrder(workbook, "Sheet1", "Sheet2");
  564. workbook.createSheet();
  565. assertSheetOrder(workbook, "Sheet1", "Sheet2", "Sheet0");
  566. workbook.removeSheetAt(0);
  567. assertSheetOrder(workbook, "Sheet2", "Sheet0");
  568. workbook.createSheet();
  569. assertSheetOrder(workbook, "Sheet2", "Sheet0", "Sheet1");
  570. try (Workbook read = writeOutAndReadBack(workbook)) {
  571. assertSheetOrder(read, "Sheet2", "Sheet0", "Sheet1");
  572. }
  573. }
  574. }
  575. @Test
  576. void bug51158() throws IOException {
  577. // create a workbook
  578. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  579. XSSFSheet sheet = wb1.createSheet("Test Sheet");
  580. XSSFRow row = sheet.createRow(2);
  581. XSSFCell cell = row.createCell(3);
  582. cell.setCellValue("test1");
  583. //XSSFCreationHelper helper = workbook.getCreationHelper();
  584. //cell.setHyperlink(helper.createHyperlink(0));
  585. XSSFComment comment = sheet.createDrawingPatriarch().createCellComment(new XSSFClientAnchor());
  586. assertNotNull(comment);
  587. comment.setString("some comment");
  588. // CellStyle cs = workbook.createCellStyle();
  589. // cs.setShrinkToFit(false);
  590. // row.createCell(0).setCellStyle(cs);
  591. // write the first excel file
  592. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  593. assertNotNull(wb2);
  594. sheet = wb2.getSheetAt(0);
  595. row = sheet.getRow(2);
  596. assertEquals("test1", row.getCell(3).getStringCellValue());
  597. assertNull(row.getCell(4));
  598. // add a new cell to the sheet
  599. cell = row.createCell(4);
  600. cell.setCellValue("test2");
  601. // write the second excel file
  602. try (XSSFWorkbook wb3 = writeOutAndReadBack(wb2)) {
  603. assertNotNull(wb3);
  604. sheet = wb3.getSheetAt(0);
  605. row = sheet.getRow(2);
  606. assertEquals("test1", row.getCell(3).getStringCellValue());
  607. assertEquals("test2", row.getCell(4).getStringCellValue());
  608. }
  609. }
  610. }
  611. }
  612. @Test
  613. void bug51158a() throws IOException {
  614. // create a workbook
  615. try (XSSFWorkbook workbook = new XSSFWorkbook()) {
  616. workbook.createSheet("Test Sheet");
  617. XSSFSheet sheetBack = workbook.getSheetAt(0);
  618. // committing twice did add the XML twice without clearing the part in between
  619. sheetBack.commit();
  620. // ensure that a memory based package part does not have lingering data from previous commit() calls
  621. if (sheetBack.getPackagePart() instanceof MemoryPackagePart) {
  622. sheetBack.getPackagePart().clear();
  623. }
  624. sheetBack.commit();
  625. String str = new String(IOUtils.toByteArray(sheetBack.getPackagePart().getInputStream()), StandardCharsets.UTF_8);
  626. assertEquals(1, countMatches(str, "<worksheet"));
  627. }
  628. }
  629. @Test
  630. void bug60509() throws Exception {
  631. try (XSSFWorkbook wb = openSampleWorkbook("60509.xlsx")) {
  632. assertSheetOrder(wb, "Sheet1", "Sheet2", "Sheet3");
  633. int sheetIndex = wb.getSheetIndex("Sheet1");
  634. wb.setSheetName(sheetIndex, "Sheet1-Renamed");
  635. try (Workbook read = writeOutAndReadBack(wb)) {
  636. assertNotNull(read);
  637. assertSheetOrder(read, "Sheet1-Renamed", "Sheet2", "Sheet3");
  638. XSSFSheet sheet = (XSSFSheet) read.getSheet("Sheet1-Renamed");
  639. XDDFChartData.Series series = sheet.getDrawingPatriarch().getCharts().get(0).getChartSeries().get(0).getSeries(0);
  640. assertTrue(series instanceof XDDFBarChartData.Series, "should be a bar chart data series");
  641. String formula = series.getCategoryData().getFormula();
  642. assertTrue(formula.startsWith("'Sheet1-Renamed'!"), "should contain new sheet name");
  643. }
  644. }
  645. }
  646. @Test
  647. void bug66365() throws Exception {
  648. try (XSSFWorkbook wb = openSampleWorkbook("66365.xlsx")) {
  649. XSSFSheet sheet1 = wb.getSheetAt(0);
  650. assertEquals(sheet1.getRow(0).getCell(0).getStringCellValue(),
  651. sheet1.getRow(0).getCell(1).getStringCellValue());
  652. assertEquals(sheet1.getRow(1).getCell(0).getStringCellValue(),
  653. sheet1.getRow(1).getCell(1).getStringCellValue());
  654. }
  655. }
  656. private static final int INDEX_NOT_FOUND = -1;
  657. private static boolean isEmpty(CharSequence cs) {
  658. return cs == null || cs.length() == 0;
  659. }
  660. private static int countMatches(CharSequence str, CharSequence sub) {
  661. if (isEmpty(str) || isEmpty(sub)) {
  662. return 0;
  663. }
  664. int count = 0;
  665. int idx = 0;
  666. while ((idx = indexOf(str, sub, idx)) != INDEX_NOT_FOUND) {
  667. count++;
  668. idx += sub.length();
  669. }
  670. return count;
  671. }
  672. private static int indexOf(CharSequence cs, CharSequence searchChar, int start) {
  673. return cs.toString().indexOf(searchChar.toString(), start);
  674. }
  675. @Test
  676. void testAddPivotCache() throws IOException {
  677. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  678. CTWorkbook ctWb = wb.getCTWorkbook();
  679. CTPivotCache pivotCache = wb.addPivotCache("0");
  680. //Ensures that pivotCaches is initiated
  681. assertTrue(ctWb.isSetPivotCaches());
  682. assertSame(pivotCache, ctWb.getPivotCaches().getPivotCacheArray(0));
  683. assertEquals("0", pivotCache.getId());
  684. }
  685. }
  686. private void setPivotData(XSSFWorkbook wb){
  687. XSSFSheet sheet = wb.createSheet();
  688. Row row1 = sheet.createRow(0);
  689. // Create a cell and put a value in it.
  690. Cell cell = row1.createCell(0);
  691. cell.setCellValue("Names");
  692. Cell cell2 = row1.createCell(1);
  693. cell2.setCellValue("#");
  694. Cell cell7 = row1.createCell(2);
  695. cell7.setCellValue("Data");
  696. Row row2 = sheet.createRow(1);
  697. Cell cell3 = row2.createCell(0);
  698. cell3.setCellValue("Jan");
  699. Cell cell4 = row2.createCell(1);
  700. cell4.setCellValue(10);
  701. Cell cell8 = row2.createCell(2);
  702. cell8.setCellValue("Apa");
  703. Row row3 = sheet.createRow(2);
  704. Cell cell5 = row3.createCell(0);
  705. cell5.setCellValue("Ben");
  706. Cell cell6 = row3.createCell(1);
  707. cell6.setCellValue(9);
  708. Cell cell9 = row3.createCell(2);
  709. cell9.setCellValue("Bepa");
  710. AreaReference source = wb.getCreationHelper().createAreaReference("A1:B2");
  711. sheet.createPivotTable(source, new CellReference("H5"));
  712. }
  713. @Test
  714. void testLoadWorkbookWithPivotTable() throws Exception {
  715. File file = TempFile.createTempFile("ooxml-pivottable", ".xlsx");
  716. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  717. setPivotData(wb);
  718. FileOutputStream fileOut = new FileOutputStream(file);
  719. wb.write(fileOut);
  720. fileOut.close();
  721. }
  722. try (XSSFWorkbook wb2 = (XSSFWorkbook) WorkbookFactory.create(file)) {
  723. assertEquals(1, wb2.getPivotTables().size());
  724. }
  725. assertTrue(file.delete());
  726. }
  727. @Test
  728. void testAddPivotTableToWorkbookWithLoadedPivotTable() throws Exception {
  729. File file = TempFile.createTempFile("ooxml-pivottable", ".xlsx");
  730. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  731. setPivotData(wb);
  732. try (FileOutputStream fileOut = new FileOutputStream(file)) {
  733. wb.write(fileOut);
  734. }
  735. }
  736. try (XSSFWorkbook wb2 = (XSSFWorkbook) WorkbookFactory.create(file)) {
  737. setPivotData(wb2);
  738. assertEquals(2, wb2.getPivotTables().size());
  739. }
  740. assertTrue(file.delete());
  741. }
  742. @Test
  743. void testSetFirstVisibleTab_57373() throws IOException {
  744. try (Workbook wb = new XSSFWorkbook()) {
  745. /*Sheet sheet1 =*/
  746. wb.createSheet();
  747. Sheet sheet2 = wb.createSheet();
  748. int idx2 = wb.getSheetIndex(sheet2);
  749. Sheet sheet3 = wb.createSheet();
  750. int idx3 = wb.getSheetIndex(sheet3);
  751. // add many sheets so "first visible" is relevant
  752. for (int i = 0; i < 30; i++) {
  753. wb.createSheet();
  754. }
  755. wb.setFirstVisibleTab(idx2);
  756. wb.setActiveSheet(idx3);
  757. //wb.write(new FileOutputStream(new File("C:\\temp\\test.xlsx")));
  758. assertEquals(idx2, wb.getFirstVisibleTab());
  759. assertEquals(idx3, wb.getActiveSheetIndex());
  760. try (Workbook wbBack = writeOutAndReadBack(wb)) {
  761. sheet2 = wbBack.getSheetAt(idx2);
  762. assertNotNull(sheet2);
  763. sheet3 = wbBack.getSheetAt(idx3);
  764. assertNotNull(sheet3);
  765. assertEquals(idx2, wb.getFirstVisibleTab());
  766. assertEquals(idx3, wb.getActiveSheetIndex());
  767. }
  768. }
  769. }
  770. /**
  771. * Tests that we can save a workbook with macros and reload it.
  772. */
  773. @Test
  774. void testSetVBAProject() throws Exception {
  775. File file;
  776. final byte[] allBytes = new byte[256];
  777. for (int i = 0; i < 256; i++) {
  778. allBytes[i] = (byte) (i - 128);
  779. }
  780. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  781. wb1.createSheet();
  782. wb1.setVBAProject(new ByteArrayInputStream(allBytes));
  783. file = writeOut(wb1, "ooi-.xlsm");
  784. }
  785. // Check the package contains what we'd expect it to
  786. try (OPCPackage pkg = OPCPackage.open(file.toString())) {
  787. PackagePart wbPart = pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
  788. assertTrue(wbPart.hasRelationships());
  789. final PackageRelationshipCollection relationships = wbPart.getRelationships().getRelationships(XSSFRelation.VBA_MACROS.getRelation());
  790. assertEquals(1, relationships.size());
  791. PackageRelationship relationship = relationships.getRelationship(0);
  792. assertNotNull(relationship);
  793. assertEquals(XSSFRelation.VBA_MACROS.getDefaultFileName(), relationship.getTargetURI().toString());
  794. PackagePart vbaPart = pkg.getPart(PackagingURIHelper.createPartName(XSSFRelation.VBA_MACROS.getDefaultFileName()));
  795. assertNotNull(vbaPart);
  796. assertFalse(vbaPart.isRelationshipPart());
  797. assertEquals(XSSFRelation.VBA_MACROS.getContentType(), vbaPart.getContentType());
  798. final byte[] fromFile = IOUtils.toByteArray(vbaPart.getInputStream());
  799. assertArrayEquals(allBytes, fromFile);
  800. // Load back the XSSFWorkbook just to check nothing explodes
  801. try (XSSFWorkbook wb2 = new XSSFWorkbook(pkg)) {
  802. assertEquals(1, wb2.getNumberOfSheets());
  803. assertEquals(XSSFWorkbookType.XLSM, wb2.getWorkbookType());
  804. }
  805. }
  806. }
  807. @Test
  808. void testBug54399() throws IOException {
  809. try (XSSFWorkbook workbook = openSampleWorkbook("54399.xlsx")) {
  810. for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
  811. String name = "SheetRenamed" + (i + 1);
  812. workbook.setSheetName(i, name);
  813. assertEquals(name, workbook.getSheetName(i));
  814. }
  815. }
  816. }
  817. /**
  818. * {@code Iterator<XSSFSheet> XSSFWorkbook.iterator} was committed in r700472 on 2008-09-30
  819. * and has been replaced with {@code Iterator<Sheet> XSSFWorkbook.iterator}
  820. *
  821. * In order to make code for looping over sheets in workbooks standard, regardless
  822. * of the type of workbook (HSSFWorkbook, XSSFWorkbook, SXSSFWorkbook), the previously
  823. * available {@code Iterator<XSSFSheet> iterator} and {@code Iterator<XSSFSheet> sheetIterator}
  824. * have been replaced with {@code Iterator<Sheet>} {@link Sheet#iterator} and
  825. * {@code Iterator<Sheet>} {@link Workbook#sheetIterator}. This makes iterating over sheets in a workbook
  826. * similar to iterating over rows in a sheet and cells in a row.
  827. *
  828. * Note: this breaks backwards compatibility! Existing codebases will need to
  829. * upgrade their code with either of the following options presented in this test case.
  830. *
  831. */
  832. @SuppressWarnings("unchecked")
  833. @Test
  834. void bug58245_XSSFSheetIterator() throws IOException {
  835. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  836. wb.createSheet();
  837. // =====================================================================
  838. // Case 1: Existing code uses XSSFSheet for-each loop
  839. // =====================================================================
  840. // Option A:
  841. for (XSSFSheet sh : (Iterable<XSSFSheet>) (Iterable<? extends Sheet>) wb) {
  842. sh.createRow(0);
  843. }
  844. // Option B (preferred for new code):
  845. for (Sheet sh : wb) {
  846. sh.createRow(1);
  847. }
  848. // =====================================================================
  849. // Case 2: Existing code creates an iterator variable
  850. // =====================================================================
  851. // Option A:
  852. {
  853. Iterator<XSSFSheet> it = (Iterator<XSSFSheet>) (Iterator<? extends Sheet>) wb.iterator();
  854. XSSFSheet sh = it.next();
  855. sh.createRow(2);
  856. }
  857. // Option B (preferred for new code):
  858. {
  859. Iterator<Sheet> it = wb.iterator();
  860. Sheet sh = it.next();
  861. sh.createRow(3);
  862. }
  863. assertEquals(4, wb.getSheetAt(0).getPhysicalNumberOfRows());
  864. }
  865. }
  866. @Test
  867. void testBug56957CloseWorkbook() throws Exception {
  868. File file = TempFile.createTempFile("TestBug56957_", ".xlsx");
  869. final Date dateExp = LocaleUtil.getLocaleCalendar(2014, 10, 9).getTime();
  870. try {
  871. // as the file is written to, we make a copy before actually working on it
  872. FileHelper.copyFile(HSSFTestDataSamples.getSampleFile("56957.xlsx"), file);
  873. assertTrue(file.exists());
  874. // read-only mode works!
  875. try (Workbook workbook = XSSFWorkbookFactory.createWorkbook(OPCPackage.open(file, PackageAccess.READ))) {
  876. Date dateAct = workbook.getSheetAt(0).getRow(0).getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getDateCellValue();
  877. assertEquals(dateExp, dateAct);
  878. }
  879. try (Workbook workbook = XSSFWorkbookFactory.createWorkbook(OPCPackage.open(file, PackageAccess.READ))) {
  880. Date dateAct = workbook.getSheetAt(0).getRow(0).getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getDateCellValue();
  881. assertEquals(dateExp, dateAct);
  882. }
  883. // now check read/write mode
  884. try (Workbook workbook = XSSFWorkbookFactory.createWorkbook(OPCPackage.open(file, PackageAccess.READ_WRITE))) {
  885. Date dateAct = workbook.getSheetAt(0).getRow(0).getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getDateCellValue();
  886. assertEquals(dateExp, dateAct);
  887. }
  888. try (Workbook workbook = XSSFWorkbookFactory.createWorkbook(OPCPackage.open(file, PackageAccess.READ_WRITE))) {
  889. Date dateAct = workbook.getSheetAt(0).getRow(0).getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getDateCellValue();
  890. assertEquals(dateExp, dateAct);
  891. }
  892. } finally {
  893. assertTrue(file.exists());
  894. assertTrue(file.delete());
  895. }
  896. }
  897. @Test
  898. void closeDoesNotModifyWorkbook() throws IOException {
  899. final String filename = "SampleSS.xlsx";
  900. final File file = POIDataSamples.getSpreadSheetInstance().getFile(filename);
  901. Workbook wb;
  902. // Some tests commented out because close() modifies the file
  903. // See bug 58779
  904. // String
  905. //wb = new XSSFWorkbook(file.getPath());
  906. //assertCloseDoesNotModifyFile(filename, wb);
  907. // File
  908. //wb = new XSSFWorkbook(file);
  909. //assertCloseDoesNotModifyFile(filename, wb);
  910. // InputStream
  911. try (FileInputStream is = new FileInputStream(file)) {
  912. wb = new XSSFWorkbook(is);
  913. assertCloseDoesNotModifyFile(filename, wb);
  914. }
  915. // OPCPackage
  916. //wb = new XSSFWorkbook(OPCPackage.open(file));
  917. //assertCloseDoesNotModifyFile(filename, wb);
  918. }
  919. @Test
  920. void testCloseBeforeWrite() throws IOException {
  921. try (Workbook wb = new XSSFWorkbook()) {
  922. wb.createSheet("somesheet");
  923. // test what happens if we close the Workbook before we write it out
  924. wb.close();
  925. assertThrows(IOException.class, () -> {
  926. try {
  927. writeOutAndReadBack(wb);
  928. } catch (RuntimeException e) {
  929. throw e.getCause();
  930. }
  931. });
  932. }
  933. }
  934. /**
  935. * See bug #57840 test data tables
  936. */
  937. @Test
  938. void getTable() throws IOException {
  939. XSSFWorkbook wb = openSampleWorkbook("WithTable.xlsx");
  940. XSSFTable table1 = wb.getTable("Tabella1");
  941. assertNotNull(table1, "Tabella1 was not found in workbook");
  942. assertEquals("Tabella1", table1.getName(), "Table name");
  943. assertEquals("Foglio1", table1.getSheetName(), "Sheet name");
  944. // Table lookup should be case-insensitive
  945. assertSame(table1, wb.getTable("TABELLA1"), "Case insensitive table name lookup");
  946. // If workbook does not contain any data tables matching the provided name, getTable should return null
  947. assertNull(wb.getTable(null), "Null table name should not throw NPE");
  948. assertNull(wb.getTable("Foglio1"), "Should not be able to find non-existent table");
  949. // If a table is added after getTable is called it should still be reachable by XSSFWorkbook.getTable
  950. // This test makes sure that if any caching is done that getTable never uses a stale cache
  951. XSSFTable table2 = wb.getSheet("Foglio2").createTable(null);
  952. table2.setName("Table2");
  953. assertSame(table2, wb.getTable("Table2"), "Did not find Table2");
  954. // If table name is modified after getTable is called, the table can only be found by its new name
  955. // This test makes sure that if any caching is done that getTable never uses a stale cache
  956. table1.setName("Table1");
  957. assertSame(table1, wb.getTable("TABLE1"), "Did not find Tabella1 renamed to Table1");
  958. wb.close();
  959. }
  960. @SuppressWarnings("deprecation")
  961. @Test
  962. void testRemoveSheet() throws IOException {
  963. // Test removing a sheet maintains the named ranges correctly
  964. XSSFWorkbook wb = new XSSFWorkbook();
  965. wb.createSheet("Sheet1");
  966. wb.createSheet("Sheet2");
  967. XSSFName sheet1Name = wb.createName();
  968. sheet1Name.setNameName("name1");
  969. sheet1Name.setSheetIndex(0);
  970. sheet1Name.setRefersToFormula("Sheet1!$A$1");
  971. XSSFName sheet2Name = wb.createName();
  972. sheet2Name.setNameName("name1");
  973. sheet2Name.setSheetIndex(1);
  974. sheet2Name.setRefersToFormula("Sheet2!$A$1");
  975. assertTrue(wb.getAllNames().contains(sheet1Name));
  976. assertTrue(wb.getAllNames().contains(sheet2Name));
  977. assertEquals(2, wb.getNames("name1").size());
  978. assertEquals(sheet1Name, wb.getNames("name1").get(0));
  979. assertEquals(sheet2Name, wb.getNames("name1").get(1));
  980. // Remove sheet1, we should only have sheet2Name now
  981. wb.removeSheetAt(0);
  982. assertFalse(wb.getAllNames().contains(sheet1Name));
  983. assertTrue(wb.getAllNames().contains(sheet2Name));
  984. assertEquals(1, wb.getNames("name1").size());
  985. assertEquals(sheet2Name, wb.getNames("name1").get(0));
  986. // Check by index as well for sanity
  987. assertEquals(1, wb.getNumberOfNames());
  988. assertEquals(0, wb.getNameIndex("name1"));
  989. assertEquals(sheet2Name, wb.getNameAt(0));
  990. wb.close();
  991. }
  992. /**
  993. * See bug #61700
  994. */
  995. @Test
  996. void testWorkbookForceFormulaRecalculation() throws Exception {
  997. Workbook workbook = _testDataProvider.createWorkbook();
  998. workbook.createSheet().createRow(0).createCell(0).setCellFormula("B1+C1");
  999. workbook.getCreationHelper().createFormulaEvaluator().evaluateAll();
  1000. assertFalse(workbook.getForceFormulaRecalculation());
  1001. workbook.setForceFormulaRecalculation(true);
  1002. assertTrue(workbook.getForceFormulaRecalculation());
  1003. Workbook wbBack = _testDataProvider.writeOutAndReadBack(workbook);
  1004. assertTrue(wbBack.getForceFormulaRecalculation());
  1005. wbBack.setForceFormulaRecalculation(false);
  1006. assertFalse(wbBack.getForceFormulaRecalculation());
  1007. Workbook wbBack2 = _testDataProvider.writeOutAndReadBack(wbBack);
  1008. assertFalse(wbBack2.getForceFormulaRecalculation());
  1009. workbook.close();
  1010. wbBack.close();
  1011. wbBack2.close();
  1012. }
  1013. @Test
  1014. void testRightToLeft() throws IOException {
  1015. try(XSSFWorkbook workbook = openSampleWorkbook("right-to-left.xlsx")) {
  1016. Sheet sheet = workbook.getSheet("عربى");
  1017. Cell A1 = sheet.getRow(0).getCell(0);
  1018. Cell A2 = sheet.getRow(1).getCell(0);
  1019. Cell A3 = sheet.getRow(2).getCell(0);
  1020. Cell A4 = sheet.getRow(3).getCell(0);
  1021. expectFormattedContent(A1, "نص");
  1022. expectFormattedContent(A2, "123"); //this should really be ۱۲۳
  1023. expectFormattedContent(A3, "text with comment");
  1024. expectFormattedContent(A4, " עִבְרִית and اَلْعَرَبِيَّةُ");
  1025. Comment a3Comment = sheet.getCellComment(new CellAddress("A3"));
  1026. assertTrue(a3Comment.getString().getString().contains("تعليق الاختبا"));
  1027. }
  1028. }
  1029. @Test
  1030. void test501RC1Failure() throws Exception {
  1031. String filename = "0-www-crossref-org.lib.rivier.edu_education-files_suffix-generator.xlsm";
  1032. try(XSSFWorkbook workbook = openSampleWorkbook(filename)) {
  1033. assertTrue(workbook.isMacroEnabled());
  1034. for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
  1035. XSSFSheet sheet = workbook.getSheetAt(i);
  1036. for (Row row : sheet) {
  1037. for (Cell cell : row) {
  1038. assertNotNull(cell);
  1039. }
  1040. }
  1041. }
  1042. }
  1043. }
  1044. @Test
  1045. void testNewWorkbookWithTempFilePackageParts() throws Exception {
  1046. try(UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) {
  1047. assertFalse(ZipPackage.useTempFilePackageParts(), "useTempFilePackageParts defaults to false?");
  1048. assertFalse(ZipPackage.encryptTempFilePackageParts(), "encryptTempFilePackageParts defaults to false?");
  1049. ZipPackage.setUseTempFilePackageParts(true);
  1050. assertTrue(ZipPackage.useTempFilePackageParts(), "useTempFilePackageParts was modified?");
  1051. assertFalse(ZipPackage.encryptTempFilePackageParts(), "encryptTempFilePackageParts was not modified?");
  1052. try (XSSFWorkbook workbook = new XSSFWorkbook()) {
  1053. XSSFSheet sheet = workbook.createSheet("sheet1");
  1054. XSSFRow row = sheet.createRow(0);
  1055. XSSFCell cell0 = row.createCell(0);
  1056. cell0.setCellValue("");
  1057. XSSFCell cell1 = row.createCell(1);
  1058. cell1.setCellErrorValue(FormulaError.DIV0);
  1059. XSSFCell cell2 = row.createCell(2);
  1060. cell2.setCellErrorValue(FormulaError.FUNCTION_NOT_IMPLEMENTED);
  1061. workbook.write(bos);
  1062. } finally {
  1063. ZipPackage.setUseTempFilePackageParts(false);
  1064. }
  1065. }
  1066. }
  1067. @Test
  1068. void testNewWorkbookWithEncryptedTempFilePackageParts() throws Exception {
  1069. try(UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) {
  1070. assertFalse(ZipPackage.useTempFilePackageParts(), "useTempFilePackageParts defaults to false?");
  1071. assertFalse(ZipPackage.encryptTempFilePackageParts(), "encryptTempFilePackageParts defaults to false?");
  1072. ZipPackage.setUseTempFilePackageParts(true);
  1073. ZipPackage.setEncryptTempFilePackageParts(true);
  1074. assertTrue(ZipPackage.useTempFilePackageParts(), "useTempFilePackageParts was modified?");
  1075. assertTrue(ZipPackage.encryptTempFilePackageParts(), "encryptTempFilePackageParts was modified?");
  1076. try (XSSFWorkbook workbook = new XSSFWorkbook()) {
  1077. XSSFSheet sheet = workbook.createSheet("sheet1");
  1078. XSSFRow row = sheet.createRow(0);
  1079. XSSFCell cell0 = row.createCell(0);
  1080. cell0.setCellValue("");
  1081. XSSFCell cell1 = row.createCell(1);
  1082. cell1.setCellErrorValue(FormulaError.DIV0);
  1083. XSSFCell cell2 = row.createCell(2);
  1084. cell2.setCellErrorValue(FormulaError.FUNCTION_NOT_IMPLEMENTED);
  1085. workbook.write(bos);
  1086. } finally {
  1087. ZipPackage.setUseTempFilePackageParts(false);
  1088. ZipPackage.setEncryptTempFilePackageParts(false);
  1089. }
  1090. }
  1091. }
  1092. @Test
  1093. void testLinkExternalWorkbook() throws Exception {
  1094. String nameA = "link-external-workbook-a.xlsx";
  1095. try (
  1096. UnsynchronizedByteArrayOutputStream bosA = new UnsynchronizedByteArrayOutputStream();
  1097. UnsynchronizedByteArrayOutputStream bosB = new UnsynchronizedByteArrayOutputStream();
  1098. XSSFWorkbook workbookA = new XSSFWorkbook();
  1099. XSSFWorkbook workbookB = new XSSFWorkbook()
  1100. ) {
  1101. XSSFRow row1 = workbookA.createSheet().createRow(0);
  1102. row1.createCell(0).setCellValue(10);
  1103. row1.createCell(1).setCellValue(20);
  1104. XSSFRow row2 = workbookB.createSheet().createRow(0);
  1105. XSSFCell cell = row2.createCell(0);
  1106. workbookB.linkExternalWorkbook(nameA, workbookA);
  1107. String formula = String.format(LocaleUtil.getUserLocale(), "SUM('[%s]Sheet0'!A1:B1)", nameA);
  1108. cell.setCellFormula(formula);
  1109. XSSFFormulaEvaluator evaluator = workbookB.getCreationHelper().createFormulaEvaluator();
  1110. evaluator.evaluateFormulaCell(cell);
  1111. assertEquals(30.0, cell.getNumericCellValue());
  1112. workbookA.write(bosA);
  1113. workbookB.write(bosB);
  1114. try(
  1115. XSSFWorkbook workbook1 = new XSSFWorkbook(bosA.toInputStream());
  1116. XSSFWorkbook workbook2 = new XSSFWorkbook(bosB.toInputStream())
  1117. ) {
  1118. workbook2.linkExternalWorkbook(nameA, workbook1);
  1119. XSSFFormulaEvaluator evaluator2 = workbook2.getCreationHelper().createFormulaEvaluator();
  1120. XSSFCell cell2 = workbook2.getSheetAt(0).getRow(0).getCell(0);
  1121. evaluator2.evaluateFormulaCell(cell2);
  1122. assertEquals(30.0, cell2.getNumericCellValue());
  1123. }
  1124. }
  1125. }
  1126. @Test
  1127. void testIgnoreTrashParts() throws Exception {
  1128. try (XSSFWorkbook workbook = openSampleWorkbook("Excel_file_with_trash_item.xlsx")) {
  1129. for (PackagePart packagePart : workbook.getPackage().getParts()) {
  1130. assertFalse(packagePart.getPartName().toString().contains("trash"),
  1131. "should ignore part " + packagePart.getPartName());
  1132. }
  1133. }
  1134. }
  1135. @Test
  1136. void testCacheExternalWorkbook() throws Exception {
  1137. String nameA = "cache-external-workbook-a.xlsx";
  1138. try (
  1139. UnsynchronizedByteArrayOutputStream bosA = new UnsynchronizedByteArrayOutputStream();
  1140. UnsynchronizedByteArrayOutputStream bosB = new UnsynchronizedByteArrayOutputStream();
  1141. XSSFWorkbook workbookA = new XSSFWorkbook();
  1142. XSSFWorkbook workbookB = new XSSFWorkbook()
  1143. ) {
  1144. XSSFRow row1 = workbookA.createSheet().createRow(0);
  1145. double v1 = 10, v2 = 10, sum = v1 + v2;
  1146. row1.createCell(0).setCellValue(v1);
  1147. row1.createCell(1).setCellValue(v2);
  1148. XSSFRow row = workbookB.createSheet().createRow(0);
  1149. XSSFCell cell = row.createCell(0);
  1150. workbookB.linkExternalWorkbook(nameA, workbookA);
  1151. String formula = String.format(LocaleUtil.getUserLocale(), "SUM('[%s]Sheet0'!A1:B1)", nameA);
  1152. cell.setCellFormula(formula);
  1153. XSSFFormulaEvaluator evaluator = workbookB.getCreationHelper().createFormulaEvaluator();
  1154. evaluator.evaluateFormulaCell(cell);
  1155. assertEquals(sum, cell.getNumericCellValue());
  1156. workbookA.write(bosA);
  1157. workbookB.write(bosB);
  1158. try(
  1159. XSSFWorkbook workbook2 = new XSSFWorkbook(bosB.toInputStream())
  1160. ) {
  1161. CTExternalLink link = workbook2.getExternalLinksTable().get(0).getCTExternalLink();
  1162. CTExternalSheetData sheetData = link.getExternalBook().getSheetDataSet().getSheetDataArray(0);
  1163. assertEquals(Double.valueOf(sheetData.getRowArray(0).getCellArray(0).getV()), v1);
  1164. assertEquals(Double.valueOf(sheetData.getRowArray(0).getCellArray(1).getV()), v2);
  1165. }
  1166. }
  1167. }
  1168. @Test
  1169. void checkExistingFileForR1C1Refs() throws IOException {
  1170. try (
  1171. UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream();
  1172. XSSFWorkbook wb = openSampleWorkbook("WithTable.xlsx")
  1173. ) {
  1174. assertEquals(CellReferenceType.A1, wb.getCellReferenceType());
  1175. wb.setCellReferenceType(CellReferenceType.R1C1);
  1176. assertEquals(CellReferenceType.R1C1, wb.getCellReferenceType());
  1177. wb.write(bos);
  1178. try (XSSFWorkbook wb2 = new XSSFWorkbook(bos.toInputStream())) {
  1179. assertEquals(CellReferenceType.R1C1, wb2.getCellReferenceType());
  1180. }
  1181. }
  1182. }
  1183. @Test
  1184. void checkNewFileForR1C1Refs() throws IOException {
  1185. try (
  1186. UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream();
  1187. XSSFWorkbook wb = new XSSFWorkbook()
  1188. ) {
  1189. assertEquals(CellReferenceType.UNKNOWN, wb.getCellReferenceType());
  1190. wb.setCellReferenceType(CellReferenceType.R1C1);
  1191. assertEquals(CellReferenceType.R1C1, wb.getCellReferenceType());
  1192. wb.write(bos);
  1193. try (XSSFWorkbook wb2 = new XSSFWorkbook(bos.toInputStream())) {
  1194. assertEquals(CellReferenceType.R1C1, wb2.getCellReferenceType());
  1195. }
  1196. }
  1197. }
  1198. @Test
  1199. void testGithub321() throws Exception {
  1200. try (XSSFWorkbook wb = openSampleWorkbook("github-321.xlsx")) {
  1201. XSSFSheet xssfSheet = wb.getSheetAt(0);
  1202. DataFormatter dataFormatter = new DataFormatter();
  1203. FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
  1204. XSSFCell a3 = xssfSheet.getRow(2).getCell(0);
  1205. assertEquals(2.05, a3.getNumericCellValue());
  1206. assertEquals("2.05", dataFormatter.formatCellValue(a3));
  1207. assertEquals("2.05", dataFormatter.formatCellValue(a3, formulaEvaluator));
  1208. XSSFCell a4 = xssfSheet.getRow(3).getCell(0);
  1209. assertEquals(2.05, a4.getNumericCellValue());
  1210. assertEquals("2.1", dataFormatter.formatCellValue(a4));
  1211. assertEquals("2.1", dataFormatter.formatCellValue(a4, formulaEvaluator));
  1212. }
  1213. }
  1214. private static void expectFormattedContent(Cell cell, String value) {
  1215. assertEquals(value, new DataFormatter().formatCellValue(cell),
  1216. "Cell " + ref(cell) + " has wrong formatted content.");
  1217. }
  1218. private static String ref(Cell cell) {
  1219. return new CellReference(cell).formatAsString();
  1220. }
  1221. }