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.

TestXSSFBugs.java 156KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.xssf.usermodel;
  16. import static java.time.Duration.between;
  17. import static java.time.Instant.now;
  18. import static org.apache.logging.log4j.util.Unbox.box;
  19. import static org.apache.poi.extractor.ExtractorFactory.OOXML_PACKAGE;
  20. import static org.apache.poi.openxml4j.opc.TestContentType.isOldXercesActive;
  21. import static org.apache.poi.ss.util.Utils.addRow;
  22. import static org.apache.poi.ss.util.Utils.assertDouble;
  23. import static org.apache.poi.xssf.XSSFTestDataSamples.openSampleWorkbook;
  24. import static org.apache.poi.xssf.XSSFTestDataSamples.writeOutAndReadBack;
  25. import static org.junit.jupiter.api.Assertions.*;
  26. import static org.junit.jupiter.api.Assumptions.assumeFalse;
  27. import java.io.BufferedReader;
  28. import java.io.ByteArrayInputStream;
  29. import java.io.File;
  30. import java.io.FileInputStream;
  31. import java.io.FileOutputStream;
  32. import java.io.IOException;
  33. import java.io.InputStream;
  34. import java.io.InputStreamReader;
  35. import java.io.OutputStream;
  36. import java.nio.charset.StandardCharsets;
  37. import java.security.GeneralSecurityException;
  38. import java.time.Duration;
  39. import java.time.Instant;
  40. import java.time.LocalDateTime;
  41. import java.util.*;
  42. import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
  43. import org.apache.commons.compress.archivers.zip.ZipFile;
  44. import org.apache.commons.io.output.NullOutputStream;
  45. import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
  46. import org.apache.logging.log4j.LogManager;
  47. import org.apache.logging.log4j.Logger;
  48. import org.apache.poi.POIDataSamples;
  49. import org.apache.poi.common.usermodel.HyperlinkType;
  50. import org.apache.poi.hssf.HSSFITestDataProvider;
  51. import org.apache.poi.hssf.HSSFTestDataSamples;
  52. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  53. import org.apache.poi.ooxml.POIXMLDocumentPart;
  54. import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
  55. import org.apache.poi.ooxml.POIXMLException;
  56. import org.apache.poi.ooxml.POIXMLProperties;
  57. import org.apache.poi.ooxml.util.DocumentHelper;
  58. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  59. import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
  60. import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
  61. import org.apache.poi.openxml4j.opc.OPCPackage;
  62. import org.apache.poi.openxml4j.opc.PackageAccess;
  63. import org.apache.poi.openxml4j.opc.PackagePart;
  64. import org.apache.poi.openxml4j.opc.PackageRelationship;
  65. import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
  66. import org.apache.poi.openxml4j.opc.PackagingURIHelper;
  67. import org.apache.poi.openxml4j.util.ZipSecureFile;
  68. import org.apache.poi.poifs.crypt.Decryptor;
  69. import org.apache.poi.poifs.crypt.EncryptionInfo;
  70. import org.apache.poi.poifs.crypt.EncryptionMode;
  71. import org.apache.poi.poifs.crypt.Encryptor;
  72. import org.apache.poi.poifs.filesystem.DirectoryNode;
  73. import org.apache.poi.poifs.filesystem.DocumentEntry;
  74. import org.apache.poi.poifs.filesystem.DocumentInputStream;
  75. import org.apache.poi.poifs.filesystem.POIFSFileSystem;
  76. import org.apache.poi.sl.usermodel.ObjectShape;
  77. import org.apache.poi.sl.usermodel.Slide;
  78. import org.apache.poi.sl.usermodel.SlideShow;
  79. import org.apache.poi.sl.usermodel.SlideShowFactory;
  80. import org.apache.poi.ss.ITestDataProvider;
  81. import org.apache.poi.ss.SpreadsheetVersion;
  82. import org.apache.poi.ss.formula.ConditionalFormattingEvaluator;
  83. import org.apache.poi.ss.formula.EvaluationConditionalFormatRule;
  84. import org.apache.poi.ss.formula.FormulaParser;
  85. import org.apache.poi.ss.formula.FormulaRenderer;
  86. import org.apache.poi.ss.formula.FormulaShifter;
  87. import org.apache.poi.ss.formula.FormulaType;
  88. import org.apache.poi.ss.formula.WorkbookEvaluator;
  89. import org.apache.poi.ss.formula.WorkbookEvaluatorProvider;
  90. import org.apache.poi.ss.formula.eval.ErrorEval;
  91. import org.apache.poi.ss.formula.eval.NumberEval;
  92. import org.apache.poi.ss.formula.eval.ValueEval;
  93. import org.apache.poi.ss.formula.functions.Function;
  94. import org.apache.poi.ss.formula.ptg.Ptg;
  95. import org.apache.poi.ss.usermodel.*;
  96. import org.apache.poi.ss.util.*;
  97. import org.apache.poi.util.IOUtils;
  98. import org.apache.poi.util.LocaleUtil;
  99. import org.apache.poi.util.TempFile;
  100. import org.apache.poi.util.XMLHelper;
  101. import org.apache.poi.xssf.SXSSFITestDataProvider;
  102. import org.apache.poi.xssf.XLSBUnsupportedException;
  103. import org.apache.poi.xssf.XSSFITestDataProvider;
  104. import org.apache.poi.xssf.XSSFTestDataSamples;
  105. import org.apache.poi.xssf.eventusermodel.XSSFReader;
  106. import org.apache.poi.xssf.model.CalculationChain;
  107. import org.apache.poi.xssf.model.SharedStringsTable;
  108. import org.apache.poi.xssf.model.StylesTable;
  109. import org.apache.poi.xssf.streaming.SXSSFWorkbook;
  110. import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill;
  111. import org.apache.xmlbeans.XmlException;
  112. import org.junit.jupiter.api.Disabled;
  113. import org.junit.jupiter.api.Tag;
  114. import org.junit.jupiter.api.Test;
  115. import org.junit.jupiter.params.ParameterizedTest;
  116. import org.junit.jupiter.params.provider.CsvSource;
  117. import org.junit.jupiter.params.provider.EnumSource;
  118. import org.junit.jupiter.params.provider.ValueSource;
  119. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell;
  120. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
  121. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
  122. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames;
  123. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell;
  124. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells;
  125. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
  126. import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
  127. import org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTFontImpl;
  128. import org.xml.sax.InputSource;
  129. import org.xml.sax.SAXParseException;
  130. import org.xml.sax.XMLReader;
  131. public final class TestXSSFBugs extends BaseTestBugzillaIssues {
  132. private static final Logger LOG = LogManager.getLogger(TestXSSFBugs.class);
  133. public TestXSSFBugs() {
  134. super(XSSFITestDataProvider.instance);
  135. }
  136. /**
  137. * Named ranges had the right reference, but
  138. * the wrong sheet name
  139. */
  140. @Test
  141. void bug45430() throws IOException {
  142. try (XSSFWorkbook wb = openSampleWorkbook("45430.xlsx")) {
  143. assertFalse(wb.isMacroEnabled());
  144. assertEquals(3, wb.getNumberOfNames());
  145. assertEquals(0, wb.getName("SheetAA1").getCTName().getLocalSheetId());
  146. assertFalse(wb.getName("SheetAA1").getCTName().isSetLocalSheetId());
  147. assertEquals("SheetA!$A$1", wb.getName("SheetAA1").getRefersToFormula());
  148. assertEquals("SheetA", wb.getName("SheetAA1").getSheetName());
  149. assertEquals(0, wb.getName("SheetBA1").getCTName().getLocalSheetId());
  150. assertFalse(wb.getName("SheetBA1").getCTName().isSetLocalSheetId());
  151. assertEquals("SheetB!$A$1", wb.getName("SheetBA1").getRefersToFormula());
  152. assertEquals("SheetB", wb.getName("SheetBA1").getSheetName());
  153. assertEquals(0, wb.getName("SheetCA1").getCTName().getLocalSheetId());
  154. assertFalse(wb.getName("SheetCA1").getCTName().isSetLocalSheetId());
  155. assertEquals("SheetC!$A$1", wb.getName("SheetCA1").getRefersToFormula());
  156. assertEquals("SheetC", wb.getName("SheetCA1").getSheetName());
  157. // Save and re-load, still there
  158. try (XSSFWorkbook nwb = writeOutAndReadBack(wb)) {
  159. assertEquals(3, nwb.getNumberOfNames());
  160. assertEquals("SheetA!$A$1", nwb.getName("SheetAA1").getRefersToFormula());
  161. }
  162. }
  163. }
  164. /**
  165. * We should carry vba macros over after save
  166. */
  167. @Test
  168. void bug45431() throws IOException, InvalidFormatException {
  169. try (XSSFWorkbook wb1 = openSampleWorkbook("45431.xlsm");
  170. OPCPackage pkg1 = wb1.getPackage()) {
  171. assertTrue(wb1.isMacroEnabled());
  172. // Check the various macro related bits can be found
  173. PackagePart vba = pkg1.getPart(
  174. PackagingURIHelper.createPartName("/xl/vbaProject.bin")
  175. );
  176. assertNotNull(vba);
  177. // And the drawing bit
  178. PackagePart drw = pkg1.getPart(
  179. PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
  180. );
  181. assertNotNull(drw);
  182. // Save and re-open, both still there
  183. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1);
  184. OPCPackage pkg2 = wb2.getPackage()) {
  185. assertTrue(wb2.isMacroEnabled());
  186. vba = pkg2.getPart(
  187. PackagingURIHelper.createPartName("/xl/vbaProject.bin")
  188. );
  189. assertNotNull(vba);
  190. drw = pkg2.getPart(
  191. PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
  192. );
  193. assertNotNull(drw);
  194. // And again, just to be sure
  195. try (XSSFWorkbook wb3 = writeOutAndReadBack(wb2);
  196. OPCPackage pkg3 = wb3.getPackage()) {
  197. assertTrue(wb3.isMacroEnabled());
  198. vba = pkg3.getPart(
  199. PackagingURIHelper.createPartName("/xl/vbaProject.bin")
  200. );
  201. assertNotNull(vba);
  202. drw = pkg3.getPart(
  203. PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
  204. );
  205. assertNotNull(drw);
  206. }
  207. }
  208. }
  209. }
  210. @Test
  211. void bug47504() throws IOException {
  212. try (XSSFWorkbook wb1 = openSampleWorkbook("47504.xlsx")) {
  213. assertEquals(1, wb1.getNumberOfSheets());
  214. XSSFSheet sh = wb1.getSheetAt(0);
  215. XSSFDrawing drawing = sh.createDrawingPatriarch();
  216. List<RelationPart> rels = drawing.getRelationParts();
  217. assertEquals(1, rels.size());
  218. assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment());
  219. // And again, just to be sure
  220. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  221. assertEquals(1, wb2.getNumberOfSheets());
  222. sh = wb2.getSheetAt(0);
  223. drawing = sh.createDrawingPatriarch();
  224. rels = drawing.getRelationParts();
  225. assertEquals(1, rels.size());
  226. assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment());
  227. }
  228. }
  229. }
  230. /**
  231. * Excel will sometimes write a button with a textbox
  232. * containing &gt;br&lt; (not closed!).
  233. * Clearly Excel shouldn't do this, but test that we can
  234. * read the file despite the naughtiness
  235. */
  236. @Test
  237. void bug49020() throws IOException {
  238. try (XSSFWorkbook wb = openSampleWorkbook("BrNotClosed.xlsx")) {
  239. assertNotNull(wb);
  240. }
  241. }
  242. /**
  243. * ensure that CTPhoneticPr is loaded by the ooxml test suite so that it is included in poi-ooxml-lite
  244. */
  245. @Test
  246. void bug49325() throws IOException {
  247. try (XSSFWorkbook wb = openSampleWorkbook("49325.xlsx")) {
  248. CTWorksheet sh = wb.getSheetAt(0).getCTWorksheet();
  249. assertNotNull(sh.getPhoneticPr());
  250. }
  251. }
  252. /**
  253. * Names which are defined with a Sheet
  254. * should return that sheet index properly
  255. */
  256. @Test
  257. void bug48923() throws IOException {
  258. try (XSSFWorkbook wb = openSampleWorkbook("48923.xlsx")) {
  259. assertEquals(4, wb.getNumberOfNames());
  260. Name b1 = wb.getName("NameB1");
  261. Name b2 = wb.getName("NameB2");
  262. Name sheet2 = wb.getName("NameSheet2");
  263. Name test = wb.getName("Test");
  264. assertNotNull(b1);
  265. assertEquals("NameB1", b1.getNameName());
  266. assertEquals("Sheet1", b1.getSheetName());
  267. assertEquals(-1, b1.getSheetIndex());
  268. assertFalse(b1.isDeleted());
  269. assertFalse(b1.isHidden());
  270. assertNotNull(b2);
  271. assertEquals("NameB2", b2.getNameName());
  272. assertEquals("Sheet1", b2.getSheetName());
  273. assertEquals(-1, b2.getSheetIndex());
  274. assertFalse(b2.isDeleted());
  275. assertFalse(b2.isHidden());
  276. assertNotNull(sheet2);
  277. assertEquals("NameSheet2", sheet2.getNameName());
  278. assertEquals("Sheet2", sheet2.getSheetName());
  279. assertEquals(-1, sheet2.getSheetIndex());
  280. assertNotNull(test);
  281. assertEquals("Test", test.getNameName());
  282. assertEquals("Sheet1", test.getSheetName());
  283. assertEquals(-1, test.getSheetIndex());
  284. }
  285. }
  286. /**
  287. * Problem with evaluation formulas due to
  288. * NameXPtgs.
  289. * Blows up on:
  290. * IF(B6= (ROUNDUP(B6,0) + ROUNDDOWN(B6,0))/2, MROUND(B6,2),ROUND(B6,0))
  291. * <p>
  292. * TODO: delete this test case when MROUND and VAR are implemented
  293. */
  294. @Test
  295. void bug48539() throws IOException {
  296. try (XSSFWorkbook wb = openSampleWorkbook("48539.xlsx")) {
  297. assertEquals(3, wb.getNumberOfSheets());
  298. assertEquals(0, wb.getNumberOfNames());
  299. // Try each cell individually
  300. XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
  301. for (int i = 0; i < wb.getNumberOfSheets(); i++) {
  302. Sheet s = wb.getSheetAt(i);
  303. for (Row r : s) {
  304. for (Cell c : r) {
  305. if (c.getCellType() == CellType.FORMULA) {
  306. CellValue cv = eval.evaluate(c);
  307. if (cv.getCellType() == CellType.NUMERIC) {
  308. // assert that the calculated value agrees with
  309. // the cached formula result calculated by Excel
  310. String formula = c.getCellFormula();
  311. double cachedFormulaResult = c.getNumericCellValue();
  312. double evaluatedFormulaResult = cv.getNumberValue();
  313. assertEquals(cachedFormulaResult, evaluatedFormulaResult, 1E-7, formula);
  314. }
  315. }
  316. }
  317. }
  318. }
  319. // Now all of them
  320. XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
  321. }
  322. }
  323. /**
  324. * Foreground colours should be found even if
  325. * a theme is used
  326. */
  327. @Test
  328. void bug48779() throws IOException {
  329. try (XSSFWorkbook wb = openSampleWorkbook("48779.xlsx")) {
  330. XSSFCell cell = wb.getSheetAt(0).getRow(0).getCell(0);
  331. XSSFCellStyle cs = cell.getCellStyle();
  332. assertNotNull(cs);
  333. assertEquals(1, cs.getIndex());
  334. // Look at the low level xml elements
  335. assertEquals(2, cs.getCoreXf().getFillId());
  336. assertEquals(0, cs.getCoreXf().getXfId());
  337. assertTrue(cs.getCoreXf().getApplyFill());
  338. XSSFCellFill fg = wb.getStylesSource().getFillAt(2);
  339. assertNotNull(fg.getFillForegroundColor());
  340. assertEquals(0, fg.getFillForegroundColor().getIndexed());
  341. assertEquals(0.0, fg.getFillForegroundColor().getTint(), 0);
  342. assertEquals("FFFF0000", fg.getFillForegroundColor().getARGBHex());
  343. assertNotNull(fg.getFillBackgroundColor());
  344. assertEquals(64, fg.getFillBackgroundColor().getIndexed());
  345. // Now look higher up
  346. assertNotNull(cs.getFillForegroundXSSFColor());
  347. assertEquals(0, cs.getFillForegroundColor());
  348. assertEquals("FFFF0000", cs.getFillForegroundXSSFColor().getARGBHex());
  349. assertEquals("FFFF0000", cs.getFillForegroundColorColor().getARGBHex());
  350. assertEquals(64, cs.getFillBackgroundColor());
  351. assertNull(cs.getFillBackgroundXSSFColor().getARGBHex());
  352. assertNull(cs.getFillBackgroundColorColor().getARGBHex());
  353. }
  354. }
  355. /**
  356. * Ensure General and @ format are working properly
  357. * for integers
  358. */
  359. @Test
  360. void bug47490() throws IOException {
  361. try (XSSFWorkbook wb = openSampleWorkbook("GeneralFormatTests.xlsx")) {
  362. Sheet s = wb.getSheetAt(1);
  363. Row r;
  364. DataFormatter df = new DataFormatter();
  365. r = s.getRow(1);
  366. assertEquals(1.0, r.getCell(2).getNumericCellValue(), 0);
  367. assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
  368. assertEquals("1", df.formatCellValue(r.getCell(2)));
  369. assertEquals("1", df.formatRawCellContents(1.0, -1, "@"));
  370. assertEquals("1", df.formatRawCellContents(1.0, -1, "General"));
  371. r = s.getRow(2);
  372. assertEquals(12.0, r.getCell(2).getNumericCellValue(), 0);
  373. assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
  374. assertEquals("12", df.formatCellValue(r.getCell(2)));
  375. assertEquals("12", df.formatRawCellContents(12.0, -1, "@"));
  376. assertEquals("12", df.formatRawCellContents(12.0, -1, "General"));
  377. r = s.getRow(3);
  378. assertEquals(123.0, r.getCell(2).getNumericCellValue(), 0);
  379. assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
  380. assertEquals("123", df.formatCellValue(r.getCell(2)));
  381. assertEquals("123", df.formatRawCellContents(123.0, -1, "@"));
  382. assertEquals("123", df.formatRawCellContents(123.0, -1, "General"));
  383. }
  384. }
  385. /**
  386. * A problem file from a non-standard source (a scientific instrument that saves its
  387. * output as an .xlsx file) that have two issues:
  388. * 1. The Content Type part name is lower-case: [content_types].xml
  389. * 2. The file appears to use backslashes as path separators
  390. * <p>
  391. * The OPC spec tolerates both of these peculiarities, so does POI
  392. */
  393. @Test
  394. void bug49609() throws IOException {
  395. try (XSSFWorkbook wb = openSampleWorkbook("49609.xlsx")) {
  396. assertEquals("FAM", wb.getSheetName(0));
  397. assertEquals("Cycle", wb.getSheetAt(0).getRow(0).getCell(1).getStringCellValue());
  398. }
  399. }
  400. @Test
  401. void bug49783() throws IOException {
  402. try (Workbook wb = openSampleWorkbook("49783.xlsx")) {
  403. Sheet sheet = wb.getSheetAt(0);
  404. FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  405. Cell cell;
  406. cell = sheet.getRow(0).getCell(0);
  407. assertEquals("#REF!*#REF!", cell.getCellFormula());
  408. assertEquals(CellType.ERROR, evaluator.evaluateInCell(cell).getCellType());
  409. assertEquals("#REF!", FormulaError.forInt(cell.getErrorCellValue()).getString());
  410. Name nm1 = wb.getName("sale_1");
  411. assertNotNull(nm1, "name sale_1 should be present");
  412. assertEquals("Sheet1!#REF!", nm1.getRefersToFormula());
  413. Name nm2 = wb.getName("sale_2");
  414. assertNotNull(nm2, "name sale_2 should be present");
  415. assertEquals("Sheet1!#REF!", nm2.getRefersToFormula());
  416. cell = sheet.getRow(1).getCell(0);
  417. assertEquals("sale_1*sale_2", cell.getCellFormula());
  418. assertEquals(CellType.ERROR, evaluator.evaluateInCell(cell).getCellType());
  419. assertEquals("#REF!", FormulaError.forInt(cell.getErrorCellValue()).getString());
  420. }
  421. }
  422. /**
  423. * Creating a rich string of "hello world" and applying
  424. * a font to characters 1-5 means we have two strings,
  425. * "hello" and " world". As such, we need to apply
  426. * preserve spaces to the 2nd bit, lest we end up
  427. * with something like "helloworld" !
  428. */
  429. @Test
  430. void bug49941() throws IOException {
  431. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  432. XSSFSheet s = wb1.createSheet();
  433. XSSFRow r = s.createRow(0);
  434. XSSFCell c = r.createCell(0);
  435. // First without fonts
  436. c.setCellValue(
  437. new XSSFRichTextString(" with spaces ")
  438. );
  439. assertEquals(" with spaces ", c.getRichStringCellValue().toString());
  440. assertEquals(0, c.getRichStringCellValue().getCTRst().sizeOfRArray());
  441. assertTrue(c.getRichStringCellValue().getCTRst().isSetT());
  442. // Should have the preserve set
  443. assertEquals(
  444. 1,
  445. c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().getLength()
  446. );
  447. assertEquals(
  448. "preserve",
  449. c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().item(0).getNodeValue()
  450. );
  451. // Save and check
  452. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  453. s = wb2.getSheetAt(0);
  454. r = s.getRow(0);
  455. c = r.getCell(0);
  456. assertEquals(" with spaces ", c.getRichStringCellValue().toString());
  457. assertEquals(0, c.getRichStringCellValue().getCTRst().sizeOfRArray());
  458. assertTrue(c.getRichStringCellValue().getCTRst().isSetT());
  459. // Change the string
  460. c.setCellValue(
  461. new XSSFRichTextString("hello world")
  462. );
  463. assertEquals("hello world", c.getRichStringCellValue().toString());
  464. // Won't have preserve
  465. assertEquals(
  466. 0,
  467. c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().getLength()
  468. );
  469. // Apply a font
  470. XSSFFont f = wb2.createFont();
  471. f.setBold(true);
  472. c.getRichStringCellValue().applyFont(0, 5, f);
  473. assertEquals("hello world", c.getRichStringCellValue().toString());
  474. // Does need preserving on the 2nd part
  475. assertEquals(2, c.getRichStringCellValue().getCTRst().sizeOfRArray());
  476. assertEquals(
  477. 0,
  478. c.getRichStringCellValue().getCTRst().getRArray(0).xgetT().getDomNode().getAttributes().getLength()
  479. );
  480. assertEquals(
  481. 1,
  482. c.getRichStringCellValue().getCTRst().getRArray(1).xgetT().getDomNode().getAttributes().getLength()
  483. );
  484. assertEquals(
  485. "preserve",
  486. c.getRichStringCellValue().getCTRst().getRArray(1).xgetT().getDomNode().getAttributes().item(0).getNodeValue()
  487. );
  488. // Save and check
  489. try (XSSFWorkbook wb3 = writeOutAndReadBack(wb2)) {
  490. s = wb3.getSheetAt(0);
  491. r = s.getRow(0);
  492. c = r.getCell(0);
  493. assertEquals("hello world", c.getRichStringCellValue().toString());
  494. }
  495. }
  496. }
  497. }
  498. /**
  499. * Repeatedly writing the same file which has styles
  500. */
  501. @Test
  502. void bug49940() throws IOException {
  503. try (XSSFWorkbook wb = openSampleWorkbook("styles.xlsx")) {
  504. assertEquals(3, wb.getNumberOfSheets());
  505. assertEquals(10, wb.getStylesSource().getNumCellStyles());
  506. for (int i=0; i<3; i++) {
  507. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb)) {
  508. assertEquals(3, wb2.getNumberOfSheets());
  509. assertEquals(10, wb2.getStylesSource().getNumCellStyles());
  510. }
  511. }
  512. }
  513. }
  514. /**
  515. * Various ways of removing a cell formula should all zap the calcChain
  516. * entry.
  517. */
  518. @Test
  519. void bug49966() throws IOException {
  520. try (XSSFWorkbook wb1 = openSampleWorkbook("shared_formulas.xlsx")) {
  521. XSSFSheet sheet = wb1.getSheetAt(0);
  522. writeOutAndReadBack(wb1).close();
  523. // CalcChain has lots of entries
  524. CalculationChain cc = wb1.getCalculationChain();
  525. assertEquals("A2", cc.getCTCalcChain().getCArray(0).getR());
  526. assertEquals("A3", cc.getCTCalcChain().getCArray(1).getR());
  527. assertEquals("A4", cc.getCTCalcChain().getCArray(2).getR());
  528. assertEquals("A5", cc.getCTCalcChain().getCArray(3).getR());
  529. assertEquals("A6", cc.getCTCalcChain().getCArray(4).getR());
  530. assertEquals("A7", cc.getCTCalcChain().getCArray(5).getR());
  531. assertEquals("A8", cc.getCTCalcChain().getCArray(6).getR());
  532. assertEquals(40, cc.getCTCalcChain().sizeOfCArray());
  533. writeOutAndReadBack(wb1).close();
  534. // Try various ways of changing the formulas
  535. // If it stays a formula, chain entry should remain
  536. // Otherwise should go
  537. sheet.getRow(1).getCell(0).setCellFormula("A1"); // stay
  538. sheet.getRow(2).getCell(0).setCellFormula(null); // go
  539. sheet.getRow(3).getCell(0).setCellFormula("14"); // stay
  540. writeOutAndReadBack(wb1).close();
  541. sheet.getRow(4).getCell(0).setBlank(); // go
  542. writeOutAndReadBack(wb1).close();
  543. validateCells(sheet);
  544. sheet.getRow(5).removeCell(sheet.getRow(5).getCell(0)); // go
  545. validateCells(sheet);
  546. writeOutAndReadBack(wb1).close();
  547. sheet.getRow(6).getCell(0).setBlank(); // go
  548. writeOutAndReadBack(wb1).close();
  549. sheet.getRow(7).getCell(0).setCellValue((String) null); // go
  550. writeOutAndReadBack(wb1).close();
  551. // Save and check
  552. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  553. wb1.close();
  554. assertEquals(35, cc.getCTCalcChain().sizeOfCArray());
  555. cc = wb2.getCalculationChain();
  556. assertEquals("A2", cc.getCTCalcChain().getCArray(0).getR());
  557. assertEquals("A4", cc.getCTCalcChain().getCArray(1).getR());
  558. assertEquals("A9", cc.getCTCalcChain().getCArray(2).getR());
  559. }
  560. }
  561. }
  562. @Test
  563. void bug49966Row() throws IOException {
  564. try (XSSFWorkbook wb = openSampleWorkbook("shared_formulas.xlsx")) {
  565. XSSFSheet sheet = wb.getSheetAt(0);
  566. validateCells(sheet);
  567. sheet.getRow(5).removeCell(sheet.getRow(5).getCell(0)); // go
  568. validateCells(sheet);
  569. }
  570. }
  571. private void validateCells(XSSFSheet sheet) {
  572. for (Row row : sheet) {
  573. // trigger handling
  574. ((XSSFRow) row).onDocumentWrite();
  575. }
  576. }
  577. @Test
  578. void bug49156() throws IOException {
  579. try (Workbook wb = openSampleWorkbook("49156.xlsx")) {
  580. FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
  581. Sheet sheet = wb.getSheetAt(0);
  582. for (Row row : sheet) {
  583. for (Cell cell : row) {
  584. if (cell.getCellType() == CellType.FORMULA) {
  585. // caused NPE on some cells
  586. assertDoesNotThrow(() -> formulaEvaluator.evaluateInCell(cell));
  587. }
  588. }
  589. }
  590. }
  591. }
  592. /**
  593. * Newlines are valid characters in a formula
  594. */
  595. @Test
  596. void bug50440And51875() throws IOException {
  597. try (Workbook wb = openSampleWorkbook("NewlineInFormulas.xlsx")) {
  598. Sheet s = wb.getSheetAt(0);
  599. Cell c = s.getRow(0).getCell(0);
  600. assertEquals("SUM(\n1,2\n)", c.getCellFormula());
  601. assertEquals(3.0, c.getNumericCellValue(), 0);
  602. FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
  603. formulaEvaluator.evaluateFormulaCell(c);
  604. assertEquals("SUM(\n1,2\n)", c.getCellFormula());
  605. assertEquals(3.0, c.getNumericCellValue(), 0);
  606. // For 51875
  607. Cell b3 = s.getRow(2).getCell(1);
  608. formulaEvaluator.evaluateFormulaCell(b3);
  609. assertEquals("B1+B2", b3.getCellFormula()); // The newline is lost for shared formulas
  610. assertEquals(3.0, b3.getNumericCellValue(), 0);
  611. }
  612. }
  613. /**
  614. * Moving a cell comment from one cell to another
  615. */
  616. @Test
  617. void bug50795() throws IOException {
  618. try (XSSFWorkbook wb1 = openSampleWorkbook("50795.xlsx")) {
  619. XSSFSheet sheet = wb1.getSheetAt(0);
  620. XSSFRow row = sheet.getRow(0);
  621. XSSFCell cellWith = row.getCell(0);
  622. XSSFCell cellWithoutComment = row.getCell(1);
  623. assertNotNull(cellWith.getCellComment());
  624. assertNull(cellWithoutComment.getCellComment());
  625. String exp = "\u0410\u0432\u0442\u043e\u0440:\ncomment";
  626. XSSFComment comment = cellWith.getCellComment();
  627. assertEquals(exp, comment.getString().getString());
  628. // Check we can write it out and read it back as-is
  629. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  630. sheet = wb2.getSheetAt(0);
  631. row = sheet.getRow(0);
  632. cellWith = row.getCell(0);
  633. cellWithoutComment = row.getCell(1);
  634. // Double check things are as expected
  635. assertNotNull(cellWith.getCellComment());
  636. assertNull(cellWithoutComment.getCellComment());
  637. comment = cellWith.getCellComment();
  638. assertEquals(exp, comment.getString().getString());
  639. // Move the comment
  640. cellWithoutComment.setCellComment(comment);
  641. // Write out and re-check
  642. try (XSSFWorkbook wb3 = writeOutAndReadBack(wb2)) {
  643. sheet = wb3.getSheetAt(0);
  644. row = sheet.getRow(0);
  645. // Ensure it swapped over
  646. cellWith = row.getCell(0);
  647. cellWithoutComment = row.getCell(1);
  648. assertNull(cellWith.getCellComment());
  649. assertNotNull(cellWithoutComment.getCellComment());
  650. comment = cellWithoutComment.getCellComment();
  651. assertEquals(exp, comment.getString().getString());
  652. }
  653. }
  654. }
  655. }
  656. /**
  657. * When the cell background colour is set with one of the first
  658. * two columns of the theme colour palette, the colours are
  659. * shades of white or black.
  660. * For those cases, ensure we don't break on reading the colour
  661. */
  662. @Test
  663. void bug50299() throws IOException {
  664. try (Workbook wb = openSampleWorkbook("50299.xlsx")) {
  665. // Check all the colours
  666. for (int sn = 0; sn < wb.getNumberOfSheets(); sn++) {
  667. Sheet s = wb.getSheetAt(sn);
  668. for (Row r : s) {
  669. for (Cell c : r) {
  670. CellStyle cs = c.getCellStyle();
  671. if (cs != null) {
  672. cs.getFillForegroundColor();
  673. }
  674. }
  675. }
  676. }
  677. // Check one bit in detail
  678. // Check that we get back foreground=0 for the theme colours,
  679. // and background=64 for the auto colouring
  680. Sheet s = wb.getSheetAt(0);
  681. assertEquals(0, s.getRow(0).getCell(8).getCellStyle().getFillForegroundColor());
  682. assertEquals(64, s.getRow(0).getCell(8).getCellStyle().getFillBackgroundColor());
  683. assertEquals(0, s.getRow(1).getCell(8).getCellStyle().getFillForegroundColor());
  684. assertEquals(64, s.getRow(1).getCell(8).getCellStyle().getFillBackgroundColor());
  685. }
  686. }
  687. /**
  688. * Excel .xls style indexed colours in a .xlsx file
  689. */
  690. @Test
  691. void bug50786() throws IOException {
  692. try (XSSFWorkbook wb = openSampleWorkbook("50786-indexed_colours.xlsx")) {
  693. XSSFSheet s = wb.getSheetAt(0);
  694. XSSFRow r = s.getRow(2);
  695. // Check we have the right cell
  696. XSSFCell c = r.getCell(1);
  697. assertEquals("test\u00a0", c.getRichStringCellValue().getString());
  698. // It should be light green
  699. XSSFCellStyle cs = c.getCellStyle();
  700. assertEquals(42, cs.getFillForegroundColor());
  701. assertEquals(42, cs.getFillForegroundColorColor().getIndexed());
  702. assertNotNull(cs.getFillForegroundColorColor().getRGB());
  703. assertEquals("FFCCFFCC", cs.getFillForegroundColorColor().getARGBHex());
  704. }
  705. }
  706. /**
  707. * If the border colours are set with themes, then we
  708. * should still be able to get colours
  709. */
  710. @Test
  711. void bug50846() throws IOException {
  712. try (XSSFWorkbook wb = openSampleWorkbook("50846-border_colours.xlsx")) {
  713. XSSFSheet sheet = wb.getSheetAt(0);
  714. XSSFRow row = sheet.getRow(0);
  715. // Border from a theme, brown
  716. XSSFCell cellT = row.getCell(0);
  717. XSSFCellStyle styleT = cellT.getCellStyle();
  718. XSSFColor colorT = styleT.getBottomBorderXSSFColor();
  719. assertEquals(5, colorT.getTheme());
  720. assertEquals("FFC0504D", colorT.getARGBHex());
  721. // Border from a style direct, red
  722. XSSFCell cellS = row.getCell(1);
  723. XSSFCellStyle styleS = cellS.getCellStyle();
  724. XSSFColor colorS = styleS.getBottomBorderXSSFColor();
  725. assertEquals(0, colorS.getTheme());
  726. assertEquals("FFFF0000", colorS.getARGBHex());
  727. }
  728. }
  729. /**
  730. * Fonts where their colours come from the theme rather
  731. * then being set explicitly still should allow the
  732. * fetching of the RGB.
  733. */
  734. @Test
  735. void bug50784() throws IOException {
  736. try (XSSFWorkbook wb = openSampleWorkbook("50784-font_theme_colours.xlsx")) {
  737. XSSFSheet s = wb.getSheetAt(0);
  738. XSSFRow r = s.getRow(0);
  739. // Column 1 has a font with regular colours
  740. XSSFCell cr = r.getCell(1);
  741. XSSFFont fr = wb.getFontAt(cr.getCellStyle().getFontIndex());
  742. XSSFColor colr = fr.getXSSFColor();
  743. // No theme, has colours
  744. assertEquals(0, colr.getTheme());
  745. assertNotNull(colr.getRGB());
  746. // Column 0 has a font with colours from a theme
  747. XSSFCell ct = r.getCell(0);
  748. XSSFFont ft = wb.getFontAt(ct.getCellStyle().getFontIndex());
  749. XSSFColor colt = ft.getXSSFColor();
  750. // Has a theme, which has the colours on it
  751. assertEquals(9, colt.getTheme());
  752. XSSFColor themeC = wb.getTheme().getThemeColor(colt.getTheme());
  753. assertNotNull(themeC.getRGB());
  754. assertNotNull(colt.getRGB());
  755. assertEquals(themeC.getARGBHex(), colt.getARGBHex()); // The same colour
  756. }
  757. }
  758. /**
  759. * New lines were being eaten when setting a font on
  760. * a rich text string
  761. */
  762. @Test
  763. void bug48877() throws IOException {
  764. String text = "Use \n with word wrap on to create a new line.\n" +
  765. "This line finishes with two trailing spaces. ";
  766. try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
  767. XSSFSheet sheet = wb1.createSheet();
  768. Font font1 = wb1.createFont();
  769. font1.setColor((short) 20);
  770. Font font2 = wb1.createFont();
  771. font2.setColor(Font.COLOR_RED);
  772. Font font3 = wb1.getFontAt(0);
  773. XSSFRow row = sheet.createRow(2);
  774. XSSFCell cell = row.createCell(2);
  775. XSSFRichTextString richTextString =
  776. wb1.getCreationHelper().createRichTextString(text);
  777. // Check the text has the newline
  778. assertEquals(text, richTextString.getString());
  779. // Apply the font
  780. richTextString.applyFont(font3);
  781. richTextString.applyFont(0, 3, font1);
  782. cell.setCellValue(richTextString);
  783. // To enable newlines you need set a cell styles with wrap=true
  784. CellStyle cs = wb1.createCellStyle();
  785. cs.setWrapText(true);
  786. cell.setCellStyle(cs);
  787. // Check the text has the
  788. assertEquals(text, cell.getStringCellValue());
  789. // Save the file and re-read it
  790. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  791. sheet = wb2.getSheetAt(0);
  792. row = sheet.getRow(2);
  793. cell = row.getCell(2);
  794. assertEquals(text, cell.getStringCellValue());
  795. // Now add a 2nd, and check again
  796. int fontAt = text.indexOf('\n', 6);
  797. cell.getRichStringCellValue().applyFont(10, fontAt + 1, font2);
  798. assertEquals(text, cell.getStringCellValue());
  799. assertEquals(4, cell.getRichStringCellValue().numFormattingRuns());
  800. assertEquals("Use", cell.getRichStringCellValue().getCTRst().getRArray(0).getT());
  801. String r3 = cell.getRichStringCellValue().getCTRst().getRArray(2).getT();
  802. assertEquals("line.\n", r3.substring(r3.length() - 6));
  803. // Save and re-check
  804. try (XSSFWorkbook wb3 = writeOutAndReadBack(wb2)) {
  805. sheet = wb3.getSheetAt(0);
  806. row = sheet.getRow(2);
  807. cell = row.getCell(2);
  808. assertEquals(text, cell.getStringCellValue());
  809. }
  810. }
  811. }
  812. }
  813. /**
  814. * Adding sheets when one has a table, then re-ordering
  815. */
  816. @Test
  817. void bug50867() throws IOException {
  818. try (XSSFWorkbook wb1 = openSampleWorkbook("50867_with_table.xlsx")) {
  819. assertEquals(3, wb1.getNumberOfSheets());
  820. XSSFSheet s1 = wb1.getSheetAt(0);
  821. XSSFSheet s2 = wb1.getSheetAt(1);
  822. XSSFSheet s3 = wb1.getSheetAt(2);
  823. assertEquals(1, s1.getTables().size());
  824. assertEquals(0, s2.getTables().size());
  825. assertEquals(0, s3.getTables().size());
  826. XSSFTable t = s1.getTables().get(0);
  827. assertEquals("Tabella1", t.getName());
  828. assertEquals("Tabella1", t.getDisplayName());
  829. assertEquals("A1:C3", t.getCTTable().getRef());
  830. // Add a sheet and re-order
  831. XSSFSheet s4 = wb1.createSheet("NewSheet");
  832. wb1.setSheetOrder(s4.getSheetName(), 0);
  833. // Check on tables
  834. assertEquals(1, s1.getTables().size());
  835. assertEquals(0, s2.getTables().size());
  836. assertEquals(0, s3.getTables().size());
  837. assertEquals(0, s4.getTables().size());
  838. // Refetch to get the new order
  839. s1 = wb1.getSheetAt(0);
  840. s2 = wb1.getSheetAt(1);
  841. s3 = wb1.getSheetAt(2);
  842. s4 = wb1.getSheetAt(3);
  843. assertEquals(0, s1.getTables().size());
  844. assertEquals(1, s2.getTables().size());
  845. assertEquals(0, s3.getTables().size());
  846. assertEquals(0, s4.getTables().size());
  847. // Save and re-load
  848. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  849. s1 = wb2.getSheetAt(0);
  850. s2 = wb2.getSheetAt(1);
  851. s3 = wb2.getSheetAt(2);
  852. s4 = wb2.getSheetAt(3);
  853. assertEquals(0, s1.getTables().size());
  854. assertEquals(1, s2.getTables().size());
  855. assertEquals(0, s3.getTables().size());
  856. assertEquals(0, s4.getTables().size());
  857. t = s2.getTables().get(0);
  858. assertEquals("Tabella1", t.getName());
  859. assertEquals("Tabella1", t.getDisplayName());
  860. assertEquals("A1:C3", t.getCTTable().getRef());
  861. // Add some more tables, and check
  862. t = s2.createTable(null);
  863. t.setName("New 2");
  864. t.setDisplayName("New 2");
  865. t = s3.createTable(null);
  866. t.setName("New 3");
  867. t.setDisplayName("New 3");
  868. try (XSSFWorkbook wb3 = writeOutAndReadBack(wb2)) {
  869. s1 = wb3.getSheetAt(0);
  870. s2 = wb3.getSheetAt(1);
  871. s3 = wb3.getSheetAt(2);
  872. s4 = wb3.getSheetAt(3);
  873. assertEquals(0, s1.getTables().size());
  874. assertEquals(2, s2.getTables().size());
  875. assertEquals(1, s3.getTables().size());
  876. assertEquals(0, s4.getTables().size());
  877. t = s2.getTables().get(0);
  878. assertEquals("Tabella1", t.getName());
  879. assertEquals("Tabella1", t.getDisplayName());
  880. assertEquals("A1:C3", t.getCTTable().getRef());
  881. t = s2.getTables().get(1);
  882. assertEquals("New 2", t.getName());
  883. assertEquals("New 2", t.getDisplayName());
  884. t = s3.getTables().get(0);
  885. assertEquals("New 3", t.getName());
  886. assertEquals("New 3", t.getDisplayName());
  887. // Check the relationships
  888. assertEquals(0, s1.getRelations().size());
  889. assertEquals(3, s2.getRelations().size());
  890. assertEquals(1, s3.getRelations().size());
  891. assertEquals(0, s4.getRelations().size());
  892. assertEquals(
  893. XSSFRelation.PRINTER_SETTINGS.getContentType(),
  894. s2.getRelations().get(0).getPackagePart().getContentType()
  895. );
  896. assertEquals(
  897. XSSFRelation.TABLE.getContentType(),
  898. s2.getRelations().get(1).getPackagePart().getContentType()
  899. );
  900. assertEquals(
  901. XSSFRelation.TABLE.getContentType(),
  902. s2.getRelations().get(2).getPackagePart().getContentType()
  903. );
  904. assertEquals(
  905. XSSFRelation.TABLE.getContentType(),
  906. s3.getRelations().get(0).getPackagePart().getContentType()
  907. );
  908. assertEquals(
  909. "/xl/tables/table3.xml",
  910. s3.getRelations().get(0).getPackagePart().getPartName().toString()
  911. );
  912. }
  913. }
  914. }
  915. }
  916. /**
  917. * Setting repeating rows and columns shouldn't break
  918. * any print settings that were there before
  919. */
  920. @Test
  921. void bug49253() throws IOException {
  922. try (XSSFWorkbook wb1 = new XSSFWorkbook();
  923. XSSFWorkbook wb2 = new XSSFWorkbook()) {
  924. CellRangeAddress cra = CellRangeAddress.valueOf("C2:D3");
  925. // No print settings before repeating
  926. XSSFSheet s1 = wb1.createSheet();
  927. assertFalse(s1.getCTWorksheet().isSetPageSetup());
  928. assertTrue(s1.getCTWorksheet().isSetPageMargins());
  929. s1.setRepeatingColumns(cra);
  930. s1.setRepeatingRows(cra);
  931. assertTrue(s1.getCTWorksheet().isSetPageSetup());
  932. assertTrue(s1.getCTWorksheet().isSetPageMargins());
  933. PrintSetup ps1 = s1.getPrintSetup();
  934. assertFalse(ps1.getValidSettings());
  935. assertFalse(ps1.getLandscape());
  936. // Had valid print settings before repeating
  937. XSSFSheet s2 = wb2.createSheet();
  938. PrintSetup ps2 = s2.getPrintSetup();
  939. assertTrue(s2.getCTWorksheet().isSetPageSetup());
  940. assertTrue(s2.getCTWorksheet().isSetPageMargins());
  941. ps2.setLandscape(false);
  942. assertTrue(ps2.getValidSettings());
  943. assertFalse(ps2.getLandscape());
  944. s2.setRepeatingColumns(cra);
  945. s2.setRepeatingRows(cra);
  946. ps2 = s2.getPrintSetup();
  947. assertTrue(s2.getCTWorksheet().isSetPageSetup());
  948. assertTrue(s2.getCTWorksheet().isSetPageMargins());
  949. assertTrue(ps2.getValidSettings());
  950. assertFalse(ps2.getLandscape());
  951. }
  952. }
  953. /**
  954. * Default Column style
  955. */
  956. @Test
  957. void bug51037() throws IOException {
  958. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  959. XSSFSheet s = wb.createSheet();
  960. CellStyle defaultStyle = wb.getCellStyleAt(0);
  961. assertEquals(0, defaultStyle.getIndex());
  962. CellStyle blueStyle = wb.createCellStyle();
  963. blueStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex());
  964. blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  965. assertEquals(1, blueStyle.getIndex());
  966. CellStyle pinkStyle = wb.createCellStyle();
  967. pinkStyle.setFillForegroundColor(IndexedColors.PINK.getIndex());
  968. pinkStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  969. assertEquals(2, pinkStyle.getIndex());
  970. // Starts empty
  971. assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
  972. CTCols cols = s.getCTWorksheet().getColsArray(0);
  973. assertEquals(0, cols.sizeOfColArray());
  974. // Add some rows and columns
  975. XSSFRow r1 = s.createRow(0);
  976. XSSFRow r2 = s.createRow(1);
  977. r1.createCell(0);
  978. r1.createCell(2);
  979. r2.createCell(0);
  980. r2.createCell(3);
  981. // Check no style is there
  982. assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
  983. assertEquals(0, cols.sizeOfColArray());
  984. assertEquals(defaultStyle, s.getColumnStyle(0));
  985. assertEquals(defaultStyle, s.getColumnStyle(2));
  986. assertEquals(defaultStyle, s.getColumnStyle(3));
  987. // Apply the styles
  988. s.setDefaultColumnStyle(0, pinkStyle);
  989. s.setDefaultColumnStyle(3, blueStyle);
  990. // Check
  991. assertEquals(pinkStyle, s.getColumnStyle(0));
  992. assertEquals(defaultStyle, s.getColumnStyle(2));
  993. assertEquals(blueStyle, s.getColumnStyle(3));
  994. assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
  995. assertEquals(2, cols.sizeOfColArray());
  996. assertEquals(1, cols.getColArray(0).getMin());
  997. assertEquals(1, cols.getColArray(0).getMax());
  998. assertEquals(pinkStyle.getIndex(), cols.getColArray(0).getStyle());
  999. assertEquals(4, cols.getColArray(1).getMin());
  1000. assertEquals(4, cols.getColArray(1).getMax());
  1001. assertEquals(blueStyle.getIndex(), cols.getColArray(1).getStyle());
  1002. // Save, re-load and re-check
  1003. try (XSSFWorkbook wbBack = writeOutAndReadBack(wb)) {
  1004. s = wbBack.getSheetAt(0);
  1005. defaultStyle = wbBack.getCellStyleAt(defaultStyle.getIndex());
  1006. blueStyle = wbBack.getCellStyleAt(blueStyle.getIndex());
  1007. pinkStyle = wbBack.getCellStyleAt(pinkStyle.getIndex());
  1008. assertEquals(pinkStyle, s.getColumnStyle(0));
  1009. assertEquals(defaultStyle, s.getColumnStyle(2));
  1010. assertEquals(blueStyle, s.getColumnStyle(3));
  1011. }
  1012. }
  1013. }
  1014. /**
  1015. * Repeatedly writing a file.
  1016. * Something with the SharedStringsTable currently breaks...
  1017. */
  1018. @Test
  1019. void bug46662() throws IOException {
  1020. for (int i=0; i<2; i++) {
  1021. try (XSSFWorkbook wb1 = (i == 0) ? new XSSFWorkbook() : openSampleWorkbook("sample.xlsx")) {
  1022. for (int j=0; j<3; j++) {
  1023. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  1024. assertEquals(wb1.getNumberOfSheets(), wb2.getNumberOfSheets());
  1025. }
  1026. }
  1027. }
  1028. }
  1029. // TODO: Complex file
  1030. }
  1031. /**
  1032. * Colours and styles when the list has gaps in it
  1033. */
  1034. @Test
  1035. void bug51222() throws IOException {
  1036. try (XSSFWorkbook wb = openSampleWorkbook("51222.xlsx")) {
  1037. XSSFSheet s = wb.getSheetAt(0);
  1038. XSSFCell cA4_EEECE1 = s.getRow(3).getCell(0);
  1039. XSSFCell cA5_1F497D = s.getRow(4).getCell(0);
  1040. // Check the text
  1041. assertEquals("A4", cA4_EEECE1.getRichStringCellValue().getString());
  1042. assertEquals("A5", cA5_1F497D.getRichStringCellValue().getString());
  1043. // Check the styles assigned to them
  1044. assertEquals(4, cA4_EEECE1.getCTCell().getS());
  1045. assertEquals(5, cA5_1F497D.getCTCell().getS());
  1046. // Check we look up the correct style
  1047. assertEquals(4, cA4_EEECE1.getCellStyle().getIndex());
  1048. assertEquals(5, cA5_1F497D.getCellStyle().getIndex());
  1049. // Check the fills on them at the low level
  1050. assertEquals(5, cA4_EEECE1.getCellStyle().getCoreXf().getFillId());
  1051. assertEquals(6, cA5_1F497D.getCellStyle().getCoreXf().getFillId());
  1052. // These should reference themes 2 and 3
  1053. assertEquals(2, wb.getStylesSource().getFillAt(5).getCTFill().getPatternFill().getFgColor().getTheme());
  1054. assertEquals(3, wb.getStylesSource().getFillAt(6).getCTFill().getPatternFill().getFgColor().getTheme());
  1055. // Ensure we get the right colours for these themes
  1056. // TODO fix
  1057. // assertEquals("FFEEECE1", wb.getTheme().getThemeColor(2).getARGBHex());
  1058. // assertEquals("FF1F497D", wb.getTheme().getThemeColor(3).getARGBHex());
  1059. // Finally check the colours on the styles
  1060. // TODO fix
  1061. // assertEquals("FFEEECE1", cA4_EEECE1.getCellStyle().getFillForegroundXSSFColor().getARGBHex());
  1062. // assertEquals("FF1F497D", cA5_1F497D.getCellStyle().getFillForegroundXSSFColor().getARGBHex());
  1063. }
  1064. }
  1065. @Test
  1066. void bug51470() throws IOException {
  1067. try (XSSFWorkbook wb = openSampleWorkbook("51470.xlsx")) {
  1068. XSSFSheet sh0 = wb.getSheetAt(0);
  1069. XSSFSheet sh1 = wb.cloneSheet(0);
  1070. List<RelationPart> rels0 = sh0.getRelationParts();
  1071. List<RelationPart> rels1 = sh1.getRelationParts();
  1072. assertEquals(1, rels0.size());
  1073. assertEquals(1, rels1.size());
  1074. PackageRelationship pr0 = rels0.get(0).getRelationship();
  1075. PackageRelationship pr1 = rels1.get(0).getRelationship();
  1076. assertEquals(pr0.getTargetMode(), pr1.getTargetMode());
  1077. assertEquals(pr0.getTargetURI(), pr1.getTargetURI());
  1078. POIXMLDocumentPart doc0 = rels0.get(0).getDocumentPart();
  1079. POIXMLDocumentPart doc1 = rels1.get(0).getDocumentPart();
  1080. assertEquals(doc0, doc1);
  1081. }
  1082. }
  1083. /**
  1084. * Add comments to Sheet 1, when Sheet 2 already has
  1085. * comments (so /xl/comments1.xml is taken)
  1086. */
  1087. @Test
  1088. void bug51850() throws IOException {
  1089. try (XSSFWorkbook wb1 = openSampleWorkbook("51850.xlsx")) {
  1090. XSSFSheet sh1 = wb1.getSheetAt(0);
  1091. XSSFSheet sh2 = wb1.getSheetAt(1);
  1092. // Sheet 2 has comments
  1093. assertNotNull(sh2.getCommentsTable(false));
  1094. assertEquals(1, sh2.getCommentsTable(false).getNumberOfComments());
  1095. // Sheet 1 doesn't (yet)
  1096. assertNull(sh1.getCommentsTable(false));
  1097. // Try to add comments to Sheet 1
  1098. CreationHelper factory = wb1.getCreationHelper();
  1099. Drawing<?> drawing = sh1.createDrawingPatriarch();
  1100. ClientAnchor anchor = factory.createClientAnchor();
  1101. anchor.setCol1(0);
  1102. anchor.setCol2(4);
  1103. anchor.setRow1(0);
  1104. anchor.setRow2(1);
  1105. Comment comment1 = drawing.createCellComment(anchor);
  1106. comment1.setString(
  1107. factory.createRichTextString("I like this cell. It's my favourite."));
  1108. comment1.setAuthor("Bob T. Fish");
  1109. anchor = factory.createClientAnchor();
  1110. anchor.setCol1(0);
  1111. anchor.setCol2(4);
  1112. anchor.setRow1(1);
  1113. anchor.setRow2(1);
  1114. Comment comment2 = drawing.createCellComment(anchor);
  1115. comment2.setString(
  1116. factory.createRichTextString("This is much less fun..."));
  1117. comment2.setAuthor("Bob T. Fish");
  1118. Cell c1 = sh1.getRow(0).createCell(4);
  1119. c1.setCellValue(2.3);
  1120. c1.setCellComment(comment1);
  1121. Cell c2 = sh1.getRow(0).createCell(5);
  1122. c2.setCellValue(2.1);
  1123. c2.setCellComment(comment2);
  1124. // Save and re-load
  1125. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  1126. sh1 = wb2.getSheetAt(0);
  1127. sh2 = wb2.getSheetAt(1);
  1128. // Check the comments
  1129. assertNotNull(sh2.getCommentsTable(false));
  1130. assertEquals(1, sh2.getCommentsTable(false).getNumberOfComments());
  1131. assertNotNull(sh1.getCommentsTable(false));
  1132. assertEquals(2, sh1.getCommentsTable(false).getNumberOfComments());
  1133. }
  1134. }
  1135. }
  1136. /**
  1137. * Sheet names with a , in them
  1138. */
  1139. @Test
  1140. void bug51963() throws IOException {
  1141. try (XSSFWorkbook wb = openSampleWorkbook("51963.xlsx")) {
  1142. Sheet sheet = wb.getSheetAt(0);
  1143. assertEquals("Abc,1", sheet.getSheetName());
  1144. Name name = wb.getName("Intekon.ProdCodes");
  1145. assertEquals("'Abc,1'!$A$1:$A$2", name.getRefersToFormula());
  1146. AreaReference ref = wb.getCreationHelper().createAreaReference(name.getRefersToFormula());
  1147. assertEquals(0, ref.getFirstCell().getRow());
  1148. assertEquals(0, ref.getFirstCell().getCol());
  1149. assertEquals(1, ref.getLastCell().getRow());
  1150. assertEquals(0, ref.getLastCell().getCol());
  1151. }
  1152. }
  1153. /**
  1154. * Sum across multiple workbooks
  1155. * eg =SUM($Sheet1.C1:$Sheet4.C1)
  1156. */
  1157. @Test
  1158. void bug48703() throws IOException {
  1159. try (XSSFWorkbook wb = openSampleWorkbook("48703.xlsx")) {
  1160. XSSFSheet sheet = wb.getSheetAt(0);
  1161. // Contains two forms, one with a range and one a list
  1162. XSSFRow r1 = sheet.getRow(0);
  1163. XSSFRow r2 = sheet.getRow(1);
  1164. XSSFCell c1 = r1.getCell(1);
  1165. XSSFCell c2 = r2.getCell(1);
  1166. assertEquals(20.0, c1.getNumericCellValue(), 0);
  1167. assertEquals("SUM(Sheet1!C1,Sheet2!C1,Sheet3!C1,Sheet4!C1)", c1.getCellFormula());
  1168. assertEquals(20.0, c2.getNumericCellValue(), 0);
  1169. assertEquals("SUM(Sheet1:Sheet4!C1)", c2.getCellFormula());
  1170. // Try evaluating both
  1171. XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
  1172. eval.evaluateFormulaCell(c1);
  1173. eval.evaluateFormulaCell(c2);
  1174. assertEquals(20.0, c1.getNumericCellValue(), 0);
  1175. assertEquals(20.0, c2.getNumericCellValue(), 0);
  1176. }
  1177. }
  1178. /**
  1179. * Bugzilla 51710: problems reading shared formuals from .xlsx
  1180. */
  1181. @Test
  1182. void bug51710() throws IOException {
  1183. try (Workbook wb = openSampleWorkbook("51710.xlsx")) {
  1184. final String[] columns = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N"};
  1185. final int rowMax = 500; // bug triggers on row index 59
  1186. Sheet sheet = wb.getSheetAt(0);
  1187. // go through all formula cells
  1188. for (int rInd = 2; rInd <= rowMax; rInd++) {
  1189. Row row = sheet.getRow(rInd);
  1190. for (int cInd = 1; cInd <= 12; cInd++) {
  1191. Cell cell = row.getCell(cInd);
  1192. String formula = cell.getCellFormula();
  1193. CellReference ref = new CellReference(cell);
  1194. //simulate correct answer
  1195. String correct = "$A" + (rInd + 1) + "*" + columns[cInd] + "$2";
  1196. assertEquals(correct, formula, "Incorrect formula in " + ref.formatAsString());
  1197. }
  1198. }
  1199. }
  1200. }
  1201. /**
  1202. * Bug 53101:
  1203. */
  1204. @Test
  1205. void bug5301() throws IOException {
  1206. try (Workbook wb = openSampleWorkbook("53101.xlsx")) {
  1207. FormulaEvaluator evaluator =
  1208. wb.getCreationHelper().createFormulaEvaluator();
  1209. // A1: SUM(B1: IZ1)
  1210. double a1Value =
  1211. evaluator.evaluate(wb.getSheetAt(0).getRow(0).getCell(0)).getNumberValue();
  1212. // Assert
  1213. assertEquals(259.0, a1Value, 0.0);
  1214. // KY: SUM(B1: IZ1)
  1215. /*double ky1Value =*/
  1216. assertEquals(259.0, evaluator.evaluate(wb.getSheetAt(0).getRow(0).getCell(310)).getNumberValue(), 0.0001);
  1217. // Assert
  1218. assertEquals(259.0, a1Value, 0.0);
  1219. }
  1220. }
  1221. @Test
  1222. void bug54436() throws IOException {
  1223. try (Workbook wb = openSampleWorkbook("54436.xlsx")) {
  1224. if (!WorkbookEvaluator.getSupportedFunctionNames().contains("GETPIVOTDATA")) {
  1225. Function func = (args, srcRowIndex, srcColumnIndex) -> ErrorEval.NA;
  1226. WorkbookEvaluator.registerFunction("GETPIVOTDATA", func);
  1227. }
  1228. FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
  1229. assertDoesNotThrow(fe::evaluateAll);
  1230. }
  1231. }
  1232. /**
  1233. * Password Protected .xlsx files are now (as of 4.0.0) tested for the default password
  1234. * when opened via WorkbookFactory, so there's no EncryptedDocumentException thrown anymore
  1235. */
  1236. @Test
  1237. void bug55692_poifs() throws IOException {
  1238. // Via a POIFSFileSystem
  1239. try (POIFSFileSystem fsP = new POIFSFileSystem(
  1240. POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
  1241. Workbook wb = WorkbookFactory.create(fsP)) {
  1242. assertNotNull(wb);
  1243. assertEquals(3, wb.getNumberOfSheets());
  1244. }
  1245. }
  1246. @Test
  1247. void bug55692_stream() throws IOException {
  1248. // Directly on a Stream, will go via POIFS and spot it's
  1249. // actually a .xlsx file encrypted with the default password, and open
  1250. try (Workbook wb = WorkbookFactory.create(
  1251. POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"))) {
  1252. assertNotNull(wb);
  1253. assertEquals(3, wb.getNumberOfSheets());
  1254. }
  1255. }
  1256. @Test
  1257. void bug55692_poifs2() throws IOException {
  1258. // Via a POIFSFileSystem, will spot it's actually a .xlsx file
  1259. // encrypted with the default password, and open
  1260. try (POIFSFileSystem fsNP = new POIFSFileSystem(
  1261. POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"))) {
  1262. Workbook wb = WorkbookFactory.create(fsNP);
  1263. assertNotNull(wb);
  1264. assertEquals(3, wb.getNumberOfSheets());
  1265. wb.close();
  1266. }
  1267. }
  1268. @Test
  1269. void bug53282() throws IOException {
  1270. try (Workbook wb = openSampleWorkbook("53282b.xlsx")) {
  1271. Cell c = wb.getSheetAt(0).getRow(1).getCell(0);
  1272. assertEquals("#@_#", c.getStringCellValue());
  1273. assertEquals("http://invalid.uri", c.getHyperlink().getAddress());
  1274. }
  1275. }
  1276. /**
  1277. * Was giving NullPointerException
  1278. * at org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead
  1279. * due to a lack of Styles Table
  1280. */
  1281. @Test
  1282. void bug56278() throws IOException {
  1283. try (Workbook wb = openSampleWorkbook("56278.xlsx")) {
  1284. assertEquals(0, wb.getSheetIndex("Market Rates"));
  1285. // Save and re-check
  1286. Workbook nwb = writeOutAndReadBack(wb);
  1287. assertEquals(0, nwb.getSheetIndex("Market Rates"));
  1288. nwb.close();
  1289. }
  1290. }
  1291. @Test
  1292. void bug56315() throws IOException {
  1293. try (XSSFWorkbook wb = openSampleWorkbook("56315.xlsx")) {
  1294. Cell c = wb.getSheetAt(0).getRow(1).getCell(0);
  1295. CellValue cv = wb.getCreationHelper().createFormulaEvaluator().evaluate(c);
  1296. double rounded = cv.getNumberValue();
  1297. assertEquals(0.1, rounded, 0.0);
  1298. }
  1299. }
  1300. @Test
  1301. void bug56468() throws IOException, InterruptedException {
  1302. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  1303. XSSFSheet sheet = wb.createSheet();
  1304. XSSFRow row = sheet.createRow(0);
  1305. XSSFCell cell = row.createCell(0);
  1306. cell.setCellValue("Hi");
  1307. sheet.setRepeatingRows(new CellRangeAddress(0, 0, 0, 0));
  1308. // small hack to try to make this test stable, previously it failed whenever the two written ZIP files had
  1309. // different file-creation dates stored. We try to do a loop until the current second changes in order to
  1310. // avoid problems with some date information that is written to the ZIP and thus causes differences
  1311. long start = System.currentTimeMillis() / 1000;
  1312. while (System.currentTimeMillis() / 1000 == start) {
  1313. Thread.sleep(10);
  1314. }
  1315. UnsynchronizedByteArrayOutputStream bos = UnsynchronizedByteArrayOutputStream.builder().setBufferSize(8096).get();
  1316. wb.write(bos);
  1317. byte[] firstSave = bos.toByteArray();
  1318. bos.reset();
  1319. wb.write(bos);
  1320. byte[] secondSave = bos.toByteArray();
  1321. assertArrayEquals(firstSave, secondSave,
  1322. "Had: \n" + Arrays.toString(firstSave) + " and \n" + Arrays.toString(secondSave));
  1323. }
  1324. }
  1325. /**
  1326. * ISO-8601 style cell formats with a T in them, eg
  1327. * cell format of "yyyy-MM-ddTHH:mm:ss"
  1328. */
  1329. @Test
  1330. void bug54034() throws IOException {
  1331. TimeZone tz = LocaleUtil.getUserTimeZone();
  1332. LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET"));
  1333. try (Workbook wb = openSampleWorkbook("54034.xlsx")) {
  1334. Sheet sheet = wb.getSheet("Sheet1");
  1335. Row row = sheet.getRow(1);
  1336. Cell cell = row.getCell(2);
  1337. assertTrue(DateUtil.isCellDateFormatted(cell));
  1338. DataFormatter fmt = new DataFormatter();
  1339. assertEquals("yyyy\\-mm\\-dd\\Thh:mm", cell.getCellStyle().getDataFormatString());
  1340. assertEquals("2012-08-08T22:59", fmt.formatCellValue(cell));
  1341. } finally {
  1342. LocaleUtil.setUserTimeZone(tz);
  1343. }
  1344. }
  1345. @Test
  1346. void testBug53798XLSX() throws IOException {
  1347. try (XSSFWorkbook wb = openSampleWorkbook("53798_shiftNegative_TMPL.xlsx")) {
  1348. File xlsOutput = TempFile.createTempFile("testBug53798", ".xlsx");
  1349. bug53798Work(wb, xlsOutput);
  1350. }
  1351. }
  1352. @Disabled("Shifting rows is not yet implemented in SXSSFSheet")
  1353. @Test
  1354. void testBug53798XLSXStream() throws IOException {
  1355. try (XSSFWorkbook wb = openSampleWorkbook("53798_shiftNegative_TMPL.xlsx")) {
  1356. File xlsOutput = TempFile.createTempFile("testBug53798", ".xlsx");
  1357. SXSSFWorkbook wb2 = new SXSSFWorkbook(wb);
  1358. bug53798Work(wb2, xlsOutput);
  1359. wb2.close();
  1360. }
  1361. }
  1362. @Test
  1363. void testBug53798XLS() throws IOException {
  1364. try (Workbook wb = HSSFTestDataSamples.openSampleWorkbook("53798_shiftNegative_TMPL.xls")) {
  1365. File xlsOutput = TempFile.createTempFile("testBug53798", ".xls");
  1366. bug53798Work(wb, xlsOutput);
  1367. }
  1368. }
  1369. /**
  1370. * SUMIF was throwing a NPE on some formulas
  1371. */
  1372. @Test
  1373. void testBug56420SumIfNPE() throws IOException {
  1374. try (XSSFWorkbook wb = openSampleWorkbook("56420.xlsx")) {
  1375. FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  1376. Sheet sheet = wb.getSheetAt(0);
  1377. Row r = sheet.getRow(2);
  1378. Cell c = r.getCell(2);
  1379. assertEquals("SUMIF($A$1:$A$4,A3,$B$1:$B$4)", c.getCellFormula());
  1380. Cell eval = evaluator.evaluateInCell(c);
  1381. assertEquals(0.0, eval.getNumericCellValue(), 0.0001);
  1382. }
  1383. }
  1384. private void bug53798Work(Workbook wb, File xlsOutput) throws IOException {
  1385. Sheet testSheet = wb.getSheetAt(0);
  1386. testSheet.shiftRows(2, 2, 1);
  1387. saveAndReloadReport(wb, xlsOutput);
  1388. // 1) corrupted xlsx (unreadable data in the first row of a shifted group) already comes about
  1389. // when shifted by less than -1 negative amount (try -2)
  1390. testSheet.shiftRows(3, 3, -1);
  1391. saveAndReloadReport(wb, xlsOutput);
  1392. testSheet.shiftRows(2, 2, 1);
  1393. saveAndReloadReport(wb, xlsOutput);
  1394. // 2) attempt to create a new row IN PLACE of a removed row by a negative shift causes corrupted
  1395. // xlsx file with unreadable data in the negative shifted row.
  1396. // NOTE it's ok to create any other row.
  1397. Row newRow = testSheet.createRow(3);
  1398. saveAndReloadReport(wb, xlsOutput);
  1399. Cell newCell = newRow.createCell(0);
  1400. saveAndReloadReport(wb, xlsOutput);
  1401. newCell.setCellValue("new Cell in row " + newRow.getRowNum());
  1402. saveAndReloadReport(wb, xlsOutput);
  1403. // 3) once a negative shift has been made any attempt to shift another group of rows
  1404. // (note: outside of previously negative shifted rows) by a POSITIVE amount causes POI exception:
  1405. // org.apache.xmlbeans.impl.values.XmlValueDisconnectedException.
  1406. // NOTE: another negative shift on another group of rows is successful, provided no new rows in
  1407. // place of previously shifted rows were attempted to be created as explained above.
  1408. testSheet.shiftRows(6, 7, 1); // -- CHANGE the shift to positive once the behaviour of
  1409. // the above has been tested
  1410. saveAndReloadReport(wb, xlsOutput);
  1411. }
  1412. /**
  1413. * XSSFCell.typeMismatch on certain blank cells when formatting
  1414. * with DataFormatter
  1415. */
  1416. @Test
  1417. void bug56702() throws IOException {
  1418. try (XSSFWorkbook wb = openSampleWorkbook("56702.xlsx")) {
  1419. Sheet sheet = wb.getSheetAt(0);
  1420. // Get wrong cell by row 8 & column 7
  1421. Cell cell = sheet.getRow(8).getCell(7);
  1422. assertEquals(CellType.NUMERIC, cell.getCellType());
  1423. // Check the value - will be zero as it is <c><v/></c>
  1424. assertEquals(0.0, cell.getNumericCellValue(), 0.001);
  1425. // Try to format
  1426. DataFormatter formatter = new DataFormatter();
  1427. formatter.formatCellValue(cell);
  1428. // Check the formatting
  1429. assertEquals("0", formatter.formatCellValue(cell));
  1430. }
  1431. }
  1432. /**
  1433. * Formulas which reference named ranges, either in other
  1434. * sheets, or workbook scoped but in other workbooks.
  1435. * Used to fail with with errors like
  1436. * org.apache.poi.ss.formula.FormulaParseException: Cell reference expected after sheet name at index 9
  1437. * org.apache.poi.ss.formula.FormulaParseException: Parse error near char 0 '[' in specified formula '[0]!NR_Global_B2'. Expected number, string, or defined name
  1438. */
  1439. @Test
  1440. void bug56737() throws IOException {
  1441. try (Workbook wb = openSampleWorkbook("56737.xlsx")) {
  1442. // Check the named range definitions
  1443. Name nSheetScope = wb.getName("NR_To_A1");
  1444. Name nWBScope = wb.getName("NR_Global_B2");
  1445. assertNotNull(nSheetScope);
  1446. assertNotNull(nWBScope);
  1447. assertEquals("Defines!$A$1", nSheetScope.getRefersToFormula());
  1448. assertEquals("Defines!$B$2", nWBScope.getRefersToFormula());
  1449. // Check the different kinds of formulas
  1450. Sheet s = wb.getSheetAt(0);
  1451. Cell cRefSName = s.getRow(1).getCell(3);
  1452. Cell cRefWName = s.getRow(2).getCell(3);
  1453. assertEquals("Defines!NR_To_A1", cRefSName.getCellFormula());
  1454. // Note the formula, as stored in the file, has the external name index not filename
  1455. // TODO Provide a way to get the one with the filename
  1456. assertEquals("[0]!NR_Global_B2", cRefWName.getCellFormula());
  1457. // Try to evaluate them
  1458. FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
  1459. assertEquals("Test A1", eval.evaluate(cRefSName).getStringValue());
  1460. assertEquals(142, (int) eval.evaluate(cRefWName).getNumberValue());
  1461. // Try to evaluate everything
  1462. eval.evaluateAll();
  1463. }
  1464. }
  1465. private void saveAndReloadReport(Workbook wb, File outFile) throws IOException {
  1466. // run some method on the font to verify if it is "disconnected" already
  1467. //for(short i = 0;i < 256;i++)
  1468. {
  1469. Font font = wb.getFontAt(0);
  1470. if (font instanceof XSSFFont) {
  1471. XSSFFont xfont = (XSSFFont) wb.getFontAt(0);
  1472. CTFontImpl ctFont = (CTFontImpl) xfont.getCTFont();
  1473. assertEquals(0, ctFont.sizeOfBArray());
  1474. }
  1475. }
  1476. try (FileOutputStream fileOutStream = new FileOutputStream(outFile)) {
  1477. wb.write(fileOutStream);
  1478. }
  1479. try (FileInputStream is = new FileInputStream(outFile)) {
  1480. Workbook newWB = null;
  1481. try {
  1482. if (wb instanceof XSSFWorkbook) {
  1483. newWB = new XSSFWorkbook(is);
  1484. } else if (wb instanceof HSSFWorkbook) {
  1485. newWB = new HSSFWorkbook(is);
  1486. } else if (wb instanceof SXSSFWorkbook) {
  1487. newWB = new SXSSFWorkbook(new XSSFWorkbook(is));
  1488. } else {
  1489. throw new IllegalStateException("Unknown workbook: " + wb);
  1490. }
  1491. assertNotNull(newWB.getSheet("test"));
  1492. } finally {
  1493. if (newWB != null) {
  1494. newWB.close();
  1495. }
  1496. }
  1497. }
  1498. }
  1499. @ParameterizedTest
  1500. @CsvSource({
  1501. /* Not 0.0 because POI sees date "0" minus one month as invalid date, which is -1! */
  1502. "56688_1.xlsx, -1.0",
  1503. "56688_2.xlsx, #VALUE!",
  1504. "56688_3.xlsx, #VALUE!",
  1505. "56688_4.xlsx, date"
  1506. })
  1507. void testBug56688(String fileName, String expect) throws IOException {
  1508. if ("date".equals(expect)) {
  1509. Calendar calendar = LocaleUtil.getLocaleCalendar();
  1510. calendar.add(Calendar.MONTH, 2);
  1511. double excelDate = DateUtil.getExcelDate(calendar.getTime());
  1512. NumberEval eval = new NumberEval(Math.floor(excelDate));
  1513. expect = eval.getStringValue() + ".0";
  1514. }
  1515. try (XSSFWorkbook excel = openSampleWorkbook(fileName)) {
  1516. XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(excel);
  1517. evaluator.evaluateAll();
  1518. XSSFCell cell = excel.getSheetAt(0).getRow(1).getCell(1);
  1519. CellValue value = evaluator.evaluate(cell);
  1520. assertEquals(expect, value.formatAsString());
  1521. }
  1522. }
  1523. /**
  1524. * New hyperlink with no initial cell reference, still need
  1525. * to be able to change it
  1526. */
  1527. @Test
  1528. void testBug56527() throws IOException {
  1529. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  1530. XSSFSheet sheet = wb.createSheet();
  1531. XSSFCreationHelper creationHelper = wb.getCreationHelper();
  1532. // Try with a cell reference
  1533. XSSFHyperlink hyperlink1 = creationHelper.createHyperlink(HyperlinkType.URL);
  1534. sheet.addHyperlink(hyperlink1);
  1535. hyperlink1.setAddress("http://myurl");
  1536. hyperlink1.setCellReference("B4");
  1537. assertEquals(3, hyperlink1.getFirstRow());
  1538. assertEquals(1, hyperlink1.getFirstColumn());
  1539. assertEquals(3, hyperlink1.getLastRow());
  1540. assertEquals(1, hyperlink1.getLastColumn());
  1541. // Try with explicit rows / columns
  1542. XSSFHyperlink hyperlink2 = creationHelper.createHyperlink(HyperlinkType.URL);
  1543. sheet.addHyperlink(hyperlink2);
  1544. hyperlink2.setAddress("http://myurl");
  1545. hyperlink2.setFirstRow(5);
  1546. hyperlink2.setFirstColumn(3);
  1547. assertEquals(5, hyperlink2.getFirstRow());
  1548. assertEquals(3, hyperlink2.getFirstColumn());
  1549. assertEquals(5, hyperlink2.getLastRow());
  1550. assertEquals(3, hyperlink2.getLastColumn());
  1551. assertTrue(sheet.getHyperlinkList().contains(hyperlink1), "sheet contains hyperlink1");
  1552. assertTrue(sheet.getHyperlinkList().contains(hyperlink2), "sheet contains hyperlink2");
  1553. sheet.removeHyperlink(hyperlink1);
  1554. assertFalse(sheet.getHyperlinkList().contains(hyperlink1), "sheet no longer contains hyperlink1");
  1555. assertTrue(sheet.getHyperlinkList().contains(hyperlink2), "sheet still contains hyperlink2");
  1556. }
  1557. }
  1558. /**
  1559. * Shifting rows with a formula that references a
  1560. * function in another file
  1561. */
  1562. @Test
  1563. void bug56502() throws IOException {
  1564. try (Workbook wb = openSampleWorkbook("56502.xlsx")) {
  1565. Sheet sheet = wb.getSheetAt(0);
  1566. Cell cFunc = sheet.getRow(3).getCell(0);
  1567. assertEquals("[1]!LUCANET(\"Ist\")", cFunc.getCellFormula());
  1568. Cell cRef = sheet.getRow(3).createCell(1);
  1569. cRef.setCellFormula("A3");
  1570. // Shift it down one row
  1571. sheet.shiftRows(1, sheet.getLastRowNum(), 1);
  1572. // Check the new formulas: Function won't change, Reference will
  1573. cFunc = sheet.getRow(4).getCell(0);
  1574. assertEquals("[1]!LUCANET(\"Ist\")", cFunc.getCellFormula());
  1575. cRef = sheet.getRow(4).getCell(1);
  1576. assertEquals("A4", cRef.getCellFormula());
  1577. }
  1578. }
  1579. @Test
  1580. void bug54764() throws IOException, OpenXML4JException, XmlException {
  1581. try (OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("54764.xlsx")) {
  1582. // Check the core properties - will be found but empty, due
  1583. // to the expansion being too much to be considered valid
  1584. POIXMLProperties props = new POIXMLProperties(pkg);
  1585. assertNull(props.getCoreProperties().getTitle());
  1586. assertNull(props.getCoreProperties().getSubject());
  1587. assertNull(props.getCoreProperties().getDescription());
  1588. // Now check the spreadsheet itself
  1589. assertThrows(POIXMLException.class, () -> new XSSFWorkbook(pkg), "Should fail as too much expansion occurs");
  1590. }
  1591. // Try with one with the entities in the Content Types
  1592. assertThrows(Exception.class, () -> XSSFTestDataSamples.openSamplePackage("54764-2.xlsx"),
  1593. "Should fail as too much expansion occurs");
  1594. // Check we can still parse valid files after all that
  1595. try (Workbook wb = openSampleWorkbook("sample.xlsx")) {
  1596. assertEquals(3, wb.getNumberOfSheets());
  1597. }
  1598. }
  1599. @Test
  1600. void test54764WithSAXHelper() throws Exception {
  1601. File testFile = XSSFTestDataSamples.getSampleFile("54764.xlsx");
  1602. try (ZipFile zip = new ZipFile(testFile)) {
  1603. ZipArchiveEntry ze = zip.getEntry("xl/sharedStrings.xml");
  1604. XMLReader reader = XMLHelper.newXMLReader();
  1605. SAXParseException e = assertThrows(SAXParseException.class,
  1606. () -> reader.parse(new InputSource(zip.getInputStream(ze))));
  1607. assertNotNull(e.getMessage());
  1608. assertNotEquals(isOldXercesActive(), e.getMessage().contains("DOCTYPE is disallowed when the feature"));
  1609. }
  1610. }
  1611. @Test
  1612. void test54764WithDocumentHelper() throws Exception {
  1613. File testFile = XSSFTestDataSamples.getSampleFile("54764.xlsx");
  1614. try (ZipFile zip = new ZipFile(testFile)) {
  1615. ZipArchiveEntry ze = zip.getEntry("xl/sharedStrings.xml");
  1616. SAXParseException e = assertThrows(SAXParseException.class,
  1617. () -> DocumentHelper.readDocument(zip.getInputStream(ze)));
  1618. assertNotNull(e.getMessage());
  1619. assertNotEquals(isOldXercesActive(), e.getMessage().contains("DOCTYPE is disallowed when the feature"));
  1620. }
  1621. }
  1622. /**
  1623. * CTDefinedNamesImpl should be included in the smaller
  1624. * poi-ooxml-lite jar
  1625. */
  1626. @Test
  1627. void bug57176() throws IOException {
  1628. try (XSSFWorkbook wb = openSampleWorkbook("57176.xlsx")) {
  1629. CTDefinedNames definedNames = wb.getCTWorkbook().getDefinedNames();
  1630. List<CTDefinedName> definedNameList = definedNames.getDefinedNameList();
  1631. for (CTDefinedName defName : definedNameList) {
  1632. assertNotNull(defName.getName());
  1633. assertNotNull(defName.getStringValue());
  1634. }
  1635. assertEquals("TestDefinedName", definedNameList.get(0).getName());
  1636. }
  1637. }
  1638. /**
  1639. * .xlsb files are not supported, but we should generate a helpful
  1640. * error message if given one
  1641. */
  1642. @Test
  1643. void bug56800_xlsb() throws IOException {
  1644. // Can be opened at the OPC level
  1645. try (OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("Simple.xlsb")) {
  1646. // XSSF Workbook gives helpful error
  1647. assertThrows(XLSBUnsupportedException.class, () -> new XSSFWorkbook(pkg), ".xlsb files not supported");
  1648. // Workbook Factory gives helpful error on package
  1649. assertThrows(XLSBUnsupportedException.class, () -> XSSFWorkbookFactory.createWorkbook(pkg), ".xlsb files not supported");
  1650. }
  1651. // Workbook Factory gives helpful error on file
  1652. File xlsbFile = HSSFTestDataSamples.getSampleFile("Simple.xlsb");
  1653. assertThrows(XLSBUnsupportedException.class, () -> WorkbookFactory.create(xlsbFile), ".xlsb files not supported");
  1654. }
  1655. @Test
  1656. void testBug57196() throws IOException {
  1657. try (Workbook wb = openSampleWorkbook("57196.xlsx")) {
  1658. Sheet sheet = wb.getSheet("Feuil1");
  1659. Row mod = sheet.getRow(1);
  1660. mod.getCell(1).setCellValue(3);
  1661. mod = sheet.getRow(2);
  1662. mod.createCell(0).setCellValue(10);
  1663. XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
  1664. assertEquals(256, mod.getCell(2).getNumericCellValue());
  1665. }
  1666. }
  1667. @Test
  1668. void test57196_Detail() throws IOException {
  1669. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  1670. XSSFSheet sheet = wb.createSheet("Sheet1");
  1671. XSSFRow row = sheet.createRow(0);
  1672. XSSFCell cell = row.createCell(0);
  1673. cell.setCellFormula("DEC2HEX(HEX2DEC(O8)-O2+D2)");
  1674. XSSFFormulaEvaluator fe = new XSSFFormulaEvaluator(wb);
  1675. CellValue cv = fe.evaluate(cell);
  1676. assertNotNull(cv);
  1677. }
  1678. }
  1679. @Test
  1680. void test57196_Detail2() throws IOException {
  1681. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  1682. XSSFSheet sheet = wb.createSheet("Sheet1");
  1683. XSSFRow row = sheet.createRow(0);
  1684. XSSFCell cell = row.createCell(0);
  1685. cell.setCellFormula("DEC2HEX(O2+D2)");
  1686. XSSFFormulaEvaluator fe = new XSSFFormulaEvaluator(wb);
  1687. CellValue cv = fe.evaluate(cell);
  1688. assertNotNull(cv);
  1689. }
  1690. }
  1691. @ParameterizedTest
  1692. @CsvSource({
  1693. // simple formula worked
  1694. "DEC2HEX(O2+D2), org.apache.poi.ss.formula.eval.StringEval [0]",
  1695. // this already failed! Hex2Dec did not correctly handle RefEval
  1696. "HEX2DEC(O8), org.apache.poi.ss.formula.eval.NumberEval [0]",
  1697. // slightly more complex one failed
  1698. "HEX2DEC(O8)-O2+D2, org.apache.poi.ss.formula.eval.NumberEval [0]",
  1699. // more complicated failed
  1700. "DEC2HEX(HEX2DEC(O8)-O2+D2), org.apache.poi.ss.formula.eval.StringEval [0]",
  1701. // what other similar functions
  1702. "DEC2BIN(O8)-O2+D2, org.apache.poi.ss.formula.eval.ErrorEval [#VALUE!]",
  1703. // what other similar functions
  1704. "DEC2BIN(A1), org.apache.poi.ss.formula.eval.StringEval [0]"
  1705. })
  1706. void test57196_WorkbookEvaluator(String formula, String expValue) throws IOException {
  1707. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  1708. XSSFSheet sheet = wb.createSheet("Sheet1");
  1709. XSSFRow row = sheet.createRow(0);
  1710. XSSFCell cell = row.createCell(0);
  1711. cell.setCellValue("0");
  1712. cell = row.createCell(1);
  1713. cell.setCellValue(0);
  1714. cell = row.createCell(2);
  1715. cell.setCellValue(0);
  1716. cell.setCellFormula(formula);
  1717. WorkbookEvaluator workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null);
  1718. workbookEvaluator.setDebugEvaluationOutputForNextEval(true);
  1719. ValueEval ve = workbookEvaluator.evaluate(new XSSFEvaluationCell(cell));
  1720. assertEquals(expValue, ve.toString());
  1721. }
  1722. }
  1723. /**
  1724. * A .xlsx file with no Shared Strings table should open fine
  1725. * in read-only mode
  1726. */
  1727. @ParameterizedTest
  1728. @EnumSource(value = PackageAccess.class, names = {"READ_WRITE", "READ"})
  1729. void bug57482(PackageAccess access) throws IOException, InvalidFormatException {
  1730. File file = HSSFTestDataSamples.getSampleFile("57482-OnlyNumeric.xlsx");
  1731. try (OPCPackage pkg = OPCPackage.open(file, access);
  1732. XSSFWorkbook wb1 = new XSSFWorkbook(pkg)) {
  1733. // Try to open it and read the contents
  1734. assertNotNull(wb1.getSharedStringSource());
  1735. assertEquals(0, wb1.getSharedStringSource().getCount());
  1736. DataFormatter fmt = new DataFormatter();
  1737. XSSFSheet s = wb1.getSheetAt(0);
  1738. assertEquals("1", fmt.formatCellValue(s.getRow(0).getCell(0)));
  1739. assertEquals("11", fmt.formatCellValue(s.getRow(0).getCell(1)));
  1740. assertEquals("5", fmt.formatCellValue(s.getRow(4).getCell(0)));
  1741. // Add a text cell
  1742. s.getRow(0).createCell(3).setCellValue("Testing");
  1743. assertEquals("Testing", fmt.formatCellValue(s.getRow(0).getCell(3)));
  1744. // Try to write-out and read again, should only work
  1745. // in read-write mode, not read-only mode
  1746. try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
  1747. assertNotEquals(PackageAccess.READ, access, "Shouln't be able to write from read-only mode");
  1748. // Check again
  1749. s = wb2.getSheetAt(0);
  1750. assertEquals("1", fmt.formatCellValue(s.getRow(0).getCell(0)));
  1751. assertEquals("11", fmt.formatCellValue(s.getRow(0).getCell(1)));
  1752. assertEquals("5", fmt.formatCellValue(s.getRow(4).getCell(0)));
  1753. assertEquals("Testing", fmt.formatCellValue(s.getRow(0).getCell(3)));
  1754. wb2.getPackage().revert();
  1755. } catch (InvalidOperationException e) {
  1756. if (access == PackageAccess.READ_WRITE) {
  1757. // Shouldn't occur in write-mode
  1758. throw e;
  1759. }
  1760. }
  1761. pkg.revert();
  1762. }
  1763. }
  1764. /**
  1765. * "Unknown error type: -60" fetching formula error value
  1766. */
  1767. @Test
  1768. void bug57535() throws IOException {
  1769. try (Workbook wb = openSampleWorkbook("57535.xlsx")) {
  1770. FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  1771. evaluator.clearAllCachedResultValues();
  1772. Sheet sheet = wb.getSheet("Sheet1");
  1773. Cell cell = sheet.getRow(5).getCell(4);
  1774. assertEquals(CellType.FORMULA, cell.getCellType());
  1775. assertEquals("E4+E5", cell.getCellFormula());
  1776. CellValue value = evaluator.evaluate(cell);
  1777. assertEquals(CellType.ERROR, value.getCellType());
  1778. assertEquals(-60, value.getErrorValue());
  1779. assertEquals("~CIRCULAR~REF~", FormulaError.forInt(value.getErrorValue()).getString());
  1780. assertEquals("CIRCULAR_REF", FormulaError.forInt(value.getErrorValue()).toString());
  1781. }
  1782. }
  1783. @Test
  1784. void test57165() throws IOException {
  1785. try (XSSFWorkbook wb = openSampleWorkbook("57171_57163_57165.xlsx")) {
  1786. removeAllSheetsBut(3, wb);
  1787. // Throws exception here
  1788. assertDoesNotThrow(() -> wb.cloneSheet(0));
  1789. wb.setSheetName(1, "New Sheet");
  1790. try (XSSFWorkbook wbBack = writeOutAndReadBack(wb)) {
  1791. assertNotNull(wbBack.getSheet("New Sheet"));
  1792. }
  1793. }
  1794. }
  1795. @Test
  1796. void test57165_create() throws IOException {
  1797. try (XSSFWorkbook wb = openSampleWorkbook("57171_57163_57165.xlsx")) {
  1798. removeAllSheetsBut(3, wb);
  1799. // Throws exception here
  1800. assertDoesNotThrow(() -> wb.createSheet("newsheet"));
  1801. wb.setSheetName(1, "New Sheet");
  1802. try (XSSFWorkbook wbBack = writeOutAndReadBack(wb)) {
  1803. assertNotNull(wbBack.getSheet("New Sheet"));
  1804. }
  1805. }
  1806. }
  1807. private static void removeAllSheetsBut(@SuppressWarnings("SameParameterValue") int sheetIndex, Workbook wb) {
  1808. int sheetNb = wb.getNumberOfSheets();
  1809. // Move this sheet at the first position
  1810. wb.setSheetOrder(wb.getSheetName(sheetIndex), 0);
  1811. for (int sn = sheetNb - 1; sn > 0; sn--) {
  1812. wb.removeSheetAt(sn);
  1813. }
  1814. }
  1815. /**
  1816. * Sums 2 plus the cell at the left, indirectly to avoid reference
  1817. * problems when deleting columns, conditionally to stop recursion
  1818. */
  1819. private static final String FORMULA1 =
  1820. "IF( INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) = 0, 0, "
  1821. + "INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) ) + 2";
  1822. /**
  1823. * Sums 2 plus the upper cell, indirectly to avoid reference
  1824. * problems when deleting rows, conditionally to stop recursion
  1825. */
  1826. private static final String FORMULA2 =
  1827. "IF( INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) = 0, 0, "
  1828. + "INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) ) + 2";
  1829. /**
  1830. * Expected:
  1831. * <p>
  1832. * [ 0][ 2][ 4]
  1833. */
  1834. @Test
  1835. void testBug56820_Formula1() throws IOException {
  1836. try (Workbook wb = new XSSFWorkbook()) {
  1837. FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  1838. Sheet sh = wb.createSheet();
  1839. sh.createRow(0).createCell(0).setCellValue(0.0d);
  1840. Cell formulaCell1 = sh.getRow(0).createCell(1);
  1841. Cell formulaCell2 = sh.getRow(0).createCell(2);
  1842. formulaCell1.setCellFormula(FORMULA1);
  1843. formulaCell2.setCellFormula(FORMULA1);
  1844. double A1 = evaluator.evaluate(formulaCell1).getNumberValue();
  1845. double A2 = evaluator.evaluate(formulaCell2).getNumberValue();
  1846. assertEquals(2, A1, 0);
  1847. assertEquals(4, A2, 0); //<-- FAILS EXPECTATIONS
  1848. }
  1849. }
  1850. /**
  1851. * Expected:
  1852. * <p>
  1853. * [ 0] <- number
  1854. * [ 2] <- formula
  1855. * [ 4] <- formula
  1856. */
  1857. @Test
  1858. void testBug56820_Formula2() throws IOException {
  1859. try (Workbook wb = new XSSFWorkbook()) {
  1860. FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  1861. Sheet sh = wb.createSheet();
  1862. sh.createRow(0).createCell(0).setCellValue(0.0d);
  1863. Cell formulaCell1 = sh.createRow(1).createCell(0);
  1864. Cell formulaCell2 = sh.createRow(2).createCell(0);
  1865. formulaCell1.setCellFormula(FORMULA2);
  1866. formulaCell2.setCellFormula(FORMULA2);
  1867. double A1 = evaluator.evaluate(formulaCell1).getNumberValue();
  1868. double A2 = evaluator.evaluate(formulaCell2).getNumberValue(); //<-- FAILS EVALUATION
  1869. assertEquals(2, A1, 0);
  1870. assertEquals(4, A2, 0);
  1871. }
  1872. }
  1873. @Test
  1874. void test56467() throws IOException {
  1875. try (Workbook wb = openSampleWorkbook("picture.xlsx")) {
  1876. Sheet orig = wb.getSheetAt(0);
  1877. assertNotNull(orig);
  1878. Sheet sheet = wb.cloneSheet(0);
  1879. Drawing<?> drawing = sheet.createDrawingPatriarch();
  1880. for (XSSFShape shape : ((XSSFDrawing) drawing).getShapes()) {
  1881. if (shape instanceof XSSFPicture) {
  1882. XSSFPictureData pictureData = ((XSSFPicture) shape).getPictureData();
  1883. assertNotNull(pictureData);
  1884. }
  1885. }
  1886. }
  1887. }
  1888. /**
  1889. * OOXML-Strict files
  1890. * Not currently working - namespace mis-match from XMLBeans
  1891. */
  1892. @Test
  1893. @Disabled("XMLBeans namespace mis-match on ooxml-strict files")
  1894. void test57699() throws IOException {
  1895. try (XSSFWorkbook wb = openSampleWorkbook("sample.strict.xlsx")) {
  1896. assertEquals(3, wb.getNumberOfSheets());
  1897. // TODO Check sheet contents
  1898. // TODO Check formula evaluation
  1899. try (XSSFWorkbook wbBack = writeOutAndReadBack(wb)) {
  1900. assertEquals(3, wbBack.getNumberOfSheets());
  1901. // TODO Re-check sheet contents
  1902. // TODO Re-check formula evaluation
  1903. }
  1904. }
  1905. }
  1906. @Test
  1907. void testBug56295_MergeXlslsWithStyles() throws IOException {
  1908. try (XSSFWorkbook xlsToAppendWorkbook = openSampleWorkbook("56295.xlsx");
  1909. XSSFWorkbook targetWorkbook = new XSSFWorkbook()) {
  1910. XSSFSheet sheet = xlsToAppendWorkbook.getSheetAt(0);
  1911. XSSFRow srcRow = sheet.getRow(0);
  1912. XSSFCell oldCell = srcRow.getCell(0);
  1913. XSSFCellStyle cellStyle = oldCell.getCellStyle();
  1914. checkStyle(cellStyle);
  1915. // StylesTable table = xlsToAppendWorkbook.getStylesSource();
  1916. // List<XSSFCellFill> fills = table.getFills();
  1917. // System.out.println("Having " + fills.size() + " fills");
  1918. // for(XSSFCellFill fill : fills) {
  1919. // System.out.println("Fill: " + fill.getFillBackgroundColor() + "/" + fill.getFillForegroundColor());
  1920. // }
  1921. xlsToAppendWorkbook.close();
  1922. XSSFSheet newSheet = targetWorkbook.createSheet(sheet.getSheetName());
  1923. XSSFRow destRow = newSheet.createRow(0);
  1924. XSSFCell newCell = destRow.createCell(0);
  1925. //newCell.getCellStyle().cloneStyleFrom(cellStyle);
  1926. CellStyle newCellStyle = targetWorkbook.createCellStyle();
  1927. newCellStyle.cloneStyleFrom(cellStyle);
  1928. newCell.setCellStyle(newCellStyle);
  1929. checkStyle(newCell.getCellStyle());
  1930. newCell.setCellValue(oldCell.getStringCellValue());
  1931. try (XSSFWorkbook wbBack = writeOutAndReadBack(targetWorkbook)) {
  1932. XSSFCellStyle styleBack = wbBack.getSheetAt(0).getRow(0).getCell(0).getCellStyle();
  1933. checkStyle(styleBack);
  1934. }
  1935. }
  1936. }
  1937. /**
  1938. * Paragraph with property BuFont but none of the properties
  1939. * BuNone, BuChar, and BuAutoNum, used to trigger a NPE
  1940. * Excel treats this as not-bulleted, so now do we
  1941. */
  1942. @Test
  1943. void testBug57826() throws IOException {
  1944. try (XSSFWorkbook workbook = openSampleWorkbook("57826.xlsx")) {
  1945. assertTrue(workbook.getNumberOfSheets() >= 1, "no sheets in workbook");
  1946. XSSFSheet sheet = workbook.getSheetAt(0);
  1947. XSSFDrawing drawing = sheet.getDrawingPatriarch();
  1948. assertNotNull(drawing);
  1949. List<XSSFShape> shapes = drawing.getShapes();
  1950. assertEquals(1, shapes.size());
  1951. assertTrue(shapes.get(0) instanceof XSSFSimpleShape);
  1952. XSSFSimpleShape shape = (XSSFSimpleShape) shapes.get(0);
  1953. // Used to throw a NPE
  1954. String text = shape.getText();
  1955. // No bulleting info included
  1956. assertEquals("test ok", text);
  1957. }
  1958. }
  1959. private void checkStyle(XSSFCellStyle cellStyle) {
  1960. assertNotNull(cellStyle);
  1961. assertEquals(0, cellStyle.getFillForegroundColor());
  1962. assertNotNull(cellStyle.getFillForegroundXSSFColor());
  1963. XSSFColor fgColor = cellStyle.getFillForegroundColorColor();
  1964. assertNotNull(fgColor);
  1965. assertEquals("FF00FFFF", fgColor.getARGBHex());
  1966. assertEquals(0, cellStyle.getFillBackgroundColor());
  1967. assertNotNull(cellStyle.getFillBackgroundXSSFColor());
  1968. XSSFColor bgColor = cellStyle.getFillBackgroundColorColor();
  1969. assertNotNull(bgColor);
  1970. assertEquals("FF00FFFF", fgColor.getARGBHex());
  1971. }
  1972. @Test
  1973. void bug57642() throws IOException {
  1974. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  1975. XSSFSheet s = wb.createSheet("TestSheet");
  1976. XSSFCell c = s.createRow(0).createCell(0);
  1977. c.setCellFormula("ISERROR(TestSheet!A1)");
  1978. c = s.createRow(1).createCell(1);
  1979. c.setCellFormula("ISERROR(B2)");
  1980. wb.setSheetName(0, "CSN");
  1981. c = s.getRow(0).getCell(0);
  1982. assertEquals("ISERROR(CSN!A1)", c.getCellFormula());
  1983. c = s.getRow(1).getCell(1);
  1984. assertEquals("ISERROR(B2)", c.getCellFormula());
  1985. }
  1986. }
  1987. /**
  1988. * .xlsx supports 64000 cell styles, the style indexes after
  1989. * 32,767 must not be -32,768, then -32,767, -32,766
  1990. */
  1991. @Test
  1992. void bug57880() throws IOException {
  1993. int numStyles = 33000;
  1994. File file;
  1995. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  1996. for (int i = 1; i < numStyles; i++) {
  1997. // Create a style and use it
  1998. XSSFCellStyle style = wb.createCellStyle();
  1999. assertEquals(i, style.getUIndex());
  2000. }
  2001. assertEquals(numStyles, wb.getNumCellStyles());
  2002. // avoid OOM in Gump run
  2003. file = XSSFTestDataSamples.writeOutAndClose(wb, "bug57880");
  2004. }
  2005. // avoid zip bomb detection
  2006. double ratio = ZipSecureFile.getMinInflateRatio();
  2007. ZipSecureFile.setMinInflateRatio(0.00005);
  2008. try (XSSFWorkbook wb = XSSFTestDataSamples.readBackAndDelete(file)) {
  2009. ZipSecureFile.setMinInflateRatio(ratio);
  2010. //Assume identical cell styles aren't consolidated
  2011. //If XSSFWorkbooks ever implicitly optimize/consolidate cell styles (such as when the workbook is written to disk)
  2012. //then this unit test should be updated
  2013. assertEquals(numStyles, wb.getNumCellStyles());
  2014. for (int i = 1; i < numStyles; i++) {
  2015. XSSFCellStyle style = wb.getCellStyleAt(i);
  2016. assertNotNull(style);
  2017. assertEquals(i, style.getUIndex());
  2018. }
  2019. }
  2020. }
  2021. @ParameterizedTest
  2022. @ValueSource(booleans = { false, true})
  2023. void test56574(boolean createRow) throws IOException {
  2024. try (XSSFWorkbook wb = openSampleWorkbook("56574.xlsx")) {
  2025. Sheet sheet = wb.getSheet("Func");
  2026. assertNotNull(sheet);
  2027. Map<String, Object[]> data;
  2028. data = new TreeMap<>();
  2029. data.put("1", new Object[]{"ID", "NAME", "LASTNAME"});
  2030. data.put("2", new Object[]{2, "Amit", "Shukla"});
  2031. data.put("3", new Object[]{1, "Lokesh", "Gupta"});
  2032. data.put("4", new Object[]{4, "John", "Adwards"});
  2033. data.put("5", new Object[]{2, "Brian", "Schultz"});
  2034. int rownum = 1;
  2035. for (Map.Entry<String, Object[]> me : data.entrySet()) {
  2036. final Row row;
  2037. if (createRow) {
  2038. row = sheet.createRow(rownum++);
  2039. } else {
  2040. row = sheet.getRow(rownum++);
  2041. }
  2042. assertNotNull(row);
  2043. int cellnum = 0;
  2044. for (Object obj : me.getValue()) {
  2045. Cell cell = row.getCell(cellnum);
  2046. if (cell == null) {
  2047. cell = row.createCell(cellnum);
  2048. } else {
  2049. if (cell.getCellType() == CellType.FORMULA) {
  2050. cell.setCellFormula(null);
  2051. cell.getCellStyle().setDataFormat((short) 0);
  2052. }
  2053. }
  2054. if (obj instanceof String) {
  2055. cell.setCellValue((String) obj);
  2056. } else if (obj instanceof Integer) {
  2057. cell.setCellValue((Integer) obj);
  2058. }
  2059. cellnum++;
  2060. }
  2061. }
  2062. XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
  2063. wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
  2064. CalculationChain chain = wb.getCalculationChain();
  2065. checkCellsAreGone(chain);
  2066. try (XSSFWorkbook wbBack = writeOutAndReadBack(wb)) {
  2067. Sheet sheetBack = wbBack.getSheet("Func");
  2068. assertNotNull(sheetBack);
  2069. chain = wbBack.getCalculationChain();
  2070. checkCellsAreGone(chain);
  2071. }
  2072. }
  2073. }
  2074. private void checkCellsAreGone(CalculationChain chain) {
  2075. for (CTCalcCell calc : chain.getCTCalcChain().getCList()) {
  2076. // A2 to A6 should be gone
  2077. assertNotEquals("A2", calc.getR());
  2078. assertNotEquals("A3", calc.getR());
  2079. assertNotEquals("A4", calc.getR());
  2080. assertNotEquals("A5", calc.getR());
  2081. assertNotEquals("A6", calc.getR());
  2082. }
  2083. }
  2084. /**
  2085. * Excel 2007 generated Macro-Enabled .xlsm file
  2086. */
  2087. @Test
  2088. void bug57181() throws IOException {
  2089. try (XSSFWorkbook wb = openSampleWorkbook("57181.xlsm")) {
  2090. assertEquals(9, wb.getNumberOfSheets());
  2091. }
  2092. }
  2093. @Test
  2094. void bug52111() throws IOException {
  2095. try (Workbook wb = openSampleWorkbook("Intersection-52111-xssf.xlsx")) {
  2096. Sheet s = wb.getSheetAt(0);
  2097. assertFormula(wb, s.getRow(2).getCell(0), "(C2:D3 D3:E4)", "4.0");
  2098. assertFormula(wb, s.getRow(6).getCell(0), "Tabelle2!E:E Tabelle2!11:11", "5.0");
  2099. assertFormula(wb, s.getRow(8).getCell(0), "Tabelle2!E:F Tabelle2!11:12", null);
  2100. }
  2101. }
  2102. @Test
  2103. void test48962() throws IOException {
  2104. try (Workbook wb = openSampleWorkbook("48962.xlsx")) {
  2105. Sheet sh = wb.getSheetAt(0);
  2106. Row row = sh.getRow(1);
  2107. Cell cell = row.getCell(0);
  2108. CellStyle style = cell.getCellStyle();
  2109. assertNotNull(style);
  2110. // color index
  2111. assertEquals(64, style.getFillBackgroundColor());
  2112. XSSFColor color = ((XSSFCellStyle) style).getFillBackgroundXSSFColor();
  2113. assertNotNull(color);
  2114. // indexed color
  2115. assertEquals(64, color.getIndexed());
  2116. assertEquals(64, color.getIndex());
  2117. // not an RGB color
  2118. assertFalse(color.isRGB());
  2119. assertNull(color.getRGB());
  2120. }
  2121. }
  2122. @Test
  2123. void test50755_workday_formula_example() throws IOException {
  2124. try (Workbook wb = openSampleWorkbook("50755_workday_formula_example.xlsx")) {
  2125. Sheet sheet = wb.getSheet("Sheet1");
  2126. for (Row aRow : sheet) {
  2127. Cell cell = aRow.getCell(1);
  2128. if (cell.getCellType() == CellType.FORMULA) {
  2129. String formula = cell.getCellFormula();
  2130. assertNotNull(formula);
  2131. assertTrue(formula.contains("WORKDAY"));
  2132. } else {
  2133. assertNotNull(cell.toString());
  2134. }
  2135. }
  2136. }
  2137. }
  2138. @ParameterizedTest
  2139. @ValueSource(strings = { "51626.xlsx", "51626_contact.xlsx"})
  2140. void test51626(String fileName) throws IOException {
  2141. try (Workbook wb = openSampleWorkbook(fileName)) {
  2142. assertNotNull(wb);
  2143. }
  2144. try (InputStream stream = HSSFTestDataSamples.openSampleFileStream(fileName);
  2145. Workbook wb = WorkbookFactory.create(stream)) {
  2146. assertNotNull(wb);
  2147. }
  2148. }
  2149. @Disabled("this test is only for manual verification, as we can't test if the cell is visible in Excel")
  2150. void test51451() throws IOException {
  2151. try (Workbook wb = new XSSFWorkbook()) {
  2152. Sheet sh = wb.createSheet();
  2153. Row row = sh.createRow(0);
  2154. Cell cell = row.createCell(0);
  2155. cell.setCellValue(239827342);
  2156. CellStyle style = wb.createCellStyle();
  2157. //style.setHidden(false);
  2158. DataFormat excelFormat = wb.createDataFormat();
  2159. style.setDataFormat(excelFormat.getFormat("#,##0"));
  2160. sh.setDefaultColumnStyle(0, style);
  2161. }
  2162. }
  2163. @Test
  2164. void test53105() throws IOException {
  2165. try (Workbook wb = openSampleWorkbook("53105.xlsx")) {
  2166. assertNotNull(wb);
  2167. // Act
  2168. // evaluate SUM('Skye Lookup Input'!A4:XFD4), cells in range each contain "1"
  2169. FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  2170. double numericValue = evaluator.evaluate(wb.getSheetAt(0).getRow(1).getCell(0)).getNumberValue();
  2171. // Assert
  2172. assertEquals(16384.0, numericValue, 0.0);
  2173. }
  2174. }
  2175. @Test
  2176. void test58315() throws IOException {
  2177. try (Workbook wb = openSampleWorkbook("58315.xlsx")) {
  2178. Cell cell = wb.getSheetAt(0).getRow(0).getCell(0);
  2179. assertNotNull(cell);
  2180. StringBuilder tmpCellContent = new StringBuilder(cell.getStringCellValue());
  2181. XSSFRichTextString richText = (XSSFRichTextString) cell.getRichStringCellValue();
  2182. for (int i = richText.length() - 1; i >= 0; i--) {
  2183. Font f = richText.getFontAtIndex(i);
  2184. if (f != null && f.getStrikeout()) {
  2185. tmpCellContent.deleteCharAt(i);
  2186. }
  2187. }
  2188. String result = tmpCellContent.toString();
  2189. assertEquals("320 350", result);
  2190. }
  2191. }
  2192. @Test
  2193. void test55406() throws IOException {
  2194. try (Workbook wb = openSampleWorkbook("55406_Conditional_formatting_sample.xlsx")) {
  2195. Sheet sheet = wb.getSheetAt(0);
  2196. Cell cellA1 = sheet.getRow(0).getCell(0);
  2197. Cell cellA2 = sheet.getRow(1).getCell(0);
  2198. assertEquals(0, cellA1.getCellStyle().getFillForegroundColor());
  2199. assertEquals("FFFDFDFD", ((XSSFColor) cellA1.getCellStyle().getFillForegroundColorColor()).getARGBHex());
  2200. assertEquals(0, cellA2.getCellStyle().getFillForegroundColor());
  2201. assertEquals("FFFDFDFD", ((XSSFColor) cellA2.getCellStyle().getFillForegroundColorColor()).getARGBHex());
  2202. SheetConditionalFormatting cond = sheet.getSheetConditionalFormatting();
  2203. assertEquals(2, cond.getNumConditionalFormattings());
  2204. assertEquals(1, cond.getConditionalFormattingAt(0).getNumberOfRules());
  2205. assertEquals(64, cond.getConditionalFormattingAt(0).getRule(0).getPatternFormatting().getFillForegroundColor());
  2206. assertEquals("ISEVEN(ROW())", cond.getConditionalFormattingAt(0).getRule(0).getFormula1());
  2207. assertNull(((XSSFColor) cond.getConditionalFormattingAt(0).getRule(0).getPatternFormatting().getFillForegroundColorColor()).getARGBHex());
  2208. assertEquals(1, cond.getConditionalFormattingAt(1).getNumberOfRules());
  2209. assertEquals(64, cond.getConditionalFormattingAt(1).getRule(0).getPatternFormatting().getFillForegroundColor());
  2210. assertEquals("ISEVEN(ROW())", cond.getConditionalFormattingAt(1).getRule(0).getFormula1());
  2211. assertNull(((XSSFColor) cond.getConditionalFormattingAt(1).getRule(0).getPatternFormatting().getFillForegroundColorColor()).getARGBHex());
  2212. }
  2213. }
  2214. @Test
  2215. void test51998() throws IOException {
  2216. try (Workbook wb = openSampleWorkbook("51998.xlsx")) {
  2217. Set<String> sheetNames = new HashSet<>();
  2218. for (int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) {
  2219. sheetNames.add(wb.getSheetName(sheetNum));
  2220. }
  2221. for (String sheetName : sheetNames) {
  2222. int sheetIndex = wb.getSheetIndex(sheetName);
  2223. wb.removeSheetAt(sheetIndex);
  2224. Sheet newSheet = wb.createSheet();
  2225. //Sheet newSheet = wb.createSheet(sheetName);
  2226. int newSheetIndex = wb.getSheetIndex(newSheet);
  2227. wb.setSheetName(newSheetIndex, sheetName);
  2228. wb.setSheetOrder(sheetName, sheetIndex);
  2229. }
  2230. try (Workbook wbBack = writeOutAndReadBack(wb)) {
  2231. assertNotNull(wbBack);
  2232. }
  2233. }
  2234. }
  2235. @Test
  2236. void test58731() throws IOException {
  2237. Object[][] bookData = {
  2238. {"Head First Java", "Kathy Serria", 79},
  2239. {"Effective Java", "Joshua Bloch", 36},
  2240. {"Clean Code", "Robert martin", 42},
  2241. {"Thinking in Java", "Bruce Eckel", 35},
  2242. };
  2243. try (Workbook wb = openSampleWorkbook("58731.xlsx")) {
  2244. Sheet sheet = wb.createSheet("Java Books");
  2245. int rowCount = 0;
  2246. for (Object[] aBook : bookData) {
  2247. Row row = sheet.createRow(rowCount++);
  2248. int columnCount = 0;
  2249. for (Object field : aBook) {
  2250. Cell cell = row.createCell(columnCount++);
  2251. if (field instanceof String) {
  2252. cell.setCellValue((String) field);
  2253. } else if (field instanceof Integer) {
  2254. cell.setCellValue((Integer) field);
  2255. }
  2256. }
  2257. }
  2258. try (Workbook wb2 = writeOutAndReadBack(wb)) {
  2259. sheet = wb2.getSheet("Java Books");
  2260. assertNotNull(sheet.getRow(0));
  2261. assertNotNull(sheet.getRow(0).getCell(0));
  2262. assertEquals(bookData[0][0], sheet.getRow(0).getCell(0).getStringCellValue());
  2263. }
  2264. }
  2265. }
  2266. /**
  2267. * Regression between 3.10.1 and 3.13 -
  2268. * org.apache.poi.openxml4j.exceptions.InvalidFormatException:
  2269. * The part /xl/sharedStrings.xml does not have any content type
  2270. * ! Rule: Package require content types when retrieving a part from a package. [M.1.14]
  2271. */
  2272. @Test
  2273. void test58760() throws IOException {
  2274. try (Workbook wb1 = openSampleWorkbook("58760.xlsx")) {
  2275. assertEquals(1, wb1.getNumberOfSheets());
  2276. assertEquals("Sheet1", wb1.getSheetName(0));
  2277. try (Workbook wb2 = writeOutAndReadBack(wb1)) {
  2278. assertEquals(1, wb2.getNumberOfSheets());
  2279. assertEquals("Sheet1", wb2.getSheetName(0));
  2280. }
  2281. }
  2282. }
  2283. @Test
  2284. void test57236() throws IOException {
  2285. // Having very small numbers leads to different formatting, Excel uses the scientific notation, but POI leads to "0"
  2286. /*
  2287. DecimalFormat format = new DecimalFormat("#.##########", new DecimalFormatSymbols(Locale.getDefault()));
  2288. double d = 3.0E-104;
  2289. assertEquals("3.0E-104", format.format(d));
  2290. */
  2291. DataFormatter formatter = new DataFormatter(true);
  2292. try (XSSFWorkbook wb = openSampleWorkbook("57236.xlsx")) {
  2293. for (int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) {
  2294. Sheet sheet = wb.getSheetAt(sheetNum);
  2295. for (int rowNum = sheet.getFirstRowNum(); rowNum < sheet.getLastRowNum(); rowNum++) {
  2296. Row row = sheet.getRow(rowNum);
  2297. for (int cellNum = row.getFirstCellNum(); cellNum < row.getLastCellNum(); cellNum++) {
  2298. Cell cell = row.getCell(cellNum);
  2299. String fmtCellValue = formatter.formatCellValue(cell);
  2300. assertNotNull(fmtCellValue);
  2301. assertNotEquals("0", fmtCellValue);
  2302. }
  2303. }
  2304. }
  2305. }
  2306. }
  2307. @ParameterizedTest()
  2308. @CsvSource({ "false, rotated.xls", "true, rotated.xlsx" })
  2309. @Disabled("Creates files for checking results manually, actual values are tested in Test*CellStyle")
  2310. void test58043(boolean xssf, String fileName) throws IOException {
  2311. try (Workbook wb = WorkbookFactory.create(xssf)) {
  2312. Sheet sheet = wb.createSheet();
  2313. Row row = sheet.createRow((short) 0);
  2314. Cell cell = row.createCell(0);
  2315. cell.setCellValue("Unsuccessful rotated text.");
  2316. CellStyle style = wb.createCellStyle();
  2317. style.setRotation((short) -90);
  2318. cell.setCellStyle(style);
  2319. assertEquals(180, style.getRotation());
  2320. XSSFTestDataSamples.writeOut(wb, fileName);
  2321. }
  2322. }
  2323. @Test
  2324. void test59132() throws IOException {
  2325. try (Workbook workbook = openSampleWorkbook("59132.xlsx")) {
  2326. Sheet worksheet = workbook.getSheet("sheet1");
  2327. // B3
  2328. Row row = worksheet.getRow(2);
  2329. Cell cell = row.getCell(1);
  2330. cell.setCellValue((String) null);
  2331. FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
  2332. // B3
  2333. row = worksheet.getRow(2);
  2334. cell = row.getCell(1);
  2335. assertEquals(CellType.BLANK, cell.getCellType());
  2336. assertEquals(CellType._NONE, evaluator.evaluateFormulaCell(cell));
  2337. // A3
  2338. row = worksheet.getRow(2);
  2339. cell = row.getCell(0);
  2340. assertEquals(CellType.FORMULA, cell.getCellType());
  2341. assertEquals("IF(ISBLANK(B3),\"\",B3)", cell.getCellFormula());
  2342. assertEquals(CellType.STRING, evaluator.evaluateFormulaCell(cell));
  2343. CellValue value = evaluator.evaluate(cell);
  2344. assertEquals("", value.getStringValue());
  2345. // A5
  2346. row = worksheet.getRow(4);
  2347. cell = row.getCell(0);
  2348. assertEquals(CellType.FORMULA, cell.getCellType());
  2349. assertEquals("COUNTBLANK(A1:A4)", cell.getCellFormula());
  2350. assertEquals(CellType.NUMERIC, evaluator.evaluateFormulaCell(cell));
  2351. value = evaluator.evaluate(cell);
  2352. assertEquals(1.0, value.getNumberValue(), 0.1);
  2353. }
  2354. }
  2355. @Disabled("bug 59442")
  2356. @Test
  2357. void testSetRGBBackgroundColor() throws IOException {
  2358. try (XSSFWorkbook workbook = new XSSFWorkbook()) {
  2359. XSSFCell cell = workbook.createSheet().createRow(0).createCell(0);
  2360. XSSFColor color = new XSSFColor(java.awt.Color.RED, workbook.getStylesSource().getIndexedColors());
  2361. XSSFCellStyle style = workbook.createCellStyle();
  2362. style.setFillForegroundColor(color);
  2363. style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  2364. cell.setCellStyle(style);
  2365. // Everything is fine at this point, cell is red
  2366. XSSFColor actual = cell.getCellStyle().getFillBackgroundColorColor();
  2367. assertNull(actual);
  2368. actual = cell.getCellStyle().getFillForegroundColorColor();
  2369. assertNotNull(actual);
  2370. assertEquals(color.getARGBHex(), actual.getARGBHex());
  2371. Map<String, Object> properties = new HashMap<>();
  2372. properties.put(CellUtil.BORDER_BOTTOM, BorderStyle.THIN);
  2373. CellUtil.setCellStyleProperties(cell, properties);
  2374. // Now the cell is all black
  2375. actual = cell.getCellStyle().getFillBackgroundColorColor();
  2376. assertNotNull(actual);
  2377. assertNull(actual.getARGBHex());
  2378. actual = cell.getCellStyle().getFillForegroundColorColor();
  2379. assertNotNull(actual);
  2380. assertEquals(color.getARGBHex(), actual.getARGBHex());
  2381. try (XSSFWorkbook nwb = writeOutAndReadBack(workbook)) {
  2382. XSSFCell ncell = nwb.getSheetAt(0).getRow(0).getCell(0);
  2383. XSSFColor ncolor = new XSSFColor(java.awt.Color.RED, workbook.getStylesSource().getIndexedColors());
  2384. // Now the cell is all black
  2385. XSSFColor nactual = ncell.getCellStyle().getFillBackgroundColorColor();
  2386. assertNotNull(nactual);
  2387. assertEquals(ncolor.getARGBHex(), nactual.getARGBHex());
  2388. }
  2389. }
  2390. }
  2391. @Disabled("currently fails on POI 3.15 beta 2")
  2392. @Test
  2393. void test55273() throws IOException {
  2394. try (Workbook wb = openSampleWorkbook("ExcelTables.xlsx")) {
  2395. Sheet sheet = wb.getSheet("ExcelTable");
  2396. Name name = wb.getName("TableAsRangeName");
  2397. assertEquals("TableName[#All]", name.getRefersToFormula());
  2398. // POI 3.15-beta 2 (2016-06-15): getSheetName throws IllegalArgumentException: Invalid CellReference: TableName[#All]
  2399. assertEquals("TableName", name.getSheetName());
  2400. XSSFSheet xsheet = (XSSFSheet) sheet;
  2401. List<XSSFTable> tables = xsheet.getTables();
  2402. assertEquals(2, tables.size()); //FIXME: how many tables are there in this spreadsheet?
  2403. assertEquals("Table1", tables.get(0).getName()); //FIXME: what is the table name?
  2404. assertEquals("Table2", tables.get(1).getName()); //FIXME: what is the table name?
  2405. }
  2406. }
  2407. @Test
  2408. void test57523() throws IOException {
  2409. try (Workbook wb = openSampleWorkbook("57523.xlsx")) {
  2410. Sheet sheet = wb.getSheet("Attribute Master");
  2411. Row row = sheet.getRow(15);
  2412. int N = CellReference.convertColStringToIndex("N");
  2413. Cell N16 = row.getCell(N);
  2414. assertEquals(500.0, N16.getNumericCellValue(), 0.00001);
  2415. int P = CellReference.convertColStringToIndex("P");
  2416. Cell P16 = row.getCell(P);
  2417. assertEquals(10.0, P16.getNumericCellValue(), 0.00001);
  2418. }
  2419. }
  2420. /**
  2421. * Files produced by some scientific equipment neglect
  2422. * to include the row number on the row tags
  2423. */
  2424. @Test
  2425. void noRowNumbers59746() throws IOException {
  2426. try (Workbook wb = openSampleWorkbook("59746_NoRowNums.xlsx")) {
  2427. Sheet sheet = wb.getSheetAt(0);
  2428. assertTrue(sheet.getLastRowNum() > 20, "Last row num: " + sheet.getLastRowNum());
  2429. assertEquals("Checked", sheet.getRow(0).getCell(0).getStringCellValue());
  2430. assertEquals("Checked", sheet.getRow(9).getCell(2).getStringCellValue());
  2431. assertFalse(sheet.getRow(70).getCell(8).getBooleanCellValue());
  2432. assertEquals(71, sheet.getPhysicalNumberOfRows());
  2433. assertEquals(70, sheet.getLastRowNum());
  2434. assertEquals(70, sheet.getRow(sheet.getLastRowNum()).getRowNum());
  2435. }
  2436. }
  2437. @Test
  2438. void testWorkdayFunction() throws IOException {
  2439. try (XSSFWorkbook workbook = openSampleWorkbook("59106.xlsx")) {
  2440. XSSFSheet sheet = workbook.getSheet("Test");
  2441. Row row = sheet.getRow(1);
  2442. Cell cell = row.getCell(0);
  2443. DataFormatter form = new DataFormatter();
  2444. FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
  2445. String result = form.formatCellValue(cell, evaluator);
  2446. assertEquals("09 Mar 2016", result);
  2447. }
  2448. }
  2449. // This bug is currently open. When this bug is fixed, it should not throw an AssertionError
  2450. @Test
  2451. void test55076_collapseColumnGroups() throws Exception {
  2452. try (Workbook wb = new XSSFWorkbook()) {
  2453. Sheet sheet = wb.createSheet();
  2454. // this column collapsing bug only occurs when the grouped columns are different widths
  2455. sheet.setColumnWidth(1, 400);
  2456. sheet.setColumnWidth(2, 600);
  2457. sheet.setColumnWidth(3, 800);
  2458. assertEquals(400, sheet.getColumnWidth(1));
  2459. assertEquals(600, sheet.getColumnWidth(2));
  2460. assertEquals(800, sheet.getColumnWidth(3));
  2461. sheet.groupColumn(1, 3);
  2462. sheet.setColumnGroupCollapsed(1, true);
  2463. assertEquals(0, sheet.getColumnOutlineLevel(0));
  2464. assertEquals(1, sheet.getColumnOutlineLevel(1));
  2465. assertEquals(1, sheet.getColumnOutlineLevel(2));
  2466. assertEquals(1, sheet.getColumnOutlineLevel(3));
  2467. assertEquals(0, sheet.getColumnOutlineLevel(4));
  2468. // none of the columns should be hidden
  2469. // column group collapsing is a different concept
  2470. for (int c = 0; c < 5; c++) {
  2471. // if this fails for c == 1 in the future, then the implementation will be correct
  2472. // and we need to adapt this test accordingly
  2473. assertEquals(c == 1, sheet.isColumnHidden(c), "Column " + c);
  2474. }
  2475. assertEquals(400, sheet.getColumnWidth(1));
  2476. // 600 is the correct value! ... 2048 is just for pacifying the test (see above comment)
  2477. assertEquals(2048, sheet.getColumnWidth(2));
  2478. assertEquals(800, sheet.getColumnWidth(3));
  2479. }
  2480. }
  2481. /**
  2482. * Other things, including charts, may end up taking drawing part
  2483. * numbers. (Uses a test file hand-crafted with an extra non-drawing
  2484. * part with a part number)
  2485. */
  2486. @Test
  2487. void drawingNumbersAlreadyTaken_60255() throws IOException {
  2488. try (Workbook wb = openSampleWorkbook("60255_extra_drawingparts.xlsx")) {
  2489. assertEquals(4, wb.getNumberOfSheets());
  2490. // Sheet 3 starts with a drawing
  2491. Sheet sheet = wb.getSheetAt(0);
  2492. assertNull(sheet.getDrawingPatriarch());
  2493. sheet = wb.getSheetAt(1);
  2494. assertNull(sheet.getDrawingPatriarch());
  2495. sheet = wb.getSheetAt(2);
  2496. assertNotNull(sheet.getDrawingPatriarch());
  2497. sheet = wb.getSheetAt(3);
  2498. assertNull(sheet.getDrawingPatriarch());
  2499. // Add another sheet, and give it a drawing
  2500. sheet = wb.createSheet();
  2501. assertNull(sheet.getDrawingPatriarch());
  2502. sheet.createDrawingPatriarch();
  2503. assertNotNull(sheet.getDrawingPatriarch());
  2504. // Save and check
  2505. Workbook wbBack = writeOutAndReadBack(wb);
  2506. assertEquals(5, wbBack.getNumberOfSheets());
  2507. // Sheets 3 and 5 now
  2508. sheet = wbBack.getSheetAt(0);
  2509. assertNull(sheet.getDrawingPatriarch());
  2510. sheet = wbBack.getSheetAt(1);
  2511. assertNull(sheet.getDrawingPatriarch());
  2512. sheet = wbBack.getSheetAt(2);
  2513. assertNotNull(sheet.getDrawingPatriarch());
  2514. sheet = wbBack.getSheetAt(3);
  2515. assertNull(sheet.getDrawingPatriarch());
  2516. sheet = wbBack.getSheetAt(4);
  2517. assertNotNull(sheet.getDrawingPatriarch());
  2518. }
  2519. }
  2520. @Test
  2521. void test53611() throws IOException {
  2522. try (Workbook wb = new XSSFWorkbook()) {
  2523. Sheet sheet = wb.createSheet("test");
  2524. Row row = sheet.createRow(1);
  2525. Cell cell = row.createCell(1);
  2526. cell.setCellValue("blabla");
  2527. //0 1 2 3 4 5 6 7
  2528. //A B C D E F G H
  2529. row = sheet.createRow(4);
  2530. cell = row.createCell(7);
  2531. cell.setCellValue("blabla");
  2532. // we currently only populate the dimension during writing out
  2533. // to avoid having to iterate all rows/cells in each add/remove of a row or cell
  2534. wb.write(NullOutputStream.INSTANCE);
  2535. assertEquals("B2:H5", ((XSSFSheet) sheet).getCTWorksheet().getDimension().getRef());
  2536. }
  2537. }
  2538. @Test
  2539. void test61798() throws IOException {
  2540. try (Workbook wb = new XSSFWorkbook()) {
  2541. Sheet sheet = wb.createSheet("test");
  2542. Row row = sheet.createRow(1);
  2543. Cell cell = row.createCell(1);
  2544. cell.setCellValue("blabla");
  2545. row = sheet.createRow(4);
  2546. // Allowable column range for EXCEL2007 is (0..16383) or ('A'..'XDF')
  2547. cell = row.createCell(16383);
  2548. cell.setCellValue("blabla");
  2549. // we currently only populate the dimension during writing out
  2550. // to avoid having to iterate all rows/cells in each add/remove of a row or cell
  2551. wb.write(NullOutputStream.INSTANCE);
  2552. assertEquals("B2:XFD5", ((XSSFSheet) sheet).getCTWorksheet().getDimension().getRef());
  2553. }
  2554. }
  2555. @Test
  2556. void bug61063() throws Exception {
  2557. try (Workbook wb = openSampleWorkbook("61063.xlsx")) {
  2558. FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
  2559. Sheet s = wb.getSheetAt(0);
  2560. Row r = s.getRow(3);
  2561. Cell c = r.getCell(0);
  2562. assertEquals(CellType.FORMULA, c.getCellType());
  2563. eval.setDebugEvaluationOutputForNextEval(true);
  2564. CellValue cv = eval.evaluate(c);
  2565. assertNotNull(cv);
  2566. assertEquals(2.0, cv.getNumberValue(), 0.00001, "Had: " + cv);
  2567. }
  2568. }
  2569. @Test
  2570. void bug61516() throws IOException {
  2571. final String initialFormula = "A1";
  2572. final String expectedFormula = "#REF!"; // from ms excel
  2573. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  2574. Sheet sheet = wb.createSheet("sheet1");
  2575. sheet.createRow(0).createCell(0).setCellValue(1); // A1 = 1
  2576. {
  2577. Cell c3 = sheet.createRow(2).createCell(2);
  2578. c3.setCellFormula(initialFormula); // C3 = =A1
  2579. FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  2580. CellValue cellValue = evaluator.evaluate(c3);
  2581. assertEquals(1, cellValue.getNumberValue(), 0.0001);
  2582. }
  2583. {
  2584. FormulaShifter formulaShifter = FormulaShifter.createForRowCopy(0, "sheet1", 2/*firstRowToShift*/, 2/*lastRowToShift*/
  2585. , -1/*step*/, SpreadsheetVersion.EXCEL2007); // parameters 2, 2, -1 should mean : move row range [2-2] one level up
  2586. XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
  2587. Ptg[] ptgs = FormulaParser.parse(initialFormula, fpb, FormulaType.CELL, 0); // [A1]
  2588. formulaShifter.adjustFormula(ptgs, 0); // adjusted to [A]
  2589. String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); //A
  2590. //System.out.println(String.format("initial formula : A1; expected formula value after shifting up : #REF!; actual formula value : %s", shiftedFmla));
  2591. assertEquals(expectedFormula, shiftedFmla,
  2592. "On copy we expect the formula to be adjusted, in this case it would point to row -1, which is an invalid REF");
  2593. }
  2594. {
  2595. FormulaShifter formulaShifter = FormulaShifter.createForRowShift(0, "sheet1", 2/*firstRowToShift*/, 2/*lastRowToShift*/
  2596. , -1/*step*/, SpreadsheetVersion.EXCEL2007); // parameters 2, 2, -1 should mean : move row range [2-2] one level up
  2597. XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
  2598. Ptg[] ptgs = FormulaParser.parse(initialFormula, fpb, FormulaType.CELL, 0); // [A1]
  2599. formulaShifter.adjustFormula(ptgs, 0); // adjusted to [A]
  2600. String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); //A
  2601. //System.out.println(String.format("initial formula : A1; expected formula value after shifting up : #REF!; actual formula value : %s", shiftedFmla));
  2602. assertEquals(initialFormula, shiftedFmla,
  2603. "On move we expect the formula to stay the same, thus expecting the initial formula A1 here");
  2604. }
  2605. sheet.shiftRows(2, 2, -1);
  2606. {
  2607. Cell c2 = sheet.getRow(1).getCell(2);
  2608. assertNotNull(c2, "cell C2 needs to exist now");
  2609. assertEquals(CellType.FORMULA, c2.getCellType());
  2610. assertEquals(initialFormula, c2.getCellFormula());
  2611. FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  2612. CellValue cellValue = evaluator.evaluate(c2);
  2613. assertEquals(1, cellValue.getNumberValue(), 0.0001);
  2614. }
  2615. }
  2616. }
  2617. @Test
  2618. void test61652() throws IOException {
  2619. try (Workbook wb = openSampleWorkbook("61652.xlsx")) {
  2620. Sheet sheet = wb.getSheet("IRPPCalc");
  2621. Row row = sheet.getRow(11);
  2622. Cell cell = row.getCell(18);
  2623. WorkbookEvaluatorProvider fe = (WorkbookEvaluatorProvider) wb.getCreationHelper().createFormulaEvaluator();
  2624. ConditionalFormattingEvaluator condfmt = new ConditionalFormattingEvaluator(wb, fe);
  2625. assertEquals("[]", condfmt.getConditionalFormattingForCell(cell).toString(),
  2626. "Conditional formatting is not triggered for this cell");
  2627. // but we can read the conditional formatting itself
  2628. List<EvaluationConditionalFormatRule> rules = condfmt.getFormatRulesForSheet(sheet);
  2629. assertEquals(1, rules.size());
  2630. assertEquals("AND($A1>=EDATE($D$6,3),$B1>0)", rules.get(0).getFormula1());
  2631. }
  2632. }
  2633. @Test
  2634. void test61543() throws IOException {
  2635. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  2636. XSSFSheet sheet = wb.createSheet();
  2637. XSSFTable table1 = sheet.createTable(null);
  2638. XSSFTable table2 = sheet.createTable(null);
  2639. XSSFTable table3 = sheet.createTable(null);
  2640. assertDoesNotThrow(() -> sheet.removeTable(table1));
  2641. assertDoesNotThrow(() -> sheet.createTable(null));
  2642. assertDoesNotThrow(() -> sheet.removeTable(table2));
  2643. assertDoesNotThrow(() -> sheet.removeTable(table3));
  2644. assertDoesNotThrow(() -> sheet.createTable(null));
  2645. }
  2646. }
  2647. /**
  2648. * Auto column sizing failed when there were loads of fonts with
  2649. * errors like ArrayIndexOutOfBoundsException: -32765
  2650. */
  2651. @Test
  2652. void test62108() throws IOException {
  2653. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  2654. XSSFSheet sheet = wb.createSheet();
  2655. XSSFRow row = sheet.createRow(0);
  2656. // Create lots of fonts
  2657. XSSFDataFormat formats = wb.createDataFormat();
  2658. XSSFFont[] fonts = new XSSFFont[50000];
  2659. for (int i = 0; i < fonts.length; i++) {
  2660. XSSFFont font = wb.createFont();
  2661. font.setFontHeight(i);
  2662. fonts[i] = font;
  2663. }
  2664. // Create a moderate number of columns, which use
  2665. // fonts from the start and end of the font list
  2666. final int numCols = 125;
  2667. for (int i = 0; i < numCols; i++) {
  2668. XSSFCellStyle cs = wb.createCellStyle();
  2669. cs.setDataFormat(formats.getFormat("'Test " + i + "' #,###"));
  2670. XSSFFont font = fonts[i];
  2671. if (i % 2 == 1) {
  2672. font = fonts[fonts.length - i];
  2673. }
  2674. cs.setFont(font);
  2675. XSSFCell c = row.createCell(i);
  2676. c.setCellValue(i);
  2677. c.setCellStyle(cs);
  2678. }
  2679. // Do the auto-size
  2680. for (int i = 0; i < numCols; i++) {
  2681. int i2 = i;
  2682. assertDoesNotThrow(() -> sheet.autoSizeColumn(i2));
  2683. }
  2684. }
  2685. }
  2686. @ParameterizedTest
  2687. @ValueSource(booleans = { false, true })
  2688. void test61905(boolean xssf) throws IOException {
  2689. ITestDataProvider instance = xssf ? XSSFITestDataProvider.instance : HSSFITestDataProvider.instance;
  2690. try (Workbook wb = instance.createWorkbook()) {
  2691. Sheet sheet = wb.createSheet("new sheet");
  2692. sheet.setActiveCell(new CellAddress("E11"));
  2693. assertEquals("E11", sheet.getActiveCell().formatAsString());
  2694. try (Workbook wbBack = instance.writeOutAndReadBack(wb)) {
  2695. sheet = wbBack.getSheetAt(0);
  2696. assertEquals("E11", sheet.getActiveCell().formatAsString());
  2697. }
  2698. }
  2699. }
  2700. @Test
  2701. void testBug54084Unicode() throws IOException {
  2702. // sample XLSX with the same text-contents as the text-file above
  2703. try (XSSFWorkbook wb = openSampleWorkbook("54084 - Greek - beyond BMP.xlsx")) {
  2704. verifyBug54084Unicode(wb);
  2705. //XSSFTestDataSamples.writeOut(wb, "bug 54084 for manual review");
  2706. // now write the file and read it back in
  2707. try (XSSFWorkbook wbWritten = writeOutAndReadBack(wb)) {
  2708. verifyBug54084Unicode(wbWritten);
  2709. }
  2710. // finally also write it out via the streaming interface and verify that we still can read it back in
  2711. try (SXSSFWorkbook swb = new SXSSFWorkbook(wb);
  2712. Workbook wbStreamingWritten = SXSSFITestDataProvider.instance.writeOutAndReadBack(swb)) {
  2713. verifyBug54084Unicode(wbStreamingWritten);
  2714. }
  2715. }
  2716. }
  2717. private void verifyBug54084Unicode(Workbook wb) {
  2718. // expected data is stored in UTF-8 in a text-file
  2719. byte[] data = HSSFTestDataSamples.getTestDataFileContent("54084 - Greek - beyond BMP.txt");
  2720. String testData = new String(data, StandardCharsets.UTF_8).trim();
  2721. Sheet sheet = wb.getSheetAt(0);
  2722. Row row = sheet.getRow(0);
  2723. Cell cell = row.getCell(0);
  2724. String value = cell.getStringCellValue();
  2725. //System.out.println(value);
  2726. assertEquals(testData, value, "The data in the text-file should exactly match the data that we read from the workbook");
  2727. }
  2728. @Test
  2729. void bug63371() throws IOException {
  2730. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  2731. XSSFSheet sheet = wb.createSheet();
  2732. CellRangeAddress region = new CellRangeAddress(1, 1, 1, 2);
  2733. assertEquals(0, sheet.addMergedRegion(region));
  2734. final CTMergeCells ctMergeCells = sheet.getCTWorksheet().getMergeCells();
  2735. assertEquals(1, sheet.getMergedRegions().size());
  2736. assertEquals(1, sheet.getNumMergedRegions());
  2737. assertEquals(1, ctMergeCells.getCount());
  2738. assertEquals(1, ctMergeCells.getMergeCellList().size());
  2739. }
  2740. }
  2741. @Test
  2742. void bug60397() throws IOException {
  2743. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  2744. XSSFSheet sheet = wb.createSheet();
  2745. CellRangeAddress region = new CellRangeAddress(1, 1, 1, 2);
  2746. assertEquals(0, sheet.addMergedRegion(region));
  2747. List<CellRangeAddress> ranges = sheet.getMergedRegions();
  2748. int numMergedRegions = sheet.getNumMergedRegions();
  2749. CTWorksheet ctSheet = sheet.getCTWorksheet();
  2750. CTMergeCells ctMergeCells = ctSheet.getMergeCells();
  2751. List<CTMergeCell> ctMergeCellList = ctMergeCells.getMergeCellList();
  2752. long ctMergeCellCount = ctMergeCells.getCount();
  2753. int ctMergeCellListSize = ctMergeCellList.size();
  2754. assertEquals(1, ranges.size());
  2755. assertEquals(1, numMergedRegions);
  2756. assertEquals(1, ctMergeCellCount);
  2757. assertEquals(1, ctMergeCellListSize);
  2758. CellRangeAddress region2 = new CellRangeAddress(1, 2, 4, 6);
  2759. assertEquals(1, sheet.addMergedRegion(region2));
  2760. ranges = sheet.getMergedRegions();
  2761. numMergedRegions = sheet.getNumMergedRegions();
  2762. ctSheet = sheet.getCTWorksheet();
  2763. ctMergeCells = ctSheet.getMergeCells();
  2764. ctMergeCellList = ctMergeCells.getMergeCellList();
  2765. ctMergeCellCount = ctMergeCells.getCount();
  2766. ctMergeCellListSize = ctMergeCellList.size();
  2767. assertEquals(2, ranges.size());
  2768. assertEquals(2, numMergedRegions);
  2769. assertEquals(2, ctMergeCellCount);
  2770. assertEquals(2, ctMergeCellListSize);
  2771. }
  2772. }
  2773. @Test
  2774. void testBug63509() throws IOException {
  2775. try (XSSFWorkbook workbook = new XSSFWorkbook()) {
  2776. XSSFSheet sheet = workbook.createSheet("sheet1");
  2777. Row row = sheet.createRow(0);
  2778. Cell cell = row.createCell(0);
  2779. cell.setCellValue("1000");
  2780. // This causes the error
  2781. sheet.addIgnoredErrors(new CellReference(cell), IgnoredErrorType.NUMBER_STORED_AS_TEXT);
  2782. // Workaround
  2783. // sheet.addIgnoredErrors(new CellReference(cell.getRowIndex(), cell.getColumnIndex(), false, false),
  2784. // IgnoredErrorType.NUMBER_STORED_AS_TEXT);
  2785. String sqref = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(0).getSqref().get(0).toString();
  2786. assertEquals("A1", sqref);
  2787. }
  2788. }
  2789. @Test
  2790. void test64045() {
  2791. File file = XSSFTestDataSamples.getSampleFile("xlsx-corrupted.xlsx");
  2792. assertThrows(POIXMLException.class, () -> new XSSFWorkbook(file), "Should catch exception as the file is corrupted");
  2793. }
  2794. @Test
  2795. void test58896WithFile() throws IOException {
  2796. try (Workbook wb = openSampleWorkbook("58896.xlsx")) {
  2797. Sheet sheet = wb.getSheetAt(0);
  2798. Instant start = now();
  2799. LOG.atInfo().log("Autosizing columns...");
  2800. for (int i = 0; i < 3; ++i) {
  2801. LOG.atInfo().log("Autosize {} - {}", box(i), between(start, now()));
  2802. sheet.autoSizeColumn(i);
  2803. }
  2804. for (int i = 0; i < 69 - 35 + 1; ++i)
  2805. for (int j = 0; j < 8; ++j) {
  2806. int col = 3 + 2 + i * (8 + 2) + j;
  2807. LOG.atInfo().log("Autosize {} - {}", box(col), between(start, now()));
  2808. sheet.autoSizeColumn(col);
  2809. }
  2810. LOG.atInfo().log(between(start, now()));
  2811. assertTrue(between(start, now()).getSeconds() < 25,
  2812. "Had start: " + start + ", now: " + now() +
  2813. ", diff: " + Duration.between(start, now()).getSeconds());
  2814. }
  2815. }
  2816. @Test
  2817. void testBug63845() throws IOException {
  2818. try (Workbook wb = new XSSFWorkbook()) {
  2819. Sheet sheet = wb.createSheet();
  2820. Row row = sheet.createRow(0);
  2821. Cell cell = row.createCell(0, CellType.FORMULA);
  2822. cell.setCellFormula("SUM(B1:E1)");
  2823. assertNull(((XSSFCell) cell).getCTCell().getV(),
  2824. "Element 'v' should not be set for formulas unless the value was calculated");
  2825. try (Workbook wbBack = writeOutAndReadBack(wb)) {
  2826. Cell cellBack = wbBack.getSheetAt(0).getRow(0).getCell(0);
  2827. assertNull(((XSSFCell) cellBack).getCTCell().getV(),
  2828. "Element 'v' should not be set for formulas unless the value was calculated");
  2829. assertNotNull(((XSSFCell) cellBack).getCTCell().getF(),
  2830. "Formula should be set internally now");
  2831. wbBack.getCreationHelper().createFormulaEvaluator().evaluateInCell(cellBack);
  2832. assertEquals("0.0", ((XSSFCell) cellBack).getCTCell().getV(),
  2833. "Element 'v' should be set now as the formula was calculated manually");
  2834. cellBack.setCellValue("123");
  2835. assertEquals("123", cellBack.getStringCellValue(),
  2836. "String value should be set now");
  2837. assertNull(((XSSFCell) cellBack).getCTCell().getF(), "No formula should be set any more");
  2838. }
  2839. }
  2840. }
  2841. @Test
  2842. void testBug63845_2() throws IOException {
  2843. try (Workbook wb = new XSSFWorkbook()) {
  2844. Sheet sheet = wb.createSheet("test");
  2845. Row row = sheet.createRow(0);
  2846. row.createCell(0).setCellValue(2);
  2847. row.createCell(1).setCellValue(5);
  2848. row.createCell(2).setCellFormula("A1+B1");
  2849. try (Workbook wbBack = writeOutAndReadBack(wb)) {
  2850. Cell cellBack = wbBack.getSheetAt(0).getRow(0).getCell(2);
  2851. assertNull(((XSSFCell) cellBack).getCTCell().getV(),
  2852. "Element 'v' should not be set for formulas unless the value was calculated");
  2853. wbBack.getCreationHelper().createFormulaEvaluator().evaluateInCell(cellBack);
  2854. assertEquals("7.0", ((XSSFCell) cellBack).getCTCell().getV(),
  2855. "Element 'v' should be set now as the formula was calculated manually");
  2856. }
  2857. }
  2858. }
  2859. @Test
  2860. public void testBug63339() throws IOException {
  2861. try (Workbook wb = new XSSFWorkbook()) {
  2862. Sheet sheet = wb.createSheet();
  2863. Row row = sheet.createRow(0);
  2864. Cell cell = row.createCell(0, CellType.FORMULA);
  2865. cell.setCellFormula("SUM(B1:E1)");
  2866. assertNotNull(((XSSFCell) cell).getCTCell().getF(),
  2867. "Element 'f' should contain the formula now");
  2868. // this will actually set the "cached" value of the Formula
  2869. // you will need to use setCellType() to change the cell to
  2870. // a different type of value
  2871. cell.setCellValue(34.5);
  2872. assertNotNull(((XSSFCell) cell).getCTCell().getF(),
  2873. "Element 'f' should not be set now");
  2874. assertEquals("34.5", ((XSSFCell) cell).getCTCell().getV(),
  2875. "Element 'v' should contain the string now");
  2876. try (Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb)) {
  2877. Cell cellBack = wbBack.getSheetAt(0).getRow(0).getCell(0);
  2878. assertNotNull(((XSSFCell) cellBack).getCTCell().getF(),
  2879. "Element 'f' should not be set now");
  2880. assertEquals("34.5", ((XSSFCell) cellBack).getCTCell().getV(),
  2881. "Element 'v' should contain the string now");
  2882. }
  2883. }
  2884. }
  2885. @Test
  2886. void testBug64508() throws IOException {
  2887. try (Workbook wb = openSampleWorkbook("64508.xlsx")) {
  2888. int activeSheet = wb.getActiveSheetIndex();
  2889. Sheet sheet1 = wb.getSheetAt(activeSheet);
  2890. Row row = sheet1.getRow(1);
  2891. CellReference aCellReference = new CellReference("E2");
  2892. Cell aCell = row.getCell(aCellReference.getCol());
  2893. assertEquals(CellType.STRING, aCell.getCellType());
  2894. assertEquals("", aCell.getStringCellValue());
  2895. }
  2896. }
  2897. @Test
  2898. void testBug64667() throws IOException {
  2899. //test that an NPE isn't thrown on opening
  2900. try (Workbook wb = openSampleWorkbook("64667.xlsx")) {
  2901. int activeSheet = wb.getActiveSheetIndex();
  2902. assertEquals(0, activeSheet);
  2903. assertNotNull(wb.getSheetAt(activeSheet));
  2904. }
  2905. }
  2906. @Test
  2907. @Tag("scratchpad.ignore")
  2908. void testXLSXinPPT() throws Exception {
  2909. assumeFalse(Boolean.getBoolean("scratchpad.ignore"));
  2910. try (SlideShow<?,?> ppt = SlideShowFactory.create(
  2911. POIDataSamples.getSlideShowInstance().openResourceAsStream("testPPT_oleWorkbook.ppt"))) {
  2912. Slide<?, ?> slide = ppt.getSlides().get(1);
  2913. ObjectShape<?,?> oleShape = (ObjectShape<?,?>)slide.getShapes().get(2);
  2914. org.apache.poi.sl.usermodel.ObjectData data = oleShape.getObjectData();
  2915. assertNull(data.getFileName());
  2916. // Will be OOXML wrapped in OLE2, not directly SpreadSheet
  2917. POIFSFileSystem fs = new POIFSFileSystem(data.getInputStream());
  2918. assertTrue(fs.getRoot().hasEntry(OOXML_PACKAGE));
  2919. assertFalse(fs.getRoot().hasEntry("Workbook"));
  2920. // Can fetch Package to get OOXML
  2921. DirectoryNode root = fs.getRoot();
  2922. DocumentEntry docEntry = (DocumentEntry) root.getEntry(OOXML_PACKAGE);
  2923. try (DocumentInputStream dis = new DocumentInputStream(docEntry);
  2924. OPCPackage pkg = OPCPackage.open(dis);
  2925. XSSFWorkbook wb = new XSSFWorkbook(pkg)) {
  2926. assertEquals(1, wb.getNumberOfSheets());
  2927. }
  2928. // Via the XSSF Factory
  2929. XSSFWorkbookFactory xssfFactory = new XSSFWorkbookFactory();
  2930. try (XSSFWorkbook wb = xssfFactory.create(fs.getRoot(), null)) {
  2931. assertEquals(1, wb.getNumberOfSheets());
  2932. }
  2933. // Or can open via the normal Factory, as stream or OLE2
  2934. try (Workbook wb = WorkbookFactory.create(fs)) {
  2935. assertEquals(1, wb.getNumberOfSheets());
  2936. }
  2937. try (Workbook wb = WorkbookFactory.create(data.getInputStream())) {
  2938. assertEquals(1, wb.getNumberOfSheets());
  2939. }
  2940. }
  2941. }
  2942. @Test
  2943. void test64986() throws IOException {
  2944. try (XSSFWorkbook w = new XSSFWorkbook()) {
  2945. XSSFSheet s = w.createSheet();
  2946. XSSFRow r = s.createRow(0);
  2947. XSSFCell c = r.createCell(0);
  2948. c.setCellFormula("MATCH(\"VAL\",B1:B11,)");
  2949. FormulaEvaluator evaluator = w.getCreationHelper().createFormulaEvaluator();
  2950. CellValue value = evaluator.evaluate(c);
  2951. assertEquals(CellType.ERROR, value.getCellType());
  2952. assertEquals(ErrorEval.NA.getErrorCode(), value.getErrorValue());
  2953. // put a value in place so the match should find something
  2954. Cell val = r.createCell(1);
  2955. val.setCellValue("VAL");
  2956. // clear and check that now we find a match
  2957. evaluator.clearAllCachedResultValues();
  2958. value = evaluator.evaluate(c);
  2959. assertEquals(CellType.NUMERIC, value.getCellType());
  2960. assertEquals(1, value.getNumberValue(), 0.01);
  2961. }
  2962. }
  2963. @Test
  2964. void test64750() throws IOException {
  2965. try (Workbook wb = openSampleWorkbook("64750.xlsx")) {
  2966. Sheet sheet = wb.getSheet("Sheet1");
  2967. assertEquals(1, sheet.getDataValidations().size());
  2968. }
  2969. }
  2970. @Test
  2971. void test64450() throws IOException {
  2972. try (Workbook wb = openSampleWorkbook("64450.xlsx")) {
  2973. assertNotNull(wb);
  2974. }
  2975. }
  2976. @Test
  2977. void test64494() throws IOException {
  2978. try (Workbook wb = new XSSFWorkbook()) {
  2979. CellStyle styleRight = wb.createCellStyle();
  2980. CellStyle styleLeft = wb.createCellStyle();
  2981. styleRight.setAlignment(HorizontalAlignment.RIGHT);
  2982. //styleRight.setBorderBottom(BorderStyle.DASH_DOT);
  2983. styleLeft.setAlignment(HorizontalAlignment.LEFT);
  2984. //styleLeft.setBorderRight(BorderStyle.MEDIUM);
  2985. assertEquals(HorizontalAlignment.RIGHT, styleRight.getAlignment());
  2986. assertEquals(HorizontalAlignment.LEFT, styleLeft.getAlignment());
  2987. Sheet sheet = wb.createSheet("test");
  2988. Row row = sheet.createRow(0);
  2989. Cell cellRight = row.createCell(0);
  2990. cellRight.setCellValue("R");
  2991. cellRight.setCellStyle(styleRight);
  2992. Cell cellLeft = row.createCell(1);
  2993. cellLeft.setCellValue("L");
  2994. cellLeft.setCellStyle(styleLeft);
  2995. assertEquals(HorizontalAlignment.RIGHT, cellRight.getCellStyle().getAlignment());
  2996. assertEquals(HorizontalAlignment.LEFT, cellLeft.getCellStyle().getAlignment());
  2997. }
  2998. }
  2999. @Test
  3000. void test65464() throws IOException {
  3001. try (XSSFWorkbook wb = openSampleWorkbook("bug65464.xlsx")) {
  3002. XSSFSheet sheet = wb.getSheet("SheetWithSharedFormula");
  3003. XSSFCell v15 = sheet.getRow(14).getCell(21);
  3004. XSSFCell v16 = sheet.getRow(15).getCell(21);
  3005. XSSFCell v17 = sheet.getRow(16).getCell(21);
  3006. assertEquals("U15/R15", v15.getCellFormula());
  3007. assertSame(STCellFormulaType.SHARED, v15.getCTCell().getF().getT());
  3008. assertEquals("U16/R16", v16.getCellFormula());
  3009. assertSame(STCellFormulaType.NORMAL, v16.getCTCell().getF().getT()); //anomaly in original file
  3010. assertEquals("U17/R17", v17.getCellFormula());
  3011. assertSame(STCellFormulaType.SHARED, v17.getCTCell().getF().getT());
  3012. int calcChainSize = wb.getCalculationChain().getCTCalcChain().sizeOfCArray();
  3013. v15.removeFormula();
  3014. assertEquals(CellType.NUMERIC, v15.getCellType(), "V15 is no longer a function");
  3015. assertNull(v15.getCTCell().getF(), "V15 xmlbeans function removed");
  3016. assertEquals("U16/R16", v16.getCellFormula());
  3017. assertSame(STCellFormulaType.NORMAL, v16.getCTCell().getF().getT());
  3018. assertEquals("U17/R17", v17.getCellFormula());
  3019. assertSame(STCellFormulaType.SHARED, v17.getCTCell().getF().getT());
  3020. assertEquals(calcChainSize - 1, wb.getCalculationChain().getCTCalcChain().sizeOfCArray());
  3021. }
  3022. }
  3023. @Test
  3024. void testSetBlankOnNestedSharedFormulas() throws IOException {
  3025. try (XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("testSharedFormulasSetBlank.xlsx")) {
  3026. XSSFSheet s1 = wb1.getSheetAt(0);
  3027. assertNotNull(s1);
  3028. Iterator<Row> rowIterator = s1.rowIterator();
  3029. int count = 0;
  3030. StringBuilder sb = new StringBuilder();
  3031. while (rowIterator.hasNext()) {
  3032. Row row = rowIterator.next();
  3033. Iterator<Cell> cellIterator = row.cellIterator();
  3034. while (cellIterator.hasNext()) {
  3035. Cell cell = cellIterator.next();
  3036. // the toString is needed to exhibit the broken state
  3037. sb.append(cell.toString()).append(",");
  3038. count++;
  3039. // breaks the sheet state
  3040. cell.setBlank();
  3041. }
  3042. }
  3043. assertEquals(10, count);
  3044. assertEquals("2-1,2-1,1+2,2-1,2-1,3+3,3+3,3+3,2-1,2-1,", sb.toString());
  3045. }
  3046. }
  3047. @Test
  3048. void testBug65306() throws IOException {
  3049. try (XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("bug65306.xlsx")) {
  3050. XSSFSheet sheet = wb1.getSheetAt(0);
  3051. assertNotNull(sheet);
  3052. XSSFCell a1 = sheet.getRow(0).getCell(0);
  3053. XSSFCell b1 = sheet.getRow(0).getCell(1);
  3054. XSSFCell a2 = sheet.getRow(1).getCell(0);
  3055. XSSFCell b2 = sheet.getRow(1).getCell(1);
  3056. assertEquals(1.0, a1.getNumericCellValue());
  3057. assertEquals(2.0, a2.getNumericCellValue());
  3058. assertEquals("$A$1+3*$A$2", b1.getCellFormula());
  3059. assertEquals("$A$1+3*$A$2", b2.getCellFormula());
  3060. sheet.shiftRows(1, 1, -1);
  3061. assertNull(sheet.getRow(1), "row 2 was removed?");
  3062. a1 = sheet.getRow(0).getCell(0);
  3063. b1 = sheet.getRow(0).getCell(1);
  3064. assertEquals(2.0, a1.getNumericCellValue());
  3065. assertEquals("#REF!+3*$A$1", b1.getCellFormula());
  3066. }
  3067. }
  3068. @Test
  3069. void testBug65452() throws IOException {
  3070. File file = XSSFTestDataSamples.getSampleFile("workbook.xml");
  3071. try (FileInputStream fis = new FileInputStream(file)) {
  3072. IOException ie = assertThrows(IOException.class, () -> WorkbookFactory.create(fis));
  3073. assertEquals("Can't open workbook - unsupported file type: XML", ie.getMessage());
  3074. }
  3075. IOException ie = assertThrows(IOException.class, () -> WorkbookFactory.create(file));
  3076. assertEquals("Can't open workbook - unsupported file type: XML", ie.getMessage());
  3077. }
  3078. @Test
  3079. void testBug62021() throws IOException {
  3080. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  3081. XSSFFormulaEvaluator fe = new XSSFFormulaEvaluator(wb);
  3082. XSSFSheet sheet = wb.createSheet("testSheet");
  3083. LocalDateTime ldt = LocalDateTime.parse("2021-10-15T12:00:00");
  3084. addRow(sheet, 0, ldt);
  3085. XSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(100);
  3086. assertDouble(fe, cell, "A1+1", DateUtil.getExcelDate(ldt) + 1);
  3087. LocalDateTime expected = ldt.plusMinutes(90);
  3088. assertDouble(fe, cell, "A1+\"1:30\"", DateUtil.getExcelDate(expected));
  3089. }
  3090. }
  3091. @Test
  3092. void testBug51037() throws IOException {
  3093. try (XSSFWorkbook wb = new XSSFWorkbook()) {
  3094. XSSFCellStyle blueStyle = wb.createCellStyle();
  3095. blueStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex());
  3096. blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  3097. XSSFCellStyle pinkStyle = wb.createCellStyle();
  3098. pinkStyle.setFillForegroundColor(IndexedColors.PINK.getIndex());
  3099. pinkStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  3100. Sheet s1 = wb.createSheet("Pretty columns");
  3101. s1.setDefaultColumnStyle(4, blueStyle);
  3102. s1.setDefaultColumnStyle(6, pinkStyle);
  3103. Row r3 = s1.createRow(3);
  3104. r3.createCell(0).setCellValue("The");
  3105. r3.createCell(1).setCellValue("quick");
  3106. r3.createCell(2).setCellValue("brown");
  3107. r3.createCell(3).setCellValue("fox");
  3108. r3.createCell(4).setCellValue("jumps");
  3109. r3.createCell(5).setCellValue("over");
  3110. r3.createCell(6).setCellValue("the");
  3111. r3.createCell(7).setCellValue("lazy");
  3112. r3.createCell(8).setCellValue("dog");
  3113. Row r7 = s1.createRow(7);
  3114. r7.createCell(1).setCellStyle(pinkStyle);
  3115. r7.createCell(8).setCellStyle(blueStyle);
  3116. assertEquals(blueStyle.getIndex(), r3.getCell(4).getCellStyle().getIndex());
  3117. assertEquals(pinkStyle.getIndex(), r3.getCell(6).getCellStyle().getIndex());
  3118. try (UnsynchronizedByteArrayOutputStream bos = UnsynchronizedByteArrayOutputStream.builder().get()) {
  3119. wb.write(bos);
  3120. try (XSSFWorkbook wb2 = new XSSFWorkbook(bos.toInputStream())) {
  3121. XSSFSheet wb2Sheet = wb2.getSheetAt(0);
  3122. XSSFRow wb2R3 = wb2Sheet.getRow(3);
  3123. assertEquals(blueStyle.getIndex(), wb2R3.getCell(4).getCellStyle().getIndex());
  3124. assertEquals(pinkStyle.getIndex(), wb2R3.getCell(6).getCellStyle().getIndex());
  3125. }
  3126. }
  3127. }
  3128. }
  3129. @Test
  3130. void testBug66181() throws IOException {
  3131. File file = XSSFTestDataSamples.getSampleFile("ValueFunctionOfBlank.xlsx");
  3132. try (
  3133. FileInputStream fis = new FileInputStream(file);
  3134. Workbook workbook = WorkbookFactory.create(fis)
  3135. ) {
  3136. Sheet sheet = workbook.getSheetAt(0);
  3137. Row row = sheet.getRow(0);
  3138. Cell a1 = row.getCell(0);
  3139. assertEquals(CellType.FORMULA, a1.getCellType());
  3140. assertEquals(CellType.ERROR, a1.getCachedFormulaResultType());
  3141. FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
  3142. CellValue cv1 = evaluator.evaluate(a1);
  3143. assertEquals(CellType.ERROR, cv1.getCellType());
  3144. assertEquals(ErrorEval.VALUE_INVALID.getErrorCode(), cv1.getErrorValue());
  3145. }
  3146. }
  3147. @Test
  3148. void testBug66216() throws IOException {
  3149. File file = XSSFTestDataSamples.getSampleFile("ExcelPivotTableSample.xlsx");
  3150. try (
  3151. FileInputStream fis = new FileInputStream(file);
  3152. XSSFWorkbook workbook = new XSSFWorkbook(fis)
  3153. ) {
  3154. for (XSSFPivotTable pivotTable : workbook.getPivotTables()) {
  3155. assertNotNull(pivotTable.getCTPivotTableDefinition());
  3156. assertNotNull(pivotTable.getPivotCacheDefinition());
  3157. assertEquals(1, pivotTable.getRelations().size());
  3158. assertInstanceOf(XSSFPivotCacheDefinition.class, pivotTable.getRelations().get(0));
  3159. assertEquals("rId1", pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getId());
  3160. assertEquals(3,
  3161. pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getRecordCount());
  3162. }
  3163. }
  3164. }
  3165. @Test
  3166. void testTika3163() throws Exception {
  3167. File file = XSSFTestDataSamples.getSampleFile("CVLKRA-KYC_Download_File_Structure_V3.1.xlsx");
  3168. try (
  3169. FileInputStream fis = new FileInputStream(file);
  3170. XSSFWorkbook workbook = new XSSFWorkbook(fis)
  3171. ) {
  3172. assertNotNull(workbook.getStylesSource());
  3173. assertEquals(23, workbook.getStylesSource().getFonts().size());
  3174. }
  3175. try (OPCPackage pkg = OPCPackage.open(file, PackageAccess.READ)) {
  3176. XSSFReader reader = new XSSFReader(pkg);
  3177. StylesTable stylesTable = reader.getStylesTable();
  3178. assertNotNull(stylesTable);
  3179. assertEquals(23, stylesTable.getFonts().size());
  3180. }
  3181. }
  3182. private static final String secretKey = "foobaa";
  3183. @Test
  3184. void testBug66436() throws IOException, InvalidFormatException, GeneralSecurityException {
  3185. final File temp_excel_poi = TempFile.createTempFile("temp_excel_poi", ".xlsx");
  3186. final File temp_excel_poi_encrypt = TempFile.createTempFile("temp_excel_poi_encrypt", ".xlsx");
  3187. final File temp_excel_poi_decrypt = TempFile.createTempFile("temp_excel_poi_decrypt", ".xlsx");
  3188. /* create new excel by poi */
  3189. try (XSSFWorkbook workbook = new XSSFWorkbook();
  3190. FileOutputStream foss = new FileOutputStream(temp_excel_poi)) {
  3191. XSSFSheet sheet = workbook.createSheet();
  3192. XSSFRow row = sheet.createRow(0);
  3193. XSSFCell cell = row.createCell(0);
  3194. cell.setCellValue("Hello Apache POI");
  3195. workbook.write(foss);
  3196. }
  3197. // read bytes of workbook before
  3198. UnsynchronizedByteArrayOutputStream bosOrig = UnsynchronizedByteArrayOutputStream.builder().get();
  3199. try (FileInputStream fis = new FileInputStream(temp_excel_poi)) {
  3200. IOUtils.copy(fis, bosOrig);
  3201. }
  3202. // for the encrypted bytes
  3203. UnsynchronizedByteArrayOutputStream bosEnc = UnsynchronizedByteArrayOutputStream.builder().get();
  3204. /* encrypt excel by poi */
  3205. try (POIFSFileSystem fs = new POIFSFileSystem()) {
  3206. EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
  3207. Encryptor enc = info.getEncryptor();
  3208. enc.confirmPassword(secretKey);
  3209. // Read in an existing OOXML file and write to encrypted output stream
  3210. // don't forget to close the output stream otherwise the padding bytes aren't added
  3211. try (OPCPackage opc = OPCPackage.open(new FileInputStream(temp_excel_poi));
  3212. OutputStream os = enc.getDataStream(fs)) {
  3213. opc.save(os);
  3214. }
  3215. fs.writeFilesystem(bosEnc);
  3216. bosEnc.close();
  3217. // Write out the encrypted version
  3218. try (FileOutputStream fos = new FileOutputStream(temp_excel_poi_encrypt)) {
  3219. IOUtils.copy(new ByteArrayInputStream(bosEnc.toByteArray()), fos);
  3220. }
  3221. }
  3222. // for the decrypted bytes
  3223. UnsynchronizedByteArrayOutputStream bosDec = UnsynchronizedByteArrayOutputStream.builder().get();
  3224. /* decrypt excel by poi */
  3225. try (POIFSFileSystem fileSystem = new POIFSFileSystem(temp_excel_poi_encrypt)) {
  3226. EncryptionInfo info = new EncryptionInfo(fileSystem);
  3227. Decryptor d = Decryptor.getInstance(info);
  3228. if (!d.verifyPassword(secretKey)) {
  3229. throw new RuntimeException("Unable to process: document is encrypted");
  3230. }
  3231. // parse dataStream
  3232. try (InputStream dataStream = d.getDataStream(fileSystem)) {
  3233. IOUtils.copy(dataStream, bosDec);
  3234. }
  3235. try (FileOutputStream fos = new FileOutputStream(temp_excel_poi_decrypt)) {
  3236. IOUtils.copy(new ByteArrayInputStream(bosDec.toByteArray()), fos);
  3237. }
  3238. }
  3239. // input-data and resulting decrypted data should be equal
  3240. /* This is a flaky assertion, maybe there is a timestamp in the files which can differ
  3241. in the two byte-arrays. Other tests verify this for encryption/decryption anyway
  3242. assertArrayEquals(bosOrig.toByteArray(), bosDec.toByteArray(),
  3243. "Having " + bosOrig.size() + " bytes");*/
  3244. // also make sure the original and the resulting decrypted
  3245. // file can be read, i.e. is a valid Zip
  3246. readByCommonsCompress(temp_excel_poi);
  3247. readByCommonsCompress(temp_excel_poi_decrypt);
  3248. }
  3249. @Test
  3250. void getMacrosheet() throws IOException, InvalidFormatException {
  3251. try (XSSFWorkbook wb = openSampleWorkbook("xlmmacro.xlsm")) {
  3252. PackageRelationshipCollection prc = wb.getPackagePart().getRelationships();
  3253. assertNotNull(prc);
  3254. assertEquals(6, prc.size());
  3255. PackageRelationshipCollection prc2 = prc.getRelationships(XSSFRelation.MACRO_SHEET_XML.getRelation());
  3256. assertNotNull(prc2);
  3257. assertEquals(1, prc2.size());
  3258. }
  3259. }
  3260. @Test
  3261. void testBug62181() throws Exception {
  3262. try (XSSFWorkbook wb = openSampleWorkbook("bug62181.xlsx")) {
  3263. SharedStringsTable sst = wb.getSharedStringSource();
  3264. assertNotNull(sst);
  3265. assertEquals(0, sst.getCount());
  3266. }
  3267. }
  3268. @Test
  3269. void testBug66675() throws Exception {
  3270. try (XSSFWorkbook wb = openSampleWorkbook("bug66675.xlsx")) {
  3271. POIXMLProperties.CoreProperties coreProperties = wb.getProperties().getCoreProperties();
  3272. assertNotNull(coreProperties);
  3273. wb.removeSheetAt(0);
  3274. try (UnsynchronizedByteArrayOutputStream bos = UnsynchronizedByteArrayOutputStream.builder().get()) {
  3275. wb.write(bos);
  3276. try (XSSFWorkbook wb2 = new XSSFWorkbook(bos.toInputStream())) {
  3277. XSSFSheet sheet = wb2.getSheetAt(0);
  3278. assertNotNull(sheet);
  3279. assertNotNull(wb2.getProperties().getCoreProperties());
  3280. }
  3281. }
  3282. }
  3283. }
  3284. private static void readByCommonsCompress(File temp_excel_poi) throws IOException {
  3285. /* read by commons-compress*/
  3286. try (ZipFile zipFile = new ZipFile(temp_excel_poi)) {
  3287. ZipArchiveEntry entry = zipFile.getEntry("xl/workbook.xml");
  3288. InputStream inputStream = zipFile.getInputStream(entry);
  3289. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
  3290. while (true) {
  3291. String line = bufferedReader.readLine();
  3292. if (line == null) {
  3293. break;
  3294. }
  3295. //System.out.println(line);
  3296. }
  3297. }
  3298. }
  3299. }