From 97afbf7087ff60637f75d57568b33c85a5474f81 Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Fri, 10 Feb 2012 08:26:45 +0000 Subject: [PATCH] Bugzilla 52576: support changing external file references in HSSFWorkbook git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1242701 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 2 + .../poi/hssf/model/InternalWorkbook.java | 14 ++++ .../org/apache/poi/hssf/model/LinkTable.java | 23 ++++++ .../apache/poi/hssf/record/SupBookRecord.java | 69 ++++++++++++++---- .../poi/hssf/usermodel/HSSFWorkbook.java | 13 +++- .../poi/hssf/record/TestSupBookRecord.java | 44 +++++++++++ .../apache/poi/hssf/usermodel/TestBugs.java | 18 +++-- .../TestExternalReferenceChange.java | 52 +++++++++++++ .../poi/ss/formula/TestMissingWorkbook.java | 2 - test-data/spreadsheet/49896.xls | Bin 0 -> 16896 bytes 10 files changed, 216 insertions(+), 21 deletions(-) create mode 100644 src/testcases/org/apache/poi/hssf/usermodel/TestExternalReferenceChange.java create mode 100644 test-data/spreadsheet/49896.xls diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index af3bbee4c..86f2696b3 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,8 @@ + 52576 - support changing external file references in HSSFWorkbook + 49896 - support external references in FormulaRenderer 52527 - avoid exception when matching shared formula records in HSSF 52568 - Added methods to set/get an XWPFRun's text color 52566 - Added methods to set/get vertical alignment and color in XWPFTableCell diff --git a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java index 93d37acc4..c1ec938cf 100644 --- a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java +++ b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java @@ -2457,4 +2457,18 @@ public final class InternalWorkbook { } return record; } + + + /** + * Changes an external referenced file to another file. + * A formular in Excel which refers a cell in another file is saved in two parts: + * The referenced file is stored in an reference table. the row/cell information is saved separate. + * This method invokation will only change the reference in the lookup-table itself. + * @param oldUrl The old URL to search for and which is to be replaced + * @param newUrl The URL replacement + * @return true if the oldUrl was found and replaced with newUrl. Otherwise false + */ + public boolean changeExternalReference(String oldUrl, String newUrl) { + return linkTable.changeExternalReference(oldUrl, newUrl); + } } diff --git a/src/java/org/apache/poi/hssf/model/LinkTable.java b/src/java/org/apache/poi/hssf/model/LinkTable.java index 732ab1480..9236a625b 100644 --- a/src/java/org/apache/poi/hssf/model/LinkTable.java +++ b/src/java/org/apache/poi/hssf/model/LinkTable.java @@ -552,4 +552,27 @@ final class LinkTable { private int findRefIndexFromExtBookIndex(int extBookIndex) { return _externSheetRecord.findRefIndexFromExtBookIndex(extBookIndex); } + + /** + * Changes an external referenced file to another file. + * A formular in Excel which refers a cell in another file is saved in two parts: + * The referenced file is stored in an reference table. the row/cell information is saved separate. + * This method invokation will only change the reference in the lookup-table itself. + * @param oldUrl The old URL to search for and which is to be replaced + * @param newUrl The URL replacement + * @return true if the oldUrl was found and replaced with newUrl. Otherwise false + */ + public boolean changeExternalReference(String oldUrl, String newUrl) { + for(ExternalBookBlock ex : _externalBookBlocks) { + SupBookRecord externalRecord = ex.getExternalBookRecord(); + if (externalRecord.isExternalReferences() + && externalRecord.getURL().equals(oldUrl)) { + + externalRecord.setURL(newUrl); + return true; + } + } + return false; + } + } diff --git a/src/java/org/apache/poi/hssf/record/SupBookRecord.java b/src/java/org/apache/poi/hssf/record/SupBookRecord.java index b8be5deab..29fa4d91c 100644 --- a/src/java/org/apache/poi/hssf/record/SupBookRecord.java +++ b/src/java/org/apache/poi/hssf/record/SupBookRecord.java @@ -18,6 +18,8 @@ package org.apache.poi.hssf.record; import org.apache.poi.util.LittleEndianOutput; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; import org.apache.poi.util.StringUtil; /** @@ -31,6 +33,8 @@ import org.apache.poi.util.StringUtil; */ public final class SupBookRecord extends StandardRecord { + private final static POILogger logger = POILogFactory.getLogger(SupBookRecord.class); + public final static short sid = 0x01AE; private static final short SMALL_RECORD_SIZE = 4; @@ -42,6 +46,15 @@ public final class SupBookRecord extends StandardRecord { private String[] field_3_sheet_names; private boolean _isAddInFunctions; + protected static final char CH_VOLUME = 1; + protected static final char CH_SAME_VOLUME = 2; + protected static final char CH_DOWN_DIR = 3; + protected static final char CH_UP_DIR = 4; + protected static final char CH_LONG_VOLUME = 5; + protected static final char CH_STARTUP_DIR = 6; + protected static final char CH_ALT_STARTUP_DIR = 7; + protected static final char CH_LIB_DIR = 8; + protected static final String PATH_SEPERATOR = System.getProperty("file.separator"); public static SupBookRecord createInternalReferences(short numberOfSheets) { return new SupBookRecord(false, numberOfSheets); @@ -192,21 +205,51 @@ public final class SupBookRecord extends StandardRecord { return encodedUrl; } private static String decodeFileName(String encodedUrl) { - return encodedUrl.substring(1); - // TODO the following special characters may appear in the rest of the string, and need to get interpreted - /* see "MICROSOFT OFFICE EXCEL 97-2007 BINARY FILE FORMAT SPECIFICATION" - chVolume 1 - chSameVolume 2 - chDownDir 3 - chUpDir 4 - chLongVolume 5 - chStartupDir 6 - chAltStartupDir 7 - chLibDir 8 - - */ + /* see "MICROSOFT OFFICE EXCEL 97-2007 BINARY FILE FORMAT SPECIFICATION" */ + StringBuilder sb = new StringBuilder(); + for(int i=1; iQ*4k*5%>i8Jw`um-8@9w>K@4eX$ zg2Hfi&V79MobUV2_x;Xy&pG$(Pk&N#^470U|CM;s3W>_;e3eu>=mxHtRjL-5feYTB z&gb)*D1ytk(i_MEuRzzCa9$KShFpP6pU06C$W_Q=kjEmALw+0bc;pGlfPmB>Peh)C zT#Gyzc?$AW8<{v^u5(Vop>{aG#omMLyx(wmCd{12(S*gl>TpjDxaXgNOd`s1NT2U4wT0M;N`NKyn3so4afQ(+C zp-=vIPwV6vXq6D9RYZ2gjdrC`FM1BOTP(Un)u<(EM=4=Qo7_jU21+sTRtPTtZtysqt2>pItwzY1XWk?emv!Yp`#&&994{i}yZ8bT$dkFMnsc=L&bBdJGH@ zzU@NIEp9%zC#!i-wccCG!_6vszBEcwWII)9G;PhS+ieYsuxlftOm6d2`&DnCh zV5D{V?1gPD%dY4_+Satq+=H~u)Yk`*>S7b*4vx6?>{-;)v*_T#H1YddTEbBLqp9y{0Cs$_AY}7!(=cMI-v|E@lYo8Oc_jQ$6!t9#xj_&*9J48&qrl4(h=?*uAh{_B-}gG z%3~7l9j@S%p-H%RxCB%NlW^~F4XF$!;oiXz*TDogetjp|8txsgU=%e8WD@QjE`yc9 zB-}fQH03Y}_l{W}lW^~xTON~e?_kz2dUNzjWpD?aRUVUY@60ZbNw|0Bl*c68J9Eop z67HROxuondDR9Ot?f_43Ghuctf?lqcaw(Wp!223X`TR)1 zJa#WVapFW?EGD*Mie{O|?hsCz-60AzNGWyAGEkkaNfl%l#=SI;6*`n`TPdqYD%rMD z7EQ^vm2&n-TPY{4w3jZ2#9)9KhZ67dSnvW=hy{<{sj;JjDP?)EX^4MH*-}j|ENDV2 zAlSIgb1X6u3+I@zC0pj03(ZyC-Rb_^;-iTTa+L25D;cr6{M)c3*CKPU4zdt=6+TaN zi~cyFgM)$30r6Nm^NZ(S%2)83QxJ%o!`TPL)Of`tOU2ZOh|%FgiK$3uPCfgKznF<$ zF|DOy=7xyT0Y-_bOlN-o(zE_zCV9oQm5ON$5yKD^#dHsbil;NrpZuf0m|Cxx^Gd}u zhlpX|vcx3dn?L{6U(95$m?foRk|APrC{nGdN@rgA-BbQzrcg{$IFl3>n~;o#ViR& znh7yW%0ODO^^^BJp~WzuAr)fUIbJb7NShrZ#)-6K>r*#<(qBxSSBwwR8bZW4k(O+I z;O95{i<#*alNdJw6+j2 zPNXGU|2=%fuQlWFO$#%%!h3U-=e>DOJ|6h46xnpm_xzd8Dl!G4yiCvaFm<8`i=LY| z_%oedWD5Lvna=Srbz(;3mhWEX&vZ_aDbV6&I^V<8i4c*&p3nO;om*rIY1UstX-+kZ51jhkU)N`9>9@B7>t(g)VXohWfN zk|0x#b8P{fM=Jr9*q+6Q9BdmfgYz!ox~p>C9g9rBr&xSwo;b07P=6dSH@(I-0 zkIfYWYV6x>ZH%In=D|2>G<#~q^W#ctxMfY2Mcg#E_Q2l0uKuoEcHp47C4C@wG;xue zRph*UHTGj2z`h&$zF+yD`=k!S=3Ai70pNkN4%_>5wgs;$v<=hhi?Ue&b-A0bF+CrX zi(s^@2dZ2Vuz5k4&1*b9bz?>7;&fL}Z~smca|Ms0(P~)sVkkuH_d?N~P*Bei6a>&= zX0AV^*%69yXr=?)RpDeL?9?gte1yImHkMSHj@Z7;A$ zrx!aKS0HSsahc*(cK>P&kPw$Tdi!^$d#wI{iAR}fh)W&H(YxXF9#;g27SLFTMRxSz zvP2~eH%`un{<1N>KR3{Y@Zt%~#ta1JjbO}{4ggaOEP6(x;wjc8?Dh^}@xlT;AT=oH zj`eO`4S~pwK>C2%+ecRH?p4?kgc=*Ox%AP*4tJHv7<3O-$w3FMa&VHPBx9Asj$mA& zD8^NNXGbu7XGbu7cPuhimI;=LH|@_U2fxoFbTU|PQcW&(u`|LmAi7*kLQxZaXKSMG zY)$kXBiGvpD`2YGZWSsjVE4^v^FU#quZ=ZEmJ^v z8X1egycH4#(2eXMo(W-F^Xyr=j+?7t}7LziaE50@*NlFKUsZD9U zIWbLccIajBArjBGVI${lj%TD_52zdX-Hk1>=tr@;jV>4%V<^LDUz6?LzXuCI`^>KX z95c638Mue`CnY7*0`Jz>DSEvwe&8DT&jn)$Nz!v}WzPccXY`9>bD^ zT#Ge&xLUdsQ;>0Cr76~Vg&c)?S&m1 zspVspxB_?MLXqRm+y~E{qvLSw!7c_~*Wk!K@dFCXnra-0Wq;>xrYbRLB?5?YekS7{_hD2yOV*&!@N(U|>5aMw_J*#GWfTJnBm-GV284{0 z0VP(O* zt5Q9NAj9~JuqJ`OGcgs}s*Mw#a=|CMru=Bof-i1QBLDwJ17ef$gjWdj9|0~2);uDre3_{K6>WCe^rdrWU2L}AbWEjzFbu=UKNSr~CLl9!G zh%a)|_!1ehIDzwNa6+MBdt@P%zz-hbbBxK0efZcJ;BF(Eg@>-OcvDh>TS$)&9*m^WDRCbHC=*$XG#yg=Rwx6?U)yP}-?(P|DzjtD8r4Tx zlQNis&UFw@JJ3&hmR7t>7B5?6912naI)lu%W(Rif<7{-Fs$Y&R4Mc`00t9=8_rITW z!LsPLO_@w@cUrs8Ot!SNngwwx;;in?WR_yi$n{ZpxLIl5yj1?S?8JLPd@H>s7BH-Z n@x7QK?vVGKu?+qL(-{@ZVZi?L-<&U=sr+(uJd-kSWcmLA0Uxq= literal 0 HcmV?d00001