Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

TestXSSFBugs.java 34KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.xssf.usermodel;
  16. import java.io.ByteArrayInputStream;
  17. import java.io.ByteArrayOutputStream;
  18. import java.util.List;
  19. import org.apache.poi.POIXMLDocumentPart;
  20. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  21. import org.apache.poi.openxml4j.opc.OPCPackage;
  22. import org.apache.poi.openxml4j.opc.PackagePart;
  23. import org.apache.poi.openxml4j.opc.PackagingURIHelper;
  24. import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;
  25. import org.apache.poi.ss.usermodel.Cell;
  26. import org.apache.poi.ss.usermodel.CellStyle;
  27. import org.apache.poi.ss.usermodel.CellValue;
  28. import org.apache.poi.ss.usermodel.DataFormatter;
  29. import org.apache.poi.ss.usermodel.Font;
  30. import org.apache.poi.ss.usermodel.FormulaError;
  31. import org.apache.poi.ss.usermodel.FormulaEvaluator;
  32. import org.apache.poi.ss.usermodel.Name;
  33. import org.apache.poi.ss.usermodel.RichTextString;
  34. import org.apache.poi.ss.usermodel.Row;
  35. import org.apache.poi.ss.usermodel.Sheet;
  36. import org.apache.poi.ss.usermodel.Workbook;
  37. import org.apache.poi.xssf.XSSFITestDataProvider;
  38. import org.apache.poi.xssf.XSSFTestDataSamples;
  39. import org.apache.poi.xssf.model.CalculationChain;
  40. import org.apache.poi.xssf.model.Table;
  41. import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill;
  42. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
  43. public final class TestXSSFBugs extends BaseTestBugzillaIssues {
  44. public TestXSSFBugs() {
  45. super(XSSFITestDataProvider.instance);
  46. }
  47. /**
  48. * test writing a file with large number of unique strings,
  49. * open resulting file in Excel to check results!
  50. */
  51. public void test15375_2() {
  52. baseTest15375(1000);
  53. }
  54. /**
  55. * Named ranges had the right reference, but
  56. * the wrong sheet name
  57. */
  58. public void test45430() {
  59. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("45430.xlsx");
  60. assertFalse(wb.isMacroEnabled());
  61. assertEquals(3, wb.getNumberOfNames());
  62. assertEquals(0, wb.getNameAt(0).getCTName().getLocalSheetId());
  63. assertFalse(wb.getNameAt(0).getCTName().isSetLocalSheetId());
  64. assertEquals("SheetA!$A$1", wb.getNameAt(0).getRefersToFormula());
  65. assertEquals("SheetA", wb.getNameAt(0).getSheetName());
  66. assertEquals(0, wb.getNameAt(1).getCTName().getLocalSheetId());
  67. assertFalse(wb.getNameAt(1).getCTName().isSetLocalSheetId());
  68. assertEquals("SheetB!$A$1", wb.getNameAt(1).getRefersToFormula());
  69. assertEquals("SheetB", wb.getNameAt(1).getSheetName());
  70. assertEquals(0, wb.getNameAt(2).getCTName().getLocalSheetId());
  71. assertFalse(wb.getNameAt(2).getCTName().isSetLocalSheetId());
  72. assertEquals("SheetC!$A$1", wb.getNameAt(2).getRefersToFormula());
  73. assertEquals("SheetC", wb.getNameAt(2).getSheetName());
  74. // Save and re-load, still there
  75. XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  76. assertEquals(3, nwb.getNumberOfNames());
  77. assertEquals("SheetA!$A$1", nwb.getNameAt(0).getRefersToFormula());
  78. }
  79. /**
  80. * We should carry vba macros over after save
  81. */
  82. public void test45431() throws Exception {
  83. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("45431.xlsm");
  84. OPCPackage pkg = wb.getPackage();
  85. assertTrue(wb.isMacroEnabled());
  86. // Check the various macro related bits can be found
  87. PackagePart vba = pkg.getPart(
  88. PackagingURIHelper.createPartName("/xl/vbaProject.bin")
  89. );
  90. assertNotNull(vba);
  91. // And the drawing bit
  92. PackagePart drw = pkg.getPart(
  93. PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
  94. );
  95. assertNotNull(drw);
  96. // Save and re-open, both still there
  97. XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  98. OPCPackage nPkg = nwb.getPackage();
  99. assertTrue(nwb.isMacroEnabled());
  100. vba = nPkg.getPart(
  101. PackagingURIHelper.createPartName("/xl/vbaProject.bin")
  102. );
  103. assertNotNull(vba);
  104. drw = nPkg.getPart(
  105. PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
  106. );
  107. assertNotNull(drw);
  108. // And again, just to be sure
  109. nwb = XSSFTestDataSamples.writeOutAndReadBack(nwb);
  110. nPkg = nwb.getPackage();
  111. assertTrue(nwb.isMacroEnabled());
  112. vba = nPkg.getPart(
  113. PackagingURIHelper.createPartName("/xl/vbaProject.bin")
  114. );
  115. assertNotNull(vba);
  116. drw = nPkg.getPart(
  117. PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
  118. );
  119. assertNotNull(drw);
  120. }
  121. public void test47504() {
  122. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47504.xlsx");
  123. assertEquals(1, wb.getNumberOfSheets());
  124. XSSFSheet sh = wb.getSheetAt(0);
  125. XSSFDrawing drawing = sh.createDrawingPatriarch();
  126. List<POIXMLDocumentPart> rels = drawing.getRelations();
  127. assertEquals(1, rels.size());
  128. assertEquals("Sheet1!A1", rels.get(0).getPackageRelationship().getTargetURI().getFragment());
  129. // And again, just to be sure
  130. wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  131. assertEquals(1, wb.getNumberOfSheets());
  132. sh = wb.getSheetAt(0);
  133. drawing = sh.createDrawingPatriarch();
  134. rels = drawing.getRelations();
  135. assertEquals(1, rels.size());
  136. assertEquals("Sheet1!A1", rels.get(0).getPackageRelationship().getTargetURI().getFragment());
  137. }
  138. /**
  139. * Excel will sometimes write a button with a textbox
  140. * containing &gt;br&lt; (not closed!).
  141. * Clearly Excel shouldn't do this, but test that we can
  142. * read the file despite the naughtyness
  143. */
  144. public void test49020() throws Exception {
  145. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("BrNotClosed.xlsx");
  146. }
  147. /**
  148. * ensure that CTPhoneticPr is loaded by the ooxml test suite so that it is included in poi-ooxml-schemas
  149. */
  150. public void test49325() throws Exception {
  151. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("49325.xlsx");
  152. CTWorksheet sh = wb.getSheetAt(0).getCTWorksheet();
  153. assertNotNull(sh.getPhoneticPr());
  154. }
  155. /**
  156. * Names which are defined with a Sheet
  157. * should return that sheet index properly
  158. */
  159. public void test48923() throws Exception {
  160. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48923.xlsx");
  161. assertEquals(4, wb.getNumberOfNames());
  162. Name b1 = wb.getName("NameB1");
  163. Name b2 = wb.getName("NameB2");
  164. Name sheet2 = wb.getName("NameSheet2");
  165. Name test = wb.getName("Test");
  166. assertNotNull(b1);
  167. assertEquals("NameB1", b1.getNameName());
  168. assertEquals("Sheet1", b1.getSheetName());
  169. assertEquals(-1, b1.getSheetIndex());
  170. assertNotNull(b2);
  171. assertEquals("NameB2", b2.getNameName());
  172. assertEquals("Sheet1", b2.getSheetName());
  173. assertEquals(-1, b2.getSheetIndex());
  174. assertNotNull(sheet2);
  175. assertEquals("NameSheet2", sheet2.getNameName());
  176. assertEquals("Sheet2", sheet2.getSheetName());
  177. assertEquals(-1, sheet2.getSheetIndex());
  178. assertNotNull(test);
  179. assertEquals("Test", test.getNameName());
  180. assertEquals("Sheet1", test.getSheetName());
  181. assertEquals(-1, test.getSheetIndex());
  182. }
  183. /**
  184. * Problem with evaluation formulas due to
  185. * NameXPtgs.
  186. * Blows up on:
  187. * IF(B6= (ROUNDUP(B6,0) + ROUNDDOWN(B6,0))/2, MROUND(B6,2),ROUND(B6,0))
  188. *
  189. * TODO: delete this test case when MROUND and VAR are implemented
  190. */
  191. public void test48539() throws Exception {
  192. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48539.xlsx");
  193. assertEquals(3, wb.getNumberOfSheets());
  194. // Try each cell individually
  195. XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
  196. for(int i=0; i<wb.getNumberOfSheets(); i++) {
  197. Sheet s = wb.getSheetAt(i);
  198. for(Row r : s) {
  199. for(Cell c : r) {
  200. if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
  201. CellValue cv = eval.evaluate(c);
  202. if(cv.getCellType() == Cell.CELL_TYPE_NUMERIC) {
  203. // assert that the calculated value agrees with
  204. // the cached formula result calculated by Excel
  205. double cachedFormulaResult = c.getNumericCellValue();
  206. double evaluatedFormulaResult = cv.getNumberValue();
  207. assertEquals(c.getCellFormula(), cachedFormulaResult, evaluatedFormulaResult, 1E-7);
  208. }
  209. }
  210. }
  211. }
  212. }
  213. // Now all of them
  214. XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
  215. }
  216. /**
  217. * Foreground colours should be found even if
  218. * a theme is used
  219. */
  220. public void test48779() throws Exception {
  221. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx");
  222. XSSFCell cell = wb.getSheetAt(0).getRow(0).getCell(0);
  223. XSSFCellStyle cs = cell.getCellStyle();
  224. assertNotNull(cs);
  225. assertEquals(1, cs.getIndex());
  226. // Look at the low level xml elements
  227. assertEquals(2, cs.getCoreXf().getFillId());
  228. assertEquals(0, cs.getCoreXf().getXfId());
  229. assertEquals(true, cs.getCoreXf().getApplyFill());
  230. XSSFCellFill fg = wb.getStylesSource().getFillAt(2);
  231. assertEquals(0, fg.getFillForegroundColor().getIndexed());
  232. assertEquals(0.0, fg.getFillForegroundColor().getTint());
  233. assertEquals("FFFF0000", fg.getFillForegroundColor().getARGBHex());
  234. assertEquals(64, fg.getFillBackgroundColor().getIndexed());
  235. // Now look higher up
  236. assertNotNull(cs.getFillForegroundXSSFColor());
  237. assertEquals(0, cs.getFillForegroundColor());
  238. assertEquals("FFFF0000", cs.getFillForegroundXSSFColor().getARGBHex());
  239. assertEquals("FFFF0000", cs.getFillForegroundColorColor().getARGBHex());
  240. assertNotNull(cs.getFillBackgroundColor());
  241. assertEquals(64, cs.getFillBackgroundColor());
  242. assertEquals(null, cs.getFillBackgroundXSSFColor().getARGBHex());
  243. assertEquals(null, cs.getFillBackgroundColorColor().getARGBHex());
  244. }
  245. /**
  246. * With HSSF, if you create a font, don't change it, and
  247. * create a 2nd, you really do get two fonts that you
  248. * can alter as and when you want.
  249. * With XSSF, that wasn't the case, but this verfies
  250. * that it now is again
  251. */
  252. public void test48718() throws Exception {
  253. // Verify the HSSF behaviour
  254. // Then ensure the same for XSSF
  255. Workbook[] wbs = new Workbook[] {
  256. new HSSFWorkbook(),
  257. new XSSFWorkbook()
  258. };
  259. int[] initialFonts = new int[] { 4, 1 };
  260. for(int i=0; i<wbs.length; i++) {
  261. Workbook wb = wbs[i];
  262. int startingFonts = initialFonts[i];
  263. assertEquals(startingFonts, wb.getNumberOfFonts());
  264. // Get a font, and slightly change it
  265. Font a = wb.createFont();
  266. assertEquals(startingFonts+1, wb.getNumberOfFonts());
  267. a.setFontHeightInPoints((short)23);
  268. assertEquals(startingFonts+1, wb.getNumberOfFonts());
  269. // Get two more, unchanged
  270. Font b = wb.createFont();
  271. assertEquals(startingFonts+2, wb.getNumberOfFonts());
  272. Font c = wb.createFont();
  273. assertEquals(startingFonts+3, wb.getNumberOfFonts());
  274. }
  275. }
  276. /**
  277. * Ensure General and @ format are working properly
  278. * for integers
  279. */
  280. public void test47490() throws Exception {
  281. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("GeneralFormatTests.xlsx");
  282. Sheet s = wb.getSheetAt(1);
  283. Row r;
  284. DataFormatter df = new DataFormatter();
  285. r = s.getRow(1);
  286. assertEquals(1.0, r.getCell(2).getNumericCellValue());
  287. assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
  288. assertEquals("1", df.formatCellValue(r.getCell(2)));
  289. assertEquals("1", df.formatRawCellContents(1.0, -1, "@"));
  290. assertEquals("1", df.formatRawCellContents(1.0, -1, "General"));
  291. r = s.getRow(2);
  292. assertEquals(12.0, r.getCell(2).getNumericCellValue());
  293. assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
  294. assertEquals("12", df.formatCellValue(r.getCell(2)));
  295. assertEquals("12", df.formatRawCellContents(12.0, -1, "@"));
  296. assertEquals("12", df.formatRawCellContents(12.0, -1, "General"));
  297. r = s.getRow(3);
  298. assertEquals(123.0, r.getCell(2).getNumericCellValue());
  299. assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
  300. assertEquals("123", df.formatCellValue(r.getCell(2)));
  301. assertEquals("123", df.formatRawCellContents(123.0, -1, "@"));
  302. assertEquals("123", df.formatRawCellContents(123.0, -1, "General"));
  303. }
  304. /**
  305. * Ensures that XSSF and HSSF agree with each other,
  306. * and with the docs on when fetching the wrong
  307. * kind of value from a Formula cell
  308. */
  309. public void test47815() {
  310. Workbook[] wbs = new Workbook[] {
  311. new HSSFWorkbook(),
  312. new XSSFWorkbook()
  313. };
  314. for(Workbook wb : wbs) {
  315. Sheet s = wb.createSheet();
  316. Row r = s.createRow(0);
  317. // Setup
  318. Cell cn = r.createCell(0, Cell.CELL_TYPE_NUMERIC);
  319. cn.setCellValue(1.2);
  320. Cell cs = r.createCell(1, Cell.CELL_TYPE_STRING);
  321. cs.setCellValue("Testing");
  322. Cell cfn = r.createCell(2, Cell.CELL_TYPE_FORMULA);
  323. cfn.setCellFormula("A1");
  324. Cell cfs = r.createCell(3, Cell.CELL_TYPE_FORMULA);
  325. cfs.setCellFormula("B1");
  326. FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
  327. assertEquals(Cell.CELL_TYPE_NUMERIC, fe.evaluate(cfn).getCellType());
  328. assertEquals(Cell.CELL_TYPE_STRING, fe.evaluate(cfs).getCellType());
  329. fe.evaluateFormulaCell(cfn);
  330. fe.evaluateFormulaCell(cfs);
  331. // Now test
  332. assertEquals(Cell.CELL_TYPE_NUMERIC, cn.getCellType());
  333. assertEquals(Cell.CELL_TYPE_STRING, cs.getCellType());
  334. assertEquals(Cell.CELL_TYPE_FORMULA, cfn.getCellType());
  335. assertEquals(Cell.CELL_TYPE_NUMERIC, cfn.getCachedFormulaResultType());
  336. assertEquals(Cell.CELL_TYPE_FORMULA, cfs.getCellType());
  337. assertEquals(Cell.CELL_TYPE_STRING, cfs.getCachedFormulaResultType());
  338. // Different ways of retrieving
  339. assertEquals(1.2, cn.getNumericCellValue());
  340. try {
  341. cn.getRichStringCellValue();
  342. fail();
  343. } catch(IllegalStateException e) {}
  344. assertEquals("Testing", cs.getStringCellValue());
  345. try {
  346. cs.getNumericCellValue();
  347. fail();
  348. } catch(IllegalStateException e) {}
  349. assertEquals(1.2, cfn.getNumericCellValue());
  350. try {
  351. cfn.getRichStringCellValue();
  352. fail();
  353. } catch(IllegalStateException e) {}
  354. assertEquals("Testing", cfs.getStringCellValue());
  355. try {
  356. cfs.getNumericCellValue();
  357. fail();
  358. } catch(IllegalStateException e) {}
  359. }
  360. }
  361. /**
  362. * A problem file from a non-standard source (a scientific instrument that saves its
  363. * output as an .xlsx file) that have two issues:
  364. * 1. The Content Type part name is lower-case: [content_types].xml
  365. * 2. The file appears to use backslashes as path separators
  366. *
  367. * The OPC spec tolerates both of these peculiarities, so does POI
  368. */
  369. public void test49609() throws Exception {
  370. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("49609.xlsx");
  371. assertEquals("FAM", wb.getSheetName(0));
  372. assertEquals("Cycle", wb.getSheetAt(0).getRow(0).getCell(1).getStringCellValue());
  373. }
  374. public void test49783() throws Exception {
  375. Workbook wb = XSSFTestDataSamples.openSampleWorkbook("49783.xlsx");
  376. Sheet sheet = wb.getSheetAt(0);
  377. FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  378. Cell cell;
  379. cell = sheet.getRow(0).getCell(0);
  380. assertEquals("#REF!*#REF!", cell.getCellFormula());
  381. assertEquals(Cell.CELL_TYPE_ERROR, evaluator.evaluateInCell(cell).getCellType());
  382. assertEquals("#REF!", FormulaError.forInt(cell.getErrorCellValue()).getString());
  383. Name nm1 = wb.getName("sale_1");
  384. assertNotNull("name sale_1 should be present", nm1);
  385. assertEquals("Sheet1!#REF!", nm1.getRefersToFormula());
  386. Name nm2 = wb.getName("sale_2");
  387. assertNotNull("name sale_2 should be present", nm2);
  388. assertEquals("Sheet1!#REF!", nm2.getRefersToFormula());
  389. cell = sheet.getRow(1).getCell(0);
  390. assertEquals("sale_1*sale_2", cell.getCellFormula());
  391. assertEquals(Cell.CELL_TYPE_ERROR, evaluator.evaluateInCell(cell).getCellType());
  392. assertEquals("#REF!", FormulaError.forInt(cell.getErrorCellValue()).getString());
  393. }
  394. /**
  395. * Creating a rich string of "hello world" and applying
  396. * a font to characters 1-5 means we have two strings,
  397. * "hello" and " world". As such, we need to apply
  398. * preserve spaces to the 2nd bit, lest we end up
  399. * with something like "helloworld" !
  400. */
  401. public void test49941() throws Exception {
  402. XSSFWorkbook wb = new XSSFWorkbook();
  403. XSSFSheet s = wb.createSheet();
  404. XSSFRow r = s.createRow(0);
  405. XSSFCell c = r.createCell(0);
  406. // First without fonts
  407. c.setCellValue(
  408. new XSSFRichTextString(" with spaces ")
  409. );
  410. assertEquals(" with spaces ", c.getRichStringCellValue().toString());
  411. assertEquals(0, c.getRichStringCellValue().getCTRst().sizeOfRArray());
  412. assertEquals(true, c.getRichStringCellValue().getCTRst().isSetT());
  413. // Should have the preserve set
  414. assertEquals(
  415. 1,
  416. c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().getLength()
  417. );
  418. assertEquals(
  419. "preserve",
  420. c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().item(0).getNodeValue()
  421. );
  422. // Save and check
  423. wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  424. s = wb.getSheetAt(0);
  425. r = s.getRow(0);
  426. c = r.getCell(0);
  427. assertEquals(" with spaces ", c.getRichStringCellValue().toString());
  428. assertEquals(0, c.getRichStringCellValue().getCTRst().sizeOfRArray());
  429. assertEquals(true, c.getRichStringCellValue().getCTRst().isSetT());
  430. // Change the string
  431. c.setCellValue(
  432. new XSSFRichTextString("hello world")
  433. );
  434. assertEquals("hello world", c.getRichStringCellValue().toString());
  435. // Won't have preserve
  436. assertEquals(
  437. 0,
  438. c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().getLength()
  439. );
  440. // Apply a font
  441. XSSFFont f = wb.createFont();
  442. f.setBold(true);
  443. c.getRichStringCellValue().applyFont(0, 5, f);
  444. assertEquals("hello world", c.getRichStringCellValue().toString());
  445. // Does need preserving on the 2nd part
  446. assertEquals(2, c.getRichStringCellValue().getCTRst().sizeOfRArray());
  447. assertEquals(
  448. 0,
  449. c.getRichStringCellValue().getCTRst().getRArray(0).xgetT().getDomNode().getAttributes().getLength()
  450. );
  451. assertEquals(
  452. 1,
  453. c.getRichStringCellValue().getCTRst().getRArray(1).xgetT().getDomNode().getAttributes().getLength()
  454. );
  455. assertEquals(
  456. "preserve",
  457. c.getRichStringCellValue().getCTRst().getRArray(1).xgetT().getDomNode().getAttributes().item(0).getNodeValue()
  458. );
  459. // Save and check
  460. wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  461. s = wb.getSheetAt(0);
  462. r = s.getRow(0);
  463. c = r.getCell(0);
  464. assertEquals("hello world", c.getRichStringCellValue().toString());
  465. }
  466. /**
  467. * Repeatedly writing the same file which has styles
  468. * TODO Currently failing
  469. */
  470. public void DISABLEDtest49940() throws Exception {
  471. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("styles.xlsx");
  472. assertEquals(3, wb.getNumberOfSheets());
  473. assertEquals(10, wb.getStylesSource().getNumCellStyles());
  474. ByteArrayOutputStream b1 = new ByteArrayOutputStream();
  475. ByteArrayOutputStream b2 = new ByteArrayOutputStream();
  476. ByteArrayOutputStream b3 = new ByteArrayOutputStream();
  477. wb.write(b1);
  478. wb.write(b2);
  479. wb.write(b3);
  480. for(byte[] data : new byte[][] {
  481. b1.toByteArray(), b2.toByteArray(), b3.toByteArray()
  482. }) {
  483. ByteArrayInputStream bais = new ByteArrayInputStream(data);
  484. wb = new XSSFWorkbook(bais);
  485. assertEquals(3, wb.getNumberOfSheets());
  486. assertEquals(10, wb.getStylesSource().getNumCellStyles());
  487. }
  488. }
  489. /**
  490. * Various ways of removing a cell formula should all zap
  491. * the calcChain entry.
  492. */
  493. public void test49966() throws Exception {
  494. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("shared_formulas.xlsx");
  495. XSSFSheet sheet = wb.getSheetAt(0);
  496. // CalcChain has lots of entries
  497. CalculationChain cc = wb.getCalculationChain();
  498. assertEquals("A2", cc.getCTCalcChain().getCArray(0).getR());
  499. assertEquals("A3", cc.getCTCalcChain().getCArray(1).getR());
  500. assertEquals("A4", cc.getCTCalcChain().getCArray(2).getR());
  501. assertEquals("A5", cc.getCTCalcChain().getCArray(3).getR());
  502. assertEquals("A6", cc.getCTCalcChain().getCArray(4).getR());
  503. assertEquals("A7", cc.getCTCalcChain().getCArray(5).getR());
  504. assertEquals("A8", cc.getCTCalcChain().getCArray(6).getR());
  505. assertEquals(40, cc.getCTCalcChain().sizeOfCArray());
  506. // Try various ways of changing the formulas
  507. // If it stays a formula, chain entry should remain
  508. // Otherwise should go
  509. sheet.getRow(1).getCell(0).setCellFormula("A1"); // stay
  510. sheet.getRow(2).getCell(0).setCellFormula(null); // go
  511. sheet.getRow(3).getCell(0).setCellType(Cell.CELL_TYPE_FORMULA); // stay
  512. sheet.getRow(4).getCell(0).setCellType(Cell.CELL_TYPE_STRING); // go
  513. sheet.getRow(5).removeCell(
  514. sheet.getRow(5).getCell(0) // go
  515. );
  516. sheet.getRow(6).getCell(0).setCellType(Cell.CELL_TYPE_BLANK); // go
  517. sheet.getRow(7).getCell(0).setCellValue((String)null); // go
  518. // Save and check
  519. wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  520. assertEquals(35, cc.getCTCalcChain().sizeOfCArray());
  521. cc = wb.getCalculationChain();
  522. assertEquals("A2", cc.getCTCalcChain().getCArray(0).getR());
  523. assertEquals("A4", cc.getCTCalcChain().getCArray(1).getR());
  524. assertEquals("A9", cc.getCTCalcChain().getCArray(2).getR());
  525. }
  526. public void test49156() throws Exception {
  527. Workbook wb = XSSFTestDataSamples.openSampleWorkbook("49156.xlsx");
  528. FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
  529. Sheet sheet = wb.getSheetAt(0);
  530. for(Row row : sheet){
  531. for(Cell cell : row){
  532. if(cell.getCellType() == Cell.CELL_TYPE_FORMULA){
  533. formulaEvaluator.evaluateInCell(cell); // caused NPE on some cells
  534. }
  535. }
  536. }
  537. }
  538. /**
  539. * Newlines are valid characters in a formula
  540. */
  541. public void test50440() throws Exception {
  542. Workbook wb = XSSFTestDataSamples.openSampleWorkbook("NewlineInFormulas.xlsx");
  543. Sheet s = wb.getSheetAt(0);
  544. Cell c = s.getRow(0).getCell(0);
  545. assertEquals("SUM(\n1,2\n)", c.getCellFormula());
  546. assertEquals(3.0, c.getNumericCellValue());
  547. FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
  548. formulaEvaluator.evaluateFormulaCell(c);
  549. assertEquals("SUM(\n1,2\n)", c.getCellFormula());
  550. assertEquals(3.0, c.getNumericCellValue());
  551. }
  552. /**
  553. * Moving a cell comment from one cell to another
  554. */
  555. public void test50795() throws Exception {
  556. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50795.xlsx");
  557. XSSFSheet sheet = wb.getSheetAt(0);
  558. XSSFRow row = sheet.getRow(0);
  559. XSSFCell cellWith = row.getCell(0);
  560. XSSFCell cellWithoutComment = row.getCell(1);
  561. assertNotNull(cellWith.getCellComment());
  562. assertNull(cellWithoutComment.getCellComment());
  563. String exp = "\u0410\u0432\u0442\u043e\u0440:\ncomment";
  564. XSSFComment comment = cellWith.getCellComment();
  565. assertEquals(exp, comment.getString().getString());
  566. // Check we can write it out and read it back as-is
  567. wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  568. sheet = wb.getSheetAt(0);
  569. row = sheet.getRow(0);
  570. cellWith = row.getCell(0);
  571. cellWithoutComment = row.getCell(1);
  572. // Double check things are as expected
  573. assertNotNull(cellWith.getCellComment());
  574. assertNull(cellWithoutComment.getCellComment());
  575. comment = cellWith.getCellComment();
  576. assertEquals(exp, comment.getString().getString());
  577. // Move the comment
  578. cellWithoutComment.setCellComment(comment);
  579. // Write out and re-check
  580. wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  581. sheet = wb.getSheetAt(0);
  582. row = sheet.getRow(0);
  583. // Ensure it swapped over
  584. cellWith = row.getCell(0);
  585. cellWithoutComment = row.getCell(1);
  586. assertNull(cellWith.getCellComment());
  587. assertNotNull(cellWithoutComment.getCellComment());
  588. comment = cellWithoutComment.getCellComment();
  589. assertEquals(exp, comment.getString().getString());
  590. }
  591. /**
  592. * When the cell background colour is set with one of the first
  593. * two columns of the theme colour palette, the colours are
  594. * shades of white or black.
  595. * For those cases, ensure we don't break on reading the colour
  596. */
  597. public void test50299() throws Exception {
  598. Workbook wb = XSSFTestDataSamples.openSampleWorkbook("50299.xlsx");
  599. // Check all the colours
  600. for(int sn=0; sn<wb.getNumberOfSheets(); sn++) {
  601. Sheet s = wb.getSheetAt(sn);
  602. for(Row r : s) {
  603. for(Cell c : r) {
  604. CellStyle cs = c.getCellStyle();
  605. if(cs != null) {
  606. cs.getFillForegroundColor();
  607. }
  608. }
  609. }
  610. }
  611. // Check one bit in detail
  612. // Check that we get back foreground=0 for the theme colours,
  613. // and background=64 for the auto colouring
  614. Sheet s = wb.getSheetAt(0);
  615. assertEquals(0, s.getRow(0).getCell(8).getCellStyle().getFillForegroundColor());
  616. assertEquals(64, s.getRow(0).getCell(8).getCellStyle().getFillBackgroundColor());
  617. assertEquals(0, s.getRow(1).getCell(8).getCellStyle().getFillForegroundColor());
  618. assertEquals(64, s.getRow(1).getCell(8).getCellStyle().getFillBackgroundColor());
  619. }
  620. /**
  621. * Excel .xls style indexed colours in a .xlsx file
  622. */
  623. public void test50786() throws Exception {
  624. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50786-indexed_colours.xlsx");
  625. XSSFSheet s = wb.getSheetAt(0);
  626. XSSFRow r = s.getRow(2);
  627. // Check we have the right cell
  628. XSSFCell c = r.getCell(1);
  629. assertEquals("test\u00a0", c.getRichStringCellValue().getString());
  630. // It should be light green
  631. XSSFCellStyle cs = c.getCellStyle();
  632. assertEquals(42, cs.getFillForegroundColor());
  633. assertEquals(42, cs.getFillForegroundColorColor().getIndexed());
  634. assertNotNull(cs.getFillForegroundColorColor().getRgb());
  635. assertEquals("FFCCFFCC", cs.getFillForegroundColorColor().getARGBHex());
  636. }
  637. /**
  638. * If the border colours are set with themes, then we
  639. * should still be able to get colours
  640. */
  641. public void test50846() throws Exception {
  642. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50846-border_colours.xlsx");
  643. XSSFSheet sheet = wb.getSheetAt(0);
  644. XSSFRow row = sheet.getRow(0);
  645. // Border from a theme, brown
  646. XSSFCell cellT = row.getCell(0);
  647. XSSFCellStyle styleT = cellT.getCellStyle();
  648. XSSFColor colorT = styleT.getBottomBorderXSSFColor();
  649. assertEquals(5, colorT.getTheme());
  650. assertEquals("FFC0504D", colorT.getARGBHex());
  651. // Border from a style direct, red
  652. XSSFCell cellS = row.getCell(1);
  653. XSSFCellStyle styleS = cellS.getCellStyle();
  654. XSSFColor colorS = styleS.getBottomBorderXSSFColor();
  655. assertEquals(0, colorS.getTheme());
  656. assertEquals("FFFF0000", colorS.getARGBHex());
  657. }
  658. /**
  659. * Fonts where their colours come from the theme rather
  660. * then being set explicitly still should allow the
  661. * fetching of the RGB.
  662. */
  663. public void test50784() throws Exception {
  664. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50784-font_theme_colours.xlsx");
  665. XSSFSheet s = wb.getSheetAt(0);
  666. XSSFRow r = s.getRow(0);
  667. // Column 1 has a font with regular colours
  668. XSSFCell cr = r.getCell(1);
  669. XSSFFont fr = wb.getFontAt( cr.getCellStyle().getFontIndex() );
  670. XSSFColor colr = fr.getXSSFColor();
  671. // No theme, has colours
  672. assertEquals(0, colr.getTheme());
  673. assertNotNull( colr.getRgb() );
  674. // Column 0 has a font with colours from a theme
  675. XSSFCell ct = r.getCell(0);
  676. XSSFFont ft = wb.getFontAt( ct.getCellStyle().getFontIndex() );
  677. XSSFColor colt = ft.getXSSFColor();
  678. // Has a theme, which has the colours on it
  679. assertEquals(9, colt.getTheme());
  680. XSSFColor themeC = wb.getTheme().getThemeColor(colt.getTheme());
  681. assertNotNull( themeC.getRgb() );
  682. assertNotNull( colt.getRgb() );
  683. assertEquals( themeC.getARGBHex(), colt.getARGBHex() ); // The same colour
  684. }
  685. /**
  686. * New lines were being eaten when setting a font on
  687. * a rich text string
  688. */
  689. public void test48877() throws Exception {
  690. String text = "Use \n with word wrap on to create a new line.\n" +
  691. "This line finishes with two trailing spaces. ";
  692. Workbook wb = new XSSFWorkbook();
  693. Sheet sheet = wb.createSheet();
  694. Font font1 = wb.createFont();
  695. font1.setColor((short) 20);
  696. Row row = sheet.createRow(2);
  697. Cell cell = row.createCell(2);
  698. RichTextString richTextString =
  699. wb.getCreationHelper().createRichTextString(text);
  700. // Check the text has the newline
  701. assertEquals(text, richTextString.getString());
  702. // Apply the font
  703. richTextString.applyFont(0, 3, font1);
  704. cell.setCellValue(richTextString);
  705. // To enable newlines you need set a cell styles with wrap=true
  706. CellStyle cs = wb.createCellStyle();
  707. cs.setWrapText(true);
  708. cell.setCellStyle(cs);
  709. // Check the text has the
  710. assertEquals(text, cell.getStringCellValue());
  711. // Save the file and re-read it
  712. wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  713. sheet = wb.getSheetAt(0);
  714. row = sheet.getRow(2);
  715. cell = row.getCell(2);
  716. assertEquals(text, cell.getStringCellValue());
  717. }
  718. /**
  719. * Adding sheets when one has a table, then re-ordering
  720. */
  721. public void test50867() throws Exception {
  722. XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50867_with_table.xlsx");
  723. assertEquals(3, wb.getNumberOfSheets());
  724. XSSFSheet s1 = wb.getSheetAt(0);
  725. XSSFSheet s2 = wb.getSheetAt(1);
  726. XSSFSheet s3 = wb.getSheetAt(2);
  727. assertEquals(1, s1.getTables().size());
  728. assertEquals(0, s2.getTables().size());
  729. assertEquals(0, s3.getTables().size());
  730. Table t = s1.getTables().get(0);
  731. assertEquals("Tabella1", t.getName());
  732. assertEquals("Tabella1", t.getDisplayName());
  733. assertEquals("A1:C3", t.getCTTable().getRef());
  734. // Add a sheet and re-order
  735. XSSFSheet s4 = wb.createSheet("NewSheet");
  736. wb.setSheetOrder(s4.getSheetName(), 0);
  737. // Check on tables
  738. assertEquals(1, s1.getTables().size());
  739. assertEquals(0, s2.getTables().size());
  740. assertEquals(0, s3.getTables().size());
  741. assertEquals(0, s4.getTables().size());
  742. // Refetch to get the new order
  743. s1 = wb.getSheetAt(0);
  744. s2 = wb.getSheetAt(1);
  745. s3 = wb.getSheetAt(2);
  746. s4 = wb.getSheetAt(3);
  747. assertEquals(0, s1.getTables().size());
  748. assertEquals(1, s2.getTables().size());
  749. assertEquals(0, s3.getTables().size());
  750. assertEquals(0, s4.getTables().size());
  751. // Save and re-load
  752. wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
  753. s1 = wb.getSheetAt(0);
  754. s2 = wb.getSheetAt(1);
  755. s3 = wb.getSheetAt(2);
  756. s4 = wb.getSheetAt(3);
  757. assertEquals(0, s1.getTables().size());
  758. assertEquals(1, s2.getTables().size());
  759. assertEquals(0, s3.getTables().size());
  760. assertEquals(0, s4.getTables().size());
  761. t = s2.getTables().get(0);
  762. assertEquals("Tabella1", t.getName());
  763. assertEquals("Tabella1", t.getDisplayName());
  764. assertEquals("A1:C3", t.getCTTable().getRef());
  765. }
  766. }