From 946ea73ddb325a344607846ebf692ff4ccd78703 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 20 Jul 2012 22:35:53 +0100 Subject: [PATCH 01/30] Bugfixes to Chart Reader and Writer --- Classes/PHPExcel/Reader/Excel2007/Chart.php | 3 ++- Classes/PHPExcel/Shared/XMLWriter.php | 4 ++++ Classes/PHPExcel/Writer/Excel2007/Chart.php | 17 +++++++++++------ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index 3333c982..865fb3d7 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Chart.php +++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php @@ -64,7 +64,8 @@ class PHPExcel_Reader_Excel2007_Chart $namespacesChartMeta = $chartElements->getNamespaces(true); $chartElementsC = $chartElements->children($namespacesChartMeta['c']); - $XaxisLabel = $YaxisLabel = $legend = $title = null; + $XaxisLabel = $YaxisLabel = $legend = $title = NULL; + $dispBlanksAs = $plotVisOnly = NULL; foreach($chartElementsC as $chartElementKey => $chartElement) { switch ($chartElementKey) { diff --git a/Classes/PHPExcel/Shared/XMLWriter.php b/Classes/PHPExcel/Shared/XMLWriter.php index 18167762..2abf451a 100644 --- a/Classes/PHPExcel/Shared/XMLWriter.php +++ b/Classes/PHPExcel/Shared/XMLWriter.php @@ -114,6 +114,10 @@ class PHPExcel_Shared_XMLWriter extends XMLWriter { */ public function writeRawData($text) { + if (is_array($text)) { + $text = implode("\n",$text); + } + if (method_exists($this, 'writeRaw')) { return $this->writeRaw(htmlspecialchars($text)); } diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 705a4072..286e97c1 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -955,14 +955,19 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa $dataValues = $plotSeriesValues->getDataValues(); if (!empty($dataValues)) { - foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { - $objWriter->startElement('c:pt'); - $objWriter->writeAttribute('idx', $plotSeriesKey ); + if (!is_array($dataValues)) { + var_dump($dataValues); + } + if (is_array($dataValues)) { + foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey ); - $objWriter->startElement('c:v'); - $objWriter->writeRawData( $plotSeriesValue ); + $objWriter->startElement('c:v'); + $objWriter->writeRawData( $plotSeriesValue ); + $objWriter->endElement(); $objWriter->endElement(); - $objWriter->endElement(); + } } } From dd69a5a1341571430dee352e99a091a3e165ab4f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 20 Jul 2012 23:13:16 +0100 Subject: [PATCH 02/30] More chart bugfixing --- Classes/PHPExcel/Writer/Excel2007/Chart.php | 42 +++++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 286e97c1..3e5c350c 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -83,7 +83,12 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa $objWriter->writeAttribute('val', 0); $objWriter->endElement(); - $this->_writePlotArea($pChart->getPlotArea(), $pChart->getXAxisLabel(), $pChart->getYAxisLabel(), $objWriter); + $this->_writePlotArea($pChart->getPlotArea(), + $pChart->getXAxisLabel(), + $pChart->getYAxisLabel(), + $objWriter, + $pChart->getWorksheet() + ); $this->_writeLegend($pChart->getLegend(), $objWriter); @@ -217,7 +222,8 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Chart_Title $xAxisLabel = NULL, PHPExcel_Chart_Title $yAxisLabel = NULL, - $objWriter) + $objWriter, + PHPExcel_Worksheet $pSheet) { if (is_null($plotArea)) { return; @@ -252,7 +258,7 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa $objWriter->endElement(); } - $this->_writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType); + $this->_writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet); } } @@ -664,9 +670,17 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa * @param boolean &$catIsMultiLevelSeries Is category a multi-series category * @param boolean &$valIsMultiLevelSeries Is value set a multi-series set * @param string &$plotGroupingType Type of grouping for multi-series values + * @param PHPExcel_Worksheet $pSheet * @throws Exception */ - private function _writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType) + private function _writePlotGroup( $plotGroup, + $groupType, + $objWriter, + &$catIsMultiLevelSeries, + &$valIsMultiLevelSeries, + &$plotGroupingType, + PHPExcel_Worksheet $pSheet + ) { if (is_null($plotGroup)) { return; @@ -815,7 +829,7 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa $objWriter->startElement('c:cat'); } - $this->_writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str'); + $this->_writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet); $objWriter->endElement(); } @@ -830,7 +844,7 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa $objWriter->startElement('c:val'); } - $this->_writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num'); + $this->_writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet); $objWriter->endElement(); } @@ -885,9 +899,15 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param string $groupType Type of plot for dataseries * @param string $dataType Datatype of series values + * @param PHPExcel_Worksheet $pSheet * @throws Exception */ - private function _writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, $dataType='str') + private function _writePlotSeriesValues( $plotSeriesValues, + $objWriter, + $groupType, + $dataType='str', + PHPExcel_Worksheet $pSheet + ) { if (is_null($plotSeriesValues)) { return; @@ -956,7 +976,13 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa $dataValues = $plotSeriesValues->getDataValues(); if (!empty($dataValues)) { if (!is_array($dataValues)) { - var_dump($dataValues); + $dataValues = PHPExcel_Calculation_Functions::flattenArray( + PHPExcel_Calculation::getInstance() + ->calculateFormula('='.$dataValues, + NULL, + $pSheet->getCell('A1') + ) + ); } if (is_array($dataValues)) { foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { From 8bcf795e16412c26ea32dba09705990d6df1c67d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 20 Jul 2012 23:53:16 +0100 Subject: [PATCH 03/30] Chart writing bugfixes --- Classes/PHPExcel/Writer/Excel2007/Chart.php | 54 ++++++++++++------ Tests/templates/32readwriteChartColours1.xlsx | Bin 30668 -> 0 bytes Tests/templates/32readwriteChartLegends1.xlsx | Bin 36990 -> 0 bytes Tests/templates/32readwriteChartTypes1.xlsx | Bin 142966 -> 0 bytes .../templates/32readwriteColumnChart3D2.xlsx | Bin 45391 -> 0 bytes 5 files changed, 36 insertions(+), 18 deletions(-) delete mode 100644 Tests/templates/32readwriteChartColours1.xlsx delete mode 100644 Tests/templates/32readwriteChartLegends1.xlsx delete mode 100644 Tests/templates/32readwriteChartTypes1.xlsx delete mode 100644 Tests/templates/32readwriteColumnChart3D2.xlsx diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 3e5c350c..4a29a59c 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -849,7 +849,7 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa } if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $this->_writeBubbles($plotSeriesValues, $objWriter); + $this->_writeBubbles($plotSeriesValues, $objWriter, $pSheet); } $objWriter->endElement(); @@ -975,15 +975,17 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa $dataValues = $plotSeriesValues->getDataValues(); if (!empty($dataValues)) { - if (!is_array($dataValues)) { - $dataValues = PHPExcel_Calculation_Functions::flattenArray( - PHPExcel_Calculation::getInstance() - ->calculateFormula('='.$dataValues, - NULL, - $pSheet->getCell('A1') - ) - ); - } +// if (!is_array($dataValues)) { +// echo 'NOT AN ARRAY: '; +// var_dump($dataValues); +// $dataValues = PHPExcel_Calculation_Functions::flattenArray( +// PHPExcel_Calculation::getInstance() +// ->calculateFormula('='.$dataValues, +// NULL, +// $pSheet->getCell('A1') +// ) +// ); +// } if (is_array($dataValues)) { foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { $objWriter->startElement('c:pt'); @@ -1010,7 +1012,7 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @throws Exception */ - private function _writeBubbles($plotSeriesValues, $objWriter) + private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) { if (is_null($plotSeriesValues)) { return; @@ -1027,13 +1029,29 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount() ); $objWriter->endElement(); - foreach($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) { - $objWriter->startElement('c:pt'); - $objWriter->writeAttribute('idx', $plotSeriesKey ); - $objWriter->startElement('c:v'); - $objWriter->writeRawData( 1 ); - $objWriter->endElement(); - $objWriter->endElement(); + $dataValues = $plotSeriesValues->getDataValues(); + if (!empty($dataValues)) { +// if (!is_array($dataValues)) { +// echo 'NOT AN ARRAY: '; +// var_dump($dataValues); +// $dataValues = PHPExcel_Calculation_Functions::flattenArray( +// PHPExcel_Calculation::getInstance() +// ->calculateFormula('='.$dataValues, +// NULL, +// $pSheet->getCell('A1') +// ) +// ); +// } + if (is_array($dataValues)) { + foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey ); + $objWriter->startElement('c:v'); + $objWriter->writeRawData( 1 ); + $objWriter->endElement(); + $objWriter->endElement(); + } + } } $objWriter->endElement(); diff --git a/Tests/templates/32readwriteChartColours1.xlsx b/Tests/templates/32readwriteChartColours1.xlsx deleted file mode 100644 index 7449f3f59812a2cd20a1e05d68bfc2f010768d66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30668 zcmeFY1#=wDwk6tPmRc-}nVFfHnPo9EGcz;GB8zP?TFlJM%oa0P(#YRE@7??2oQd}X zW-6+)IxDLqD)(L+a_wwI88C1(03-k!000mHmSwKJ20#D+tmO#Jyg!~>Ou(P_KN3^qWFceI?GRq0@&_dY5 zA5cpXS#GTJ061T}T&7#7kj{?9wq$TL^6t#Lo-%Q4yO6yGA+j>3aZ{Vr0#WBKwpFR! zVh}Lj(n40!B#Wt6tVIxYYioaM@>ubRfDl{Lti_o5*ybI@;6|1?>Y0^17p6$y7wPLr zpqT-5j2JVPlCw@uizt0Xqh+1zI69H7V&71iJ2MJF7SU%x+j6R+;91@ z=NMaswCj>ym-+JA(f(Y*u{$A>ER1hC5v;Dr8yV0gDgkq7-6x=@*}>gRtw4j9{n3tS zO40BpJqh#9%XPD^D@RNEJl0L(s{28KCkX}X;g_2i167dTiWS(VK z$(9`RisK;w5xw6$soS05=*Sm}wVOtYL_9Zpg!ANLEC6ghJa=mAVvkQ@@HsxWnDM5n zn8tES>o2+CTkt%*S=>~~VZ$A=KGAZg>ZnTMk(0iDf@LrYZx zTq6egzE(=1S{5VkB`c50JawdeBVuz)v?1&`TtkhGO&fiWqLgf-rPs2$=xFTLls_a! ztau7&aMx!}#fgkcqlOkU$zRG$*HaGo!n*Jk>3A1^0K7!G}n z(&b|Wb5VK5+zv#{;L4}g%CdyVq=M0JbLNmoUWtvta>-Y974ANoI30;)BBv#{Z+W+( zoCSaX4y4bsD1YjhZQq}*Q_`h4pyXC0{>}QM|2Lk}G0ni{GHVpq| zDDL)7)<*XB)_DpP};e+5fYT_GAT_en#NHWzZJU_(n-(YlKZJl-Tl*Dgwfy zxe}Y~l<}w1txd&RSHtr3UB}IYM?YTXwGH#7D0ldIk5WPzW#DlP1C9ob2OqEAMj+v0 z)qJIUnSo%Co}*{2@1VM~k7(10lqjYIEUmLY1KF48ZzcVY$Gasr1#`GVieq21zgH<8 zTDB(cG((|LaQa1Sp$G}( znh!6TJYDTbVkDZ!NfC3|-H>IR#K6BJ$rIw~tN!PR!l%DQ`h>_QlKv-#Vw8LA zdKuw66jlX9f5oSPni6Uk#men5pLcKDV5f^0Nu?H{z5CfI1@6g5o*$WarPHPzDc7QE zQ^d+YIRKr)xLJfxMSA@?@))XfxRA61n6Xj)goe^jZs!V_9$GjKha&{rLNGTqZV4T< z0?Aqe%N13~IGVr}3i!aQ>Y#hkBRW-u(83%QgXaH?GB$tgFnZFn=w|+;S9+z16obfJ zbPxTBtAP1SwWWjFNKtJ|ady*uAQSXRAmok`g}-2$)k7hMtKRiqT}EtSg)+t?VN>*7 zlbkVJ`x#;6_sU4M1+JK5v`yu*w9R@)Il_u3MI)me9GNwPFKaZHb?c}+tUf6(Z0UEM z3%G-Vt9h23!Fhjj)bP;hXqYdM7>=a_M~w29#1}mU;bn4+pHBdnfug(*5@d~f9b;6#nZ;r z`L8wqRI^oBV+6kQTYmK1JnlB2EvicaZ6ibaOQaYr^*8#Z=>DLrAj)JuY`MG5Hb74s z=m@YLjXnQrKBB)Cqk-@;7<8&c;pLBHG@@RD&`=BN+A#h8MSM|7O|bx7<|jc9OVR32bSbc|-`mCYYy-6K=PU4jh%4#e-%ef?sv!Bll z)SRZI)-tax46=uRG$TvZJ>$Obrx9lI<{2Skt0v`-qt9a9^!S14~1Lqu9kt`NYo~E)4ka%W)2U?WOLS*+A;=_<< z&`hQrJ6_ZlHrf62S^h#yvIvu>{bKt%eun#uWSJ`DkDumz8rZva^AK=rObDSFxzf7! zcK_1y4SR9FLlf_&csn)eXRv~CM#@D*)9RIk!*2=N@W-FoF-<-lSeNogmm<)3!T5N{ zJ1_`gVZ;I%Fz>tRMFF9+91ynH^tc)#(THe(@j|`?>YE%lza5BHgs%ZQ5Hyw~>l;_h zJy6dqG#(^J!3!Gi`Fa78S3;fF>jZh;1ct$Z&X!rJ`eyviHS@BKQVtk?KNbukA5JaZ zzCZw+T$0abG=JOCo-unA4qkzOv}^liRae)ISYXhZe?Ot(!I_v!`#rPb(x_Wq@5vge z-WAvMB5-zhbq>-QQwm38aGTv3;=5yq)Cx|3*IF2&2Wr^oagj{u_C#LN^&dUat5LCS z3M2qfit~5f_m3xXu`snYW%#FM`fCGcS_<}S>}Xv`%kG3O_O=vFI8d%p%eC2+ayb2V z;rN!BX__j9g0oV-IIDXBAbqWd=^$RMwn8xK=B5Hy(kW~jk2|zX?)D|li%*c9K z9~5Iq2)(_T3;2aZdJ=T)GI530Lus!4dr3#b&FKZQd!D&! z>9?zQV@@uJ!4{NUC9PQ2{kwQ&@(gXj*{8#{YgDRidjfsCC(G3NCSN)uZCWdeFwDQ0 zeucAO=IcGtgOf18k#==I>DIjFas_E}JwfL4A^k(k{TdRD8CxNJdbQxqPns`WmUE3R z)E?mTJ*yX!G9rw(l{FeBexX7$`pTF71u!ibh8~-kMPU-;8?j3tCmv)p0kB8W&8QXW z)Wx1{Pq>4SQ(b#y>`6d|^QzAE|2TbCxjTJM-V2|KBY1cDb3Ak1M?gnszC#}uyxW_; z<@a#3MDSf8*YEb`8uP$ItN-JrkD}|(A5ShIvjx#iG(+B>hqICBYW}ykwjr`B+dv7i zrv!1)LY;kRyenuImM}*$3KGXo^gf`9IRs*$8_Y>AEZ%k{mzik`qGPPPhTt_N*w?%b zcN4r2qY?|4BOJqhz$2$Q9=$YzgUBtlrUz$qu+yQDdOx0lkLF-owDC}5hZd+B3!L=O z!$tz9(FF@G4Q@gPWzo@7N&?FHh0^J=Yy3-)48PJbz8IdYj2v?j2}J@%w3{WkUuOCV ze3hF`y*s8WC(WE!IBu(?B=op+2m#7r#x-{?6>e%G?rsD+f*K-&R<0@t}HqFm6XHqra5Vi1QJxB zm0})#Q3qc-a){jVJb?_+Z1|?53~iKR2Jx^uh-!mJq=zpbHkKF3Xkz-_1gOqMn zDJQ}H&|5J>J8e3+skEmR!DPdi@2+y&KgSoVi$sN*mkibCgui9#OhlMP7533-Xk{mQvSQ58 zLFL8)e*>Vt6ex%Sjm+O(NDt!hwG| z^N3o2UDwV!!*Sq=PL4V|rCB!J^hRYcMQ*=BQRK;tqopUOh@Meevu0bw#=mi#eIR#G z4I82asg~K0HNxojO|A|>cvVSWF?sIIu9RisfU$CTH9YSus!@SLAzDC8D?mVCNeu%; zvr*7|XoHP=DZ!?wey^9R?F8w$s+IzAbJ3F_N8SBVSPw_C>h{1!SL{;~ffcex!fM3g z7|`>^ttynqlR{6&WdAglbWSe*{#-E-4%!YWWxOuXfxt4T@Nb&m9Yd5!EPR%C|75IWty4 zW=q?J8$P*_}DN9 zE8F3*BgmP3==QhsX`WTMb!g?DcZiAI^%qW5m}`NI!|Djp$h|J1?d0fGR%*&%SFxqqbi|$srBFlzd0n@g*@Oc{qaxM-W#H zW{ZAW&Mivm(5?MsXqlUM&Sh*$JEMK)FRi^j95+4M-xb5=X{<4}=4qOp-(E?kf)zyBLeP@=Q6+0z5&>z_bf+(GrK3T@a3$jWFD8vi$+)@NEV zBD~56tb$Z?${WMi_l?7lXGL)Uiflx2Dv6R+3bk2CzDy_#@zz~NFgg8gzVvAR`8ryA zYvpeRY75K*VT&6btmVhaZo~;D!6JyH9_!t=v18?5(?Ona^v6D&B{;!EOoh&yGoE46 z$g=eW#AX|wi*I$>*3O1g1L*vm$+ZRw=zH^Z$Bl>HuGJY08=6C~7oCKJ6% ztqIbK+9N!)K0D^Jm#fwR`D8O2?B|VMqI73#qo0DJ5m!R!F zJ{9%vYUE;SOkDd^-}I*{N&ZcZ|FzWqN16YmCI2k6eCk4hhR(&*Zfv@U&GAFnJ2(%XFPsh(nm(({va%B6wksK^=vB0K+s}3 zwtkShhACsS?dnIv2w9Q=SH5KGZs>yAlgO)28mR0Z17Z} z-;`}2vl5Gu_HT-B9S2iP&(s8+dvaB^&~VTNz9{-L4a`_YNVGxD@Qb*;Pd(^yV6S>R ze;X+#z!(*8KQj9gSzB5pH2N5~B|_zFqUc)ONxjJMImdrT#&bst)z;?-%O`IBg$xrX zLw8F%bLW3iF#qcQH!|82r=-D|;KM&>ujtgA`9(;ysU8#gf%-RC2>V>Q{KvE#=Hq$g z?}0#chFvPs;;l=P6`QR$;<%jXXdxj69w4p@E4?NJ!)s}_H?UZlv7x^kR$kYD=c~SL zu4ln2f9gsxF*X?*gmdKyNbPYZANm*6@CW9Bv+^c(9oeF-VP-@<_wZ*Put9W{vzVZE zmS)0-()lER^C3&8EQ0U+9*FnC;M`kvI0hHG7M`c{Cp0sr`Mm{)4$7y{QNY$?NdHv|Ba6SET8`!I%XdTiRHYI z3p8e+G-uC|nxuxsXPP;-#e}X{&k$cHQGV-OB&ZOPe9J8%(j@BnkB zT{*oauygyTGwv(+XJV)bt~ntvGIurmGL)BT2Hc7uv|a@1c{<|ZN_Yo_AR07qCDp`g z)vl944x_17SOLx{8yYwG>O# z^$*73{?pt;@UYKIKC4!fL;wKVrwl&16k`iRr%%WK&*h&PpJ~fD@3EtF+Aq9A(T{~s z^k9@XtCE!3aOFx5OmZ4i=%nI^3ZobS6$OXmpYPXVq4Y6Q%173jxnp4RL0mXG-v!;K z+Aj5B@%fb0n5i%vz0&%T(KE+0muYwP391xI9aXJ}oqCJ&qn}dKt{;y+-j~{Ja&04L zA9<2ypfQjScy;=9D&23tR*yF|5FTW%D}fkWm%|nol(To}CYo!uZ+G}5#dw<~F4GBi z8UzM0?i~G?%4ArwPMe|0JcpxhSP)i{XZ6TmuhaXI7wpJ2!}^V^?>O>GET^CEY+uyI z1`56OlEJn#$vbh*hbk4o!M-1Dz1 z>yP}omlqQ?(Sa##i`v*z7NHSK9nMLA!DnNO#d|orKzkoKc_ERd7YL-p!jhoLL1p5d zvgnF{AjF=jTqYsZ8TP&fH!3R1AzDRsV9QKTs{fPaXoqc8ukCa&$<>p0Eh_toXPzg~d76CfrezGQ2+*o}t}#BZpAD*9_d8bJwDLq30<&zB zntA%ja_`Pgj?AJRas)B-FzZH~opUnV9_|?Ad=LM?#OK|d|DKK#^>P8|E3i+1K4kN+1T<1G@Po@;?6d+S4#ptl7 zH^89`E@8^fDiOLY(2H$RtqRbL0I?zkev)NdKxVIn$ubRW){vM!Bp3u7VWDs02nG4_ zdtr)-rBWi4WpfQgX!DkfK-kk1;_n{zkg3wy{FfFGSWcx_oU$z-B?ZPelMtC&l7l#F z3bRFYd(B~8_Q*>YcMk5FVeV9{I%m-wiulASv9aWT1dD=de7$vhHyqz{L6K47URb>l zQnHCo4K`zEM#^j@5u`4UEfsr7yfIR)YI0rI)h>58@HYp*xZ9&8oU_2uuQlb9^U2>G z`d&S-2v$l#nbxU@Ab7Dey7eWF^}f2puW!39p&q(^&jV4H8}^`= zn_g}!h|c68`^f*IyKf7p)Mh`A__f=+O1vc=q@9#IL=Enlk<)AAN%C)FAXq>c{o=q` zk&G1ao%=b1vqA+OT_W{`Lg^K{yd$og`&5VY{jtm!yNFvs&`|qf-YJxxDF9N{;-A|e^lb(T9Cg^0mAsn$xcPTQU+p|0}}ug@f~m4(T8{sTHjdM zAaq|sC4Xc(eH7dGOSF6vw9SUH_BD2M8R0OyY{`d>v>&(QPiIgV96ob>S|IvB&*YOW z%Uy{F>WQ6iG*4yq^EMLf2v40$uvZN8wJV8T7z*F-=RO28%%iu3Ym_hh0?q6`-ZByU zm{a}3@oZ@e+AdkvpliJS>UYUH3Db0*eMC4^_XTF;cM-(>NECxD_E(g=r0%AQEJ{Ud zK5{F9-`rJAGYl`QoPX(8a(0;KWyu82rdr|Dy%LNy%9t0Er27#u2(<2RkmAKA?RZ!S z09W7Mdgkx?f+lh>d@jFcm{{nvek~p+B%ozK#xBP?wjD)Me-4V&xe03PsX*viH$l^Z zOiJfDkw&CRU%QEv^w#$q;N?EO{Zei&sG924X$H#t2rrK*A1?J2W@VBee-v-X;V_Xc zO6O4|-3Yp&i^*Mq3KG5CAu6n_e*uEXA;1_9PO9jMvS303YYFATIL}s=m-{G#zPvMMcg0SI7D-Uyec?H;Y zH=XCc*l|j#@C>Go*EX^DRLGQ0s!Oefo^_I!IFz?KKvmjJl&HlrxuZHEaww>ky$Z65 z(SjW`7lG5BS4hMn7(SX6Ut#-=6+4>BFsQED*AXj zbDftl!?yz&u=J7eJ+!in0efhuFS%BfJ$B>2htg0eLG@%{)JToT;%q3_L2<~Xf5K9j zqf+X!`CVD!7;b#n%pUg-N#P0|JR1l&EcUpb9ddFW(?Z_AG|rq{85C1x)NKjD$)06| zh3LO=#N2+CMbp*V}Xp(AA49Z z=nl9hcl93eHM2P@7-UCew3piO?@IGX*7hL2B-^t4;pXNsukgdtRfewM+uM~NH+8jR z8pVlc)#+naMgNg)tITBhub23|^|soIeKD6!v7tNMsfBn>4S&r)*GTovtlpD(yDf@> zeO!4z6vP}eAH1F)sQAU6eZ3;5rt1{yRaCo;-Hs2^Y2(~dT(}?L5#ju+R${K15+#Nd`F`1?wqNCr`$fm5}Mov|dUCc>~`6pd=p8 zmU?x~c^Csa*HH|kC8yLx)Vk|%r4Y}Z6>Z=-u^gCcdIQ2i2*5xf z7qOt3Y77JLIlo^+w|{Gwz>i?PHhSw+hq)_vCIlH87I1Z@vp4SU3D5!S-^h3Dwbosj zXcR{RoVxwOhhsOGm{RZd~_gwaXCxNq{gsR>W7_&8hQ+b~=6wcw9BYBIzq!fZwK2&R+PDb0ZSmkhrb_9Fzb*8?R_)?AY zAxeL*Qp2JfoGq@srRs{mw-1&BxwHIQUEt_`gzjr|#N82_B%M;VK072Xd<&MQVRv6Z zd>{bK8a@PTnGtY=jK>ahQ*N(x{mZNI*kTnY9y)@A&@Nb)iZ|;)`v(PKX8<^YQ}L6< zs&!>SfQ@FzBM#N69i{mgHqejV8co|Ey_GUZU9(N32*D*wQa)U=ZBQAxSp=Q}d3(X2(tZo!-M8qce{jy2BcA?N$afZzJo%PX%CZ{Tjx zWFU-}eT3y7$U7eh2T73QL>SWH>fcdAl=3!8Or=p_AJB3vaqyNAC=;nfa*7HxUuL1X z#*&F(Qu7)5unSjM6Nq6@e=%khPK8st2$$z3Oi5YjBKdd)feuM6?Y=j4lp^lRt?xOl z2C4hKcNrU}WPdb14@s{#e-8 z_X_ZYtEI?cp~=jJETd2eV-+RU4-4U73WSHblwDLNWkm{MCT*8Y-fqEvgX9wM(Ysr- z*fW2dp{wsKM!lYDmW+kIlM(5~07?kzf@r}+{G)x)I*bHGL3Y~Sws0Sz#II;{-y-~* zbSl<#wha0$UFMnXf>U0xcQTqRtH0z1Jb|LHN|vK5nEo#5Sj2`M4iod}N<2S8@S}16 zk#~_Mik!mRL?4y!I(`BaYAjeI3c_eo3x}>7`27i%r@!#X{|k?c&tAyio?N)3H5^CX zpxhA@l4!dgy;6^r5KX;qolG&Jb@8N48vNa+Os-YpgOkp{&)b7L6)9#K6g>@Fk>GeY z1N?e^p)a*IYzS*y$yQFHa=4f%5D$vvM!%GQ@_TiqqFD!|*(ijWT9o z&M#?4g?8D7GSlM4V}9BA4M+0kAl{pIKBm>Mdtb3z1cgR^}>ddrY z8r8XI*6Wi_tOLGOX)9syrVz|OJHwQH==zvt`(Z!d28Gnoi4XmF0zxuWY7H|Fw)tDa zmou0zRW!5~2hKY$?BYW#3w6ZNZ$=a*5 z-c-XKq$HXzNpTv|3Q=S>DMgx3#|%&Oi=Wec94kPBQ_v-quA=D8U#De?JG$L&B4G~Z zBksGUSEaSVuW3Xo8phOQK7|k(8i6N+^$Wi#>JCt0o~1%-Wfgx@Mq=5#$u|G)NjLkqqZ5brL&`L{bpb;=RCRr-G9rr}rU2(k< zOILB2qNWv40g#9bt-#TU3x$14MT4v6-gK|^;lj|y1f#-uhipnS`ZA1DfC~o!gh~3X z#aK}nF!GHVZqz#aKyFAS2XEKZhxc%l-IoZH`Gg_^l3rk2OR;oL#3Dwafa&RrbwFUTkOb@Z>6O-T?rd71(ky1D99j~2~ z=x4|#JIOx6CUjWbA3C7G$!}wNlWgw^&yu7RI+`m^MvkaMru*lwRVly^#+G zj37U#8NT>*zs0j_A~p*7JCwG)TurWD#_(7#UvB*>StDr8Vq?WS$2^?8v2UrBy|iR7 zbMW+l#aTUj&dAwQOY79VIlXz{X@S@PT(%?Ob=ey~T)3ypo2Kul8{h5Z&<{Y##X@l+ z^NC^(vl)S`W60OrGqo^lz_!>TR*}Jp3MU=Ow{cJ;k1XS6t`6g3iJZ2D-Lvrr-0JUT zN&ILmx!>U%NjxT?k^d`Isv4da!~0!9DO(;*ZK-g8i8Ho%!(BQ_0rF{!+`f% zQqTB;m;~jx_RznI-y3>5sG%mpl9a$&v~~CeUt#VoNLJCmE^H2Ad<>1y;hljJ4bz{d z;08q7ll=pJ)iVGR@ifUuEvfgZGiSRCVjT#%kpJrfB`g-FVM`*%WJr#LKf`W&9wOcY z=B--dPZ*P3@8hFt`19pQ;;G_&Z;t@}6UvJm*jD0)iF!cs&p%R_OzGMN8j@ti+dJW~@D7pK28@89x`&5Vo;7!we%-L~xy{cG)Pk(ziVMVk^I zoaS>Ei~D*kX>wNP)6=84S7OW1bC@UN_a*(FXe7yfVz)XyR%O70qXVbg&4H)8BMC(9 zK+j9W^oTv-FZLtztO&7kvD5v2pLVsV7nq=8F<#KLackKgCz!diW_~P5zd7P1M zi0RHAT;V^k-4W>?CcSFI_jkMAE;cw9*s`6hc!VdAuIo#NoCa<}vYPp4;Ry<-b`*5f zHjVv0CGqbp?}1RRzWC=_LH&~l{a2am|7CgqC;xq>u4lc*h~`UhCIH=0+GN@$FZ(Tt z%=Sx6Rm?e5SyWEON?KwHtLa(SrF2>ntE-`lu}w|-gS5t@h{jRQ)2`Ffyv0~?g{aQ< zF>QZDvn=foH??hsylM&Kn3R(9q{YGm2)}(;efh1WHMCdSzv+=c z2Nv54PGw!%A?&G4MA&E#s5PZu0Oi@-goYmYW%5p~s@9YDg^vd5@twpvB0n$`Y|USU z#y$0>w3{&Mwy29OyrLt$u!}JRe+AXrf@2YkIboBTxhux(+qS4r^|O z>ey#n5aejA;tow5pO`;*E&k?mwLi$X^R_DY`eeG%H;=y04tB%99Pmz|6Tv{krvd>f zjg!S`f(x|%l5|G&E4;erP)2ehERj28R)i>CL&t$xH^JnnpJlvue$HN@R7D<9?Y^-! z>K@ao*&W?mK42LY(C$UTMJ$2lfXo_BO91{_p-2-zc^);TI+O{Cz*g#Q3nG6Hfvd1S zdOYc?=eneZuq#sewk9-??Y+4d)qSfy>8rR}KgE24^JS{nL3lIv(2|pY%+QT3OD@SK zB~(KTg?!Hff1)e0fLiO6ICy=8&`D}EJ<)Xtqkp+Uf`Fppb{3ta4D>@x`>m@h+< zl;HT5sHU)AX3bGwh}_&Yr;iZ%E@p)|=`B&PfW_-hhv4ddO2c)R-0G8n<+*zwlV!36 z3YR>7Cs83SSWVASC=ng*FhD{*@PpHuZe)Vu`tEZZ;D4~a>|B=k4hR6?%ctS}hbqH= zt;99u?DyD#9hk@d4xzfJI&rtA{aU1mD75S=HXJ7y$FXS^*$844Xy=@7_uqEHWmihr zDVz8jyz5wT5edxk^UAsWo2fm_rPKzBu*gn?7)}%uM{*)pD4!2b%syC8RI?&-9H@>d zJ&VssQu$Rdn{6MPpB_@~6sJf1#BHFn%MjsbzbTBw+UitwfE@aNAYxMf{=R=Fv! z;K`&brCFI)i+$1YpMg?!gWX-jVd=UmWQ6mYun0eX`C{0QstV2D z7Oqd3D1o-X{H-vw0DwmEM<@?7&$1tyjAB2Ol8V9dpgq>5#d?^@Xt)-jfVI~3+dl#g z6?6eY0pf06vCjmosu(^9Zk>C!#q17u~HxP%fFzR7z)47qT zyw8n?*o3>=UP#~c>h-MsFX{X#Bkxxb3!kM;5} z%M;_{t(;eu$1!Q$yL%V_ZhFKl$o>e6dd-tRhT z*FKvlW%oPRHgP|SOP$8JbBF1E&$G(EUeCX*+eKC_C_YwO>i^lg)Bs=DfCUr!e1{-x zbcU%8_3N8EYjg&MZuRpUv~?mq>s&94CZii(n*mjpTJ-r3DaCjt#rTPVIX%O!w>Q=* z&`PH$IfH)tbX&Sf}AqyPTw?wpwYX1fS<;J=9 z$O?EKp=`%0jAWS7__HZSw6pv$c9Mf?+9l^D1Wu=Kkab>{S!5I^+h&8UqBtpy(}0r^)0B}8_Zb7MVSg0l;}wJlZwnEXl2N>t!If6iMrl>omNw3( zlII1}|1;tI_f*T)@5HzMbA$l=f17IkQ&`SX8L|7^AO7j`1%T}o+9)`U22{{SMU+5N zt_A|ee9GtuQCN{d_4iJZsGHe+#V6tMUQheQ`;BFH8;Tj~?=rc1r8!b`vXysD`~H3c zU*ERJxu@A&#K)5SCC4r+F1HqqV+S_v5|9I$Aj-+?zu`oY))uDnEnBll%54rBAjPS! zle6{a=D*U9%(-MPgOJTPrOw)tBgK0-fM_F0-%^_#J{$_UZFFE%_KeKupHN6;R7o#I zR(D4e1%#xRa4~t)c}$;~*JGMzKUQNrpNEL#0)c|@vXi*eKWv`a4vbvA>v>C@2eTOv zugv?kax3c=dfbb0VVa>ue)N+FGiV`!%8eLX-(4I<-me&Vrj@=X=`Y1%0zE&X(k~h&dFt{2cigg{O3nNAdrfRNqnNHn_P1Bu4&y_>Vg-6SiL(h-P(3?k4P*71(QO8Zv(qGxc#Ka(k z$0V4`Bt*a@lFu@R-z=NpGzK8IBazh?=TPZg&}7pGqvk9nB5 zQGldXqLgi>pna~8U52DXn7V78xL2~gZ>FGYuA+amwS9?%eYucbrI1aHpkslMQ-P>c zv9L>_uxp91(+^SC3K6$*F}G@AmugYZG7;~eA|92Zt_`B@HB!!8P!s)-nliQ^-8%1+kq`o!j#kZQKmHQO8 zx`YpKB@77!_6h~|iU;+JhxUnu4G4z}NQ4iG1@%e>4M+wI$c1%Fg$_uE56XlOOUL$$ zM0d+a3`j){N=FUI#`Q|acgx2N%ES%HMGuQd^eM-TE2RyJCJf0W_sgYq%O;PCrcX#D zjY%er$fXWTrH#s`PRM2T31tk*Wsb{#8_RriF{Arw_m0iXj4jMhP0vou%ug;YPR=Y( zF0al^&dp3Mu1qaV&rZ$E%+AcsPERk)O)t&N&d<&*%*-xMe>U@r^Yb%{i?j0!OS3a8 zvvbR{vuktnEAw+J^9!Hn>eBq$!s7Dc(#pc(+QR($;?nxk-;uTD*_ExWt+~1FmARdz z-M+2!@uR!B%gf7;kB@&@%rp33hY6tl+x=@30O$|ED-5n=O@2=>G%B_3a7{s9IFLj- zN3ynXAR3FsYJIr&`%pZgNEEJAUC~G~rAmeFNL}$*I-~JuPNZXAXEvwv>AGif$yA~Xo0`kT%R znN4dNMw+j%$Td9lOjol{W=JFhi14s^m*Wh1T(+mLNuo4Yh7w4==NueWlPjgu%dOg! z&t$e(Jy4M@!lqejD*gz%>5rT{lngV%q$Z6(A`tc7PDwze`MJN<9juabABIvS^-a6} zaDK%(liF64g!C{f)m2?lO%5XTBKjkn9z4p&BniU&wW3UtCFN!^#PZ5U)|A3rgILPS zC*v+v8RC0sdVUnSafjEOW(n@_o*|g(RprNpgviZWkt2MbgE?jn1wC+s+nxqi?5z)_ zaj2lPd+{N{JK(59H9f}_KdnU9BT`&Gj3SGi;}Rj^F>?ShT;r@NK-cUlqwi+=;#icS zd`XcK1@eD@!tj|*)O6qfs1knqT2Mj&9b8An3VCb@+(D6Z5=b9dYgWA+%RUhNEVpkL zdM9KU6x0NFEK9q;zAb{~yvu4f>AV{N{T*mp|Bz1n%Q!-45DG58<~RFM%${8?^bL%( z*^Rhlb=kvcpnZYt6R;Q7hH#HYv~_y-W{k0m7M=x-Nks^pb4eMQ0cD#OgaM%u_jbBr z9R5lH6g8%@2WG-atOa(Aivr7l6TY_p)XDf-u$x#CJsk)2)v}CmE1LmT=x4q#&RG8K zga|q%-D5ZMyb+QpGH|>>RGQ@j?Qz|C$+ua!7ijym^9OfAaaQ`$cbZlcUN|BuS)N+F zPs=255DHNd0MEW2QY1Fu}jO|~;&CP@&9wHrsy!~^%HQLF2BVU@c6SQr^F4Sq3Vlx176OehEh&GmPd zXFmeE#E@0~Op2na7{7!ie==tN{WA$36xud`v%hRVfk&kv77YIhkF#zE@pFfP0|)?H zBqg2h5Fy?G-gA4M*dqa8k>G*S{q^C{OepBg7{iDXETzA@7lV6T7wFIp<8>WlWnzp+ zPAX0&U68K)bQLc6r-1ka)DTBVH3CVHIv+KuyA7P#*mu)m8|t7W8s;>Xcv58;t=uAk z4pKe@X67pdW?j6Y2?(6QurPW{Hw0D-G9*EOAiQg8oF!v0{@qGH4l6QDBcm{K06eKS z^)TWOVDKcdhR7Ds1I3#k2*+yx(xNK}iUtS-S0uzb9~Ng9*GNEp=|S|(2g5sK3^kJ% zf}KtYf*DnW5x5IPdLUN8btwfWJ0?uBQ5<|}aU8Ls>c{sd(F7!fCn#Xhrhtv*Qz8e+ z|Ef$TtWd?K(XsphG6kWeX+vAUK}stIDR*OxlnwEAUb6=u2V;GQ4i+WD4rLVGDa5)5 z#YWp9;YqN{E;%iMV<(hy3=7Ud7%>vg*bxd+6C}EzHIzQe1f~*)6ia)b2;N9Z`#s#I zB07dC246=PVl-lQ9YZjtDaG4_>|q~BMzBOF!5f_IR%lL~($6b~@t*Y{ctX#zOL=;V;= zbVBAa0gn*$is3YgyYfXii^qd(KNAt`UD9xt7s8lvdt)p_MQ~PYYC^Mj^sa6|kemta zNoKr5a7+MT=f3tn=h{nQMW{NUSNpclP5K*)oJ0(Zi}Fyi1`${u#QRv`2?cE%wkh9n zSEnU$e%6E|O$kND@%AFAJM5zMrB?zxBIsY%;(wjGcmC;M5^mz1+I|`o&hzA!U`y*8$(#_AE2Sb$`~tTeJuJnph)_!NnmX_ z_&W{&2L6FC$zwc0P8{I;>k62t`Ne zA5O|X!k+WAfuE%L?$9ENfmO{lF)nvm(}l2caiI9PdE|>(w81D0lEV@)T0RN!PhIe%o<4?a1j`jA3mLVzBUwy{oiddk><1 zB)T^h>Lu7h1uTG${D$(k2Evpj?I22U3Ew!z5Dtj6*MRy2%Jh6!6 zfWG}ks2NWol)^oaowt0bVmFd4w*V-vg%{3ztVbFkD=H=uhJBn#u2ZGkTC$ znEY}rIoOAIe4A!5)op6Vd*(cp?5jST6mJ^l{u(252(@k?tQsMuP}#6AIo1wVPjbMO zNmJ!6T&+o?|1%h2J=;I8Y&Y@NH=b-B||DsB>GvH4)knJ&mj)rLvD=Xz%>kG$Q~s82s-3$-d08Z-ZnKR6s&xsfsB*MZ5d?$VK>qPz&DbPa^8rc*9>V1@I z7;LNvb;ZH233=Swd>g+W#|w@p69w~CzKWJp$G2vA z!aEy%WB5V;!@xnmI5WA>nr~0c{CsZD1bMxKVnxNFuzj$nA~9k339ESJP`q-)V{?o< z`EGa!3+#G|5Cb@-8XT;Oc#7*6eit4ci6l4x#2MX@2f>{&qS5jn38N zkskf=Q0Z8SCaBvx#B6#z2!@{okE+SX+aC5cNV<`*idBSQZG4ESjsVNS!`u8YgyGQ; z)YF4~2!h31cg7k2Qrl@_IzT)k#Tcnl_|Qj}Nq4O|8q$lOBWG9qJ)UBosE!VI*AK5C zKf%EL#xo0C-4L816r2j?qMi?yvk3T}fpHg+NC-_Ct0mO7L(DP)YM3MPUU;i-1v;~t zl0HnrmPUxo#=j?rMd|~ij`*!#rSfM$HF5DW0eA#DX=Wa{s(m=d_5^c-1kb!-0~VNa zAz-*gfTB|R-C7WpTl(iALdTJ~*&_j1L5hcc1mUSPawH(43^r#ZQRo*VT?Soyr5kP^ zjP0HgvyE$+LfN;Cn+wHFdSp4V%99?GnKhD`+X~8O%Nm1cb$yEtjSz77mVT@dOy3-M z?)7~BEYarj8LZXbyEZd$1R0lwoq*iJd4|AMufOS5PnnyKizrK5=+T;F}S`FxwQ`f~;uPIK)HPgBLJjTw!VD2-1RQ<&D`dgrV!g3#iwjW{~_ zX>XvSKa61maF7r$SR4u#Tg?QOgTUp0qDT3O8Tpj{MWvZAqAb`9Yh+bSZh&$qlnwg1 ztRR^ecclQAcA+?_M=_GOa0qHP69HpuD-_=^d|h^jzZ@Va`rI%wpQa%Hfq!nLF-#&B z_6#Xls8m2=S)e;0T}tr`*@B}|j;qGbvj!~D!6RIULLh^A25<}sM9C@6b9MxhaREK&@h3w%djK5OWpn3WX7i<=Ck@fW4p;KR{D zVC#-*jj|yHS1|m z8r#@O0Ni!=s&z}8Y%MHiDAphf@}3UT5L?JZ2NHL~5Dme|%S5uT0%Q+*3n_c@)APPJZG<%Lab4GVQPxwMay z!4uxcK~4+M@uGSR62MK%+8_&@C@8g<7&S>BPFOzpz81k3H=+rs{Lgtzn@1R`i;XlW zpeA*Vwpf#qSm~>KEqYI3>FhAOX3Zn)$j_gGlAqlLKaN3|z#dk-tR`V~F~JF`#R=QT zwB#iiv>+I(B_J&zI^)GRqXP--XA1X}P~*3R?$+t-B2!L7i23TH7u(Ovn{M=078yM$ zQG`0GG=O^XxduZo@PY|?iTZ46y|i$mP^~W1ICGBFg@xGBym-aDcq^Bxc zYO%JmyDV2R8KEFDlXR-x#>O82?A1D~*yeur`lzw+!E>Z%YZeAZd7(p~)liHAp73r| z8H*9LV_&(N+@Jb5T|A77Yb?Tm16u5c`NR$9Nk}Kn=U#e7>_7`_H?6)2QuQfoFneX+ z9aJBeDFy?ypDzG|tQ|z(1NzL~eJdYG1@C_8SVUg|>lo|4z1w}^=qe%dIP!89arEv<2A%{2w^#RJ z>YD{DW;YyvEgW@QYRP)++@B+P0oc+W_k6WR$35<=zyr3J(|NM0>vo%i@mr`6KuQ1* zOAF8$P58^N>HKkT)Xx<8xZ$&6pOB4?qLxzL=2Aoe)FN9mbtyGH4m%Q#?bkDsA23lO zKKf$NuJnoDKonS(E?NfAH=jA(F?(uF~!Dtj>3t@CRj!-9;37@;2&*W$}7Fv{E$@bb#)!Ut(?i- zrKg{2A*Vma$Y8G(ZjSflG-0x(I%Yr}9i-D+bzLUqT0 zZ{TL7sZiE*U{-|)XZKBsvBo$cLG2`eKEXbeFugdw@EeThTMV(bIj;%SRDD=?INmy{ z19VV?QB*d2C@uL2Iu3YILE5RVOkhZd?Fq-W9Grg8qz=C|h2?dBD*`O4ku0CNad}7<4r2l+JV1wVQxkAekGG3IIG&1%UTe4-te* za5cfM4>s;HOaLr1=ttFkOmjHMmEhIGAh1mBM@Jg4G#%JQ13fc(&(~JR={6S)`9S3c zf}-YjodB&+^sNbZQIe)XTUM6^M9#b*OKz~`eM|(+cBa5~>ium8(rw291?OW0TGaOQ z$$s$wAi?SZ%)x4NtL;RXu-2nsDIR1CVzJ!WFvV>8`K5b@=ysK!DdEHr{;#x#($k*`db#AEsRt%yUm zM11z{!N7@fB(4|CN4&00{^P&?^h%Fc>)nDG4bB z4fV~N)HF;qG_*7{Ol*vF=)}mz%*w>X#LCRU!N$hH@h|be-dy$pU^swhfH({w3;==w zF<`*U0W?n;0EB_g?B5a?gn3IG6oo}ZN! zx|8S(#`Frs^ffq(w!07iks%__tI_EkA>%ZvvnGkis!Y|k43fX^o8+KgUlQm1RRSIUqGkrbE+)?=p( zzTMI2nzSuR3jt8(EIZtu@H+6+P@y7!SeaE)1li>`<~^MAFLADD&n~lp1F+1+9>h2X za+*#j-8DgW&86~`Ddg!UFZPcgop&g|+45|29dl-wST~~ z`!v4KXV%F()o>YvA+E1ARMSq1O?9Ce!#-B?P2C;wZ70qZj8_Oh=h`J z+jfrwrB1a>J|Y%(bamN20p%?`oWgebR+MVU?m4zN8FxB(R3?M z=jxQS!P$EafgOoz08l{tn#tX_NA+st^pzOZp7@yM{QFoO95Q8*J{c(k8c=(eHk$JbAx^*4V?lmC6IW!|#@vXIlJ)*6+R)u31IeqAT`W)6!i6PPw<*Y|(Lwy(WdXqRgev#}Ni}tsp+3Y8lM?#T55C~m_Vqjm&qk9r<9HL@>_n}$t4j+OTd71>lhLdjGjuNj6UD6 znn`iQj#cX19+Ndsg?Lo;=coSi1hclLU9cb7y)z4z7wW6y*=kb6`)7^?e4D0uD2RIF zt_^DF^CrmIi4~LzXReY42p0i`oQAU%gPoHOgM@=bG9~nr$!Ft6JEyH*SJ?2}{hoBh zO%WtAG9gp^v0&2W)wg-&@fOR|Pb?C8>>307h>9XZ4+bvti#s|#^r;c1O4Uq;SWUB1 zNHPW?ow78wavNRN`ORmOMu_6Wqg-T+bdqI}Z&Um|g(^ma{75R@JDJcrfz?6d`UV@@ z(TTKd`o0EX!aPm1zOcdoKoA%ceAUDK?$V$zK4KC&er-|#9d~+OOKI>Qg+YHu3K$B| zCFydg&+IXFI>6`3!Aze7joAS$(1$Bf?g`=huoKxi30!@BJ@)cpGle~|_tQic$FTYs z(kQK9a;;0i;Edc)Gd0b@nSq~b-X=N`GcFrl8IQ5^<5QhKsYw*v*}3aJ-1d}e+~_SA z^c#`Vyu#is-f!V!$mLgz#TqnI+c#)izMxO^9v1oDjGvM&&|>srA+k7Oy?AABZ75)G zrgvXkNa(H{sD5!^*^7CiXy!Sjc&75DTm3?PR-ph!Ez+$Q|8|M6rQn*#pcVg+^?YxP zw&qseXn`Kbh1r|@FL2h*SC2K@e$m@ED+FlX&Lbc3h6Oy+{_~Q=l$Dp9wZ6!CnybT5 zf#H{S11r5DEu53y5+5L^HO2SjDJKJKjQ(>2hOC{5m(wI3HpLf%Fr@lRoWc$L=t^7o zl$Eb2lB7C((VlwCN}dc5S5fdz#<@1BE7CcoIxc(ymF>jjT99qMo9fD`3NwleU$o?` zMdy5>e(|oEFgrWDL*&=kK&(r^eXDeP;}YAnECYM_%?opMMY8>_NK6d$(Dcu->aU6< z;UnhP2Gh~IGcfW>TapU=sY%f9n)EEuM^-5&H|46l-TQq+QH04R4tTPce~T-1rj3}_ z(8_Oo`QlrpK!i=~*o{)w!UQ_{)QO_~c2=Ybwv+RRyKLDqkn)#R6)JB$?eAKTlJzc9 zKT;ocK}FtHZnw`qw86Ld65mn!;VzElT@I7hd&{Gi`w0Z^TYjWUgf%wa$X6o1@yb)! zPZ4_teGUcqzr8ej1_6_OBD$pWMj;+ z1!99Ts|8BgThEn#;5|IdZ1mS$vSt*y@6on> zS0HGE!Yxoy0-3;;=)}gydjM5Z09;0|cQv06KbpX?N{V3}Oae84t^XwZAk6 z2*8p81<^*OaZfnC{e7s-OsJjM#{S^D$f-2Jr@ucQY|Bu!pL8gxIDAG*Nz_0)A8oc@ zhe&O;QZ7c>q%3Plnm!BQj1CVN)AnYi+EpGLOO@EK`v@03q39G6WE`!RqqQ96HZAxX z^|q?jR-2v4)_5Y9cFyBzrnPBDs!vvoi>QG3J88+%LF2WHD4si$hTNu)5Qnc={caYl z7HcFHcu5n8OwA_f`S6FM9tu){lMCe;^aXFhl;Wit_Wjo?6wiLWmJ_VTWB4%kj9o{c zN^OT_rq$z9I>*G?o~@}Ya@bEGM?7<6#M=(d=#|8trP;fqFIZ-4@=XY3IuU1T*{c1~ zpu~=xNqi#7jhk0wkb62hDsw=-r=@2zx;0&4XwaBQ;Ay5dwWZ>7-$6VR+fN@Ccr4x7 zr>L|`sI*H-*xBB2PNk_&pwsC4CsB6gyIA31kLYk4_IZov#6Ji_wMLLJo!w2 z8qqn&y|Jkjs)-w1*u&hov`|P^UfmYAEv)3KHfl_UKq^Rs^cJ@=g7WW zybbi>E@mnA%6=~SA);YC#>OJ2LJUVa&U@>I{gQ_#;)7Zd@zZwg#J%uTJS%pzz)Xx| zsd`I$j@qUjiAd(cOE$Td4KJZ3M|OAt1E~sk3W1{xt5TRlqo4Jmh9~R%r>FI>tz;oR zc4%Khv>}s3VUFl50mn@dA3;VmBQ<~Ma-3c#{ zRppU<$(CmHss=7sr zX?`^?j$J^e+zUvYQDiFU$v|!}%Q*}s><1!i1E)ea0vS}Fbq_E0d+|Rwid+i>xkJ`( zFQ}wkxj{&rEYE~v7 z0swV)khm5A-^U?PAc3S%(KMj$=E}U_6O5GMWn3$9U{mqB<%$cozPFd^!75NbPK)BC zQV4+M2`8_e0pLaTkYXSJ!;0>iT11fcnc^DJ&w@)poQ3)EX?N8+ z;!t*^GO|k{%*wdcu1_j{bzDlJiFSl)CGtf<*%qHM#WxpEN!krR0b0#6tEG?l4XurH zT!JrzR=dgq@0Wysr0m=VLEq`Gb;S`Hs?=LMdB$aD;BZpO7u~*(zvc9Sr#g2=IsZ6P zbi;bo>#LB#Nmt}BJy+s4s(|DLevO6QivvAu}FK%-|6|#oBatx4Chu~ zS55^LxwzX@;#o4vRt4IOYSV%fRPJfcrdAB%1W7{FRt^+ILaIJ=PjL8&T++yKpj+d+ zLxpbdgcKG%4h1l@jf#}B^aQGJMcTeEh;W8q z*WhI~Zw+c_XCw!@t!cl$+uGqu-KTA{km)OS0m31!%$464Z+MH42E$O<8rqFc*~}yL zPBBH)0l!U^KedORqhS0|D0G$nqrcO(bWbXv+vk<83tc<-mz@IjbVDZb+#RE~J+m4Q zsJjICy}BrpLfQRL%iv!QFl?r#N(A%0hzKj#Z!(EjU^29tnP3^oKNHMj;0iZd+6v$? z_}sXA_LzE=RzImF!CHVZWAV$=BYus%#7|sb!<%YjtYv#`)#_Yq)in}h+cjr6;w8sy zkYm6J_ezS7JCiTDhWjfv+>Gp*3dl4ecD-VWOT;n}1v`pm#QN`hiIo6MoF7_I(VBIe z+0--ad`Ndh6IdC)mx8QvHPW7n^Nn?hV!+)}XYDzJ(HtX?+?QCd9C64^>%iv_K)j$3 zlB_2)rz|r@4XKYrI&~M}dTEA1h#F>Qj~)Cacoj454T50Gq~TgwUJ*LC?QuzDywvgx z89a*9XB^|*zmg=1z@DY_Y>{+i%0|I@eYrVVq$`Z$QjO-UbW4=`R!$qvHVZRJ_}x8a z9?C&wWL$LY?9MhVzWUu@w z(XVcmDZi;X!qK%)``&Zyh5q8YulPm<=}+FS+@f7mY<+j@GgMoJn)y|9M>v%A{NdxI z9mQ4>JMH=uEUzQWT$zCIKB64sWC$rWdjG~9n;5)l2>2lbCHg_8+6$4b>m2DELF>&@ z_EG{fOYl>)X0SrhMk^461w;>pe>H3%06h{)Lw~Er{_l}+YK`~cYAA%F_TG7TfG+_B z*{_*{)$`ukee=s($eUeLiF)4K=J|yT;X}pv;`BT>h^m*>t6vI{H=*IXj-ea1864gC z(xkq7@Qc_Q17|6vzX+ei=uU&wn+w(N2b#vY4ctfe@4u^bRtBf9EOv+1pF7ge{DkS8 z?6+6QX5mD>H!C!e@X0OyDJLX(s&Y{xdLnvoT=gd5>#TWl5bjZj2&Kl2uwNT9YXGjCJll2w8RhJbObdqh7U?2#$-;ZE+o*1VJ8ht_?% zh_3y2?YVqg)Gha$^WKQL_xqfZ0PvnBUAFXIus}Z{I$S7}rF;q<*V#mw$ng=v=ixe+? zx!uR5@9an+F?|V0PLRNgcf4=gydt&3assY7dGRxqJU%DCW|L@{L-(xN@;YNmITDC^Y=#B9-$7P?W&Y89Y zDiw!E4V9E`(+^9iU~jCI=h6j?!UtLpf=#Ks>`uqN^qfPQVF>}f_kDQwLc zw4~o1U}L#%1qT==_0T}ICrQa7V&g6_T}~Hh^_s{#4Ag|X4qRm>t$2&P<3=BpT>?UZ z4&(%il9swV1_YT6zhmpv}CO8SWX86fk5 zS#?2bG1!wHm{0fQSILXf+Y5>JYa@EX0!174y3-#%-anlG)UBC5%mKdfz+dEcmkxgb zJUSX!7%jG!Z}Gg*v720hCb8rF`>2%H!skj|JOliBB!?>P^Ow=AwE9tqGWTW$`KOk~6Q7`8|cBm!_tzQ z>^~fFg3qSQeF-@18=Zi3I?`Cbe_j6Ceyv9)3cWp#xtYBSKQsMn`a0%R=vDw?Ga#kt zP_to#)gfxd=IO@|*ykcQYlMz^lit@HpL2c*9{832jT4{N>x_RTwp9!|^{}#7>_Hh5iC3SUsI!<=ZB6e5 zcQ%+gH2Xt4CdMCk1Z2uBJH3^3q$_w@0R0qZY7KSbG&3T7Ao*Chos2RWx8#5iPX97w zT_G3`r{lK)W`3HQkOWJr7m zTo8U(`HPU$Y#mu}8JRxyGT>Bn@hw5+th3o;JIDdoNkaqMgG$!+_eT3F-{c3qbZcox zrVKu*d@~Vh8tTso^R^Lxk{lK451!_Beqbt7MMWiK!B$GJ%u?gbTJIZ%S|=^!8_9&n z%`UXr8vdYS+iuPDNKw><`S7IG-dlGgZ$x(<{{L4JMHox#7Ld z36-VOKw-F%Qy7-u&p6HXrL1HhoEF)Q=}H$$Luf%+LZ6f#$gGeA#z9w~h>%Vaev@?j z{OD6im~6+*2yCHwT-$2ZoK~7$iZv9l8}Ls~MZ;YZ_AZ~Hw)`$y1)nS=9t0Q!s7)Y8dH_MxS{%kReQmA>fE2Pc((kAD%x z`&B3_T_;w1*v2E+QHpM$46jv*SmnoebsmBK?Qb18+~i|9{c$bJ!CqBI)kE9j$6a%k zZ~L?Z1#V7WOp({{9PTL#Pn&*^YP;qC;i;xj%*Ea}+r=4YlH487ubdG8x)rbix`L-3N{?BU&z}&CJk*?I~V&}FDd4_`Y0>MV6qxW0FOd6z0+z-{d)dKHbtB z{tu+1Y`T*f9=2oFL*uF28vN*QO&)ue<_TQnY?G^X*9O*)^c|l};+rtrj-;xZFsG!K zs@>IHkUZchHRrpC-8P)_ow$r$M*ExnqYVK;Txgf_{~n0(Plxrlr~eX`QA_pT0scLf z+uvjXzt9cyZ;{=u3;ug}tG^2}p?%{2cd)DLIM;(4T_L&P{=xZssH5w`*Q4=V37@0a z>d~3Fip_If^m-_hE74PQTpzUP^}r_A0j|@?UjcNI{ww4EK`MV8I`#JzU_M%j(7)?LolW}+Fc-~kfCl^*tH@t)f9DqY!z_Ls z@H+kU6<`7g z+<#F1gQMm;!gbD;D}-Wn$N%@T{(C83N4d^EafL!B@E_&zhl}Dm!gYt{D+D5u|C*0K zmGc+M)h3zi-m+IHr=ovQuKUhj2e`h=<_Z9)dmZ43_G8|1RC<_&4c)TFlqQuUj}*0J1KBa(~Ufxo-dbv3IV6ULWbNKoPEgK&}2h?rW)H UqN6pTC#L8J5Bgn{`|nTx52s7^i2wiq diff --git a/Tests/templates/32readwriteChartLegends1.xlsx b/Tests/templates/32readwriteChartLegends1.xlsx deleted file mode 100644 index 140638c078e10410b64644b01a8f60d9e2fac562..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36990 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 diff --git a/Tests/templates/32readwriteChartTypes1.xlsx b/Tests/templates/32readwriteChartTypes1.xlsx deleted file mode 100644 index 14800c6480d364a1936b678ce10e5899a93fd376..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142966 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 z 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 Date: Sat, 21 Jul 2012 11:52:20 +0100 Subject: [PATCH 04/30] Chart Writing bugfix to refresh values --- Classes/PHPExcel/Chart/DataSeriesValues.php | 23 +++++++++++++++++++-- Classes/PHPExcel/Writer/Excel2007/Chart.php | 22 -------------------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index 90ef6687..6ef5e10d 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -273,14 +273,33 @@ class PHPExcel_Chart_DataSeriesValues return $this; } + private function _stripNulls($var) { + return $var !== NULL; + } + public function refresh(PHPExcel_Worksheet $worksheet) { + echo '$this->_dataSource:',PHP_EOL; + var_dump($this->_dataSource); if ($this->_dataSource !== NULL) { + echo '$this->_dataValues:',PHP_EOL; + var_dump($this->_dataValues); + $calcEngine = PHPExcel_Calculation::getInstance(); - $this->_dataValues = PHPExcel_Calculation::_unwrapResult( + $newDataValues = PHPExcel_Calculation::_unwrapResult( $calcEngine->_calculateFormulaValue( - $this->_dataSource + '='.$this->_dataSource, + NULL, + $worksheet->getCell('A1') ) ); + + echo '$newDataValues:',PHP_EOL; + var_dump($newDataValues); + $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); + $this->_dataValues = array_values(array_shift($newDataValues)); +// $this->_dataValues = array_filter($this->_dataValues,array($this,'_stripNulls')); + echo '$this->_dataValues:',PHP_EOL; + var_dump($this->_dataValues); } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 4a29a59c..2128582b 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -975,17 +975,6 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa $dataValues = $plotSeriesValues->getDataValues(); if (!empty($dataValues)) { -// if (!is_array($dataValues)) { -// echo 'NOT AN ARRAY: '; -// var_dump($dataValues); -// $dataValues = PHPExcel_Calculation_Functions::flattenArray( -// PHPExcel_Calculation::getInstance() -// ->calculateFormula('='.$dataValues, -// NULL, -// $pSheet->getCell('A1') -// ) -// ); -// } if (is_array($dataValues)) { foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { $objWriter->startElement('c:pt'); @@ -1031,17 +1020,6 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa $dataValues = $plotSeriesValues->getDataValues(); if (!empty($dataValues)) { -// if (!is_array($dataValues)) { -// echo 'NOT AN ARRAY: '; -// var_dump($dataValues); -// $dataValues = PHPExcel_Calculation_Functions::flattenArray( -// PHPExcel_Calculation::getInstance() -// ->calculateFormula('='.$dataValues, -// NULL, -// $pSheet->getCell('A1') -// ) -// ); -// } if (is_array($dataValues)) { foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { $objWriter->startElement('c:pt'); From 19dfbfe4189a9cbd81f25bbcde2a6e0341cb5103 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 21 Jul 2012 11:57:02 +0100 Subject: [PATCH 05/30] Remove chart diagnostics from echoes --- Classes/PHPExcel/Chart/DataSeriesValues.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index 6ef5e10d..741e454a 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -278,11 +278,11 @@ class PHPExcel_Chart_DataSeriesValues } public function refresh(PHPExcel_Worksheet $worksheet) { - echo '$this->_dataSource:',PHP_EOL; - var_dump($this->_dataSource); +// echo '$this->_dataSource:',PHP_EOL; +// var_dump($this->_dataSource); if ($this->_dataSource !== NULL) { - echo '$this->_dataValues:',PHP_EOL; - var_dump($this->_dataValues); +// echo '$this->_dataValues:',PHP_EOL; +// var_dump($this->_dataValues); $calcEngine = PHPExcel_Calculation::getInstance(); $newDataValues = PHPExcel_Calculation::_unwrapResult( @@ -293,13 +293,13 @@ class PHPExcel_Chart_DataSeriesValues ) ); - echo '$newDataValues:',PHP_EOL; - var_dump($newDataValues); +// echo '$newDataValues:',PHP_EOL; +// var_dump($newDataValues); $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); $this->_dataValues = array_values(array_shift($newDataValues)); // $this->_dataValues = array_filter($this->_dataValues,array($this,'_stripNulls')); - echo '$this->_dataValues:',PHP_EOL; - var_dump($this->_dataValues); +// echo '$this->_dataValues:',PHP_EOL; +// var_dump($this->_dataValues); } } From 868d14a84d92e893c1a6ab71c03dcca5a6101879 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 23 Jul 2012 12:29:15 +0100 Subject: [PATCH 06/30] Fix to OOCalc Reader for percentage and currency datatypes --- Classes/PHPExcel/Reader/OOCalc.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index ae23016b..ddb56373 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -574,6 +574,22 @@ class PHPExcel_Reader_OOCalc implements PHPExcel_Reader_IReader $type = PHPExcel_Cell_DataType::TYPE_BOOL; $dataValue = ($allCellDataText == 'TRUE') ? True : False; break; + case 'percentage' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + $dataValue = (integer) $dataValue; + } + $formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00; + break; + case 'currency' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + $dataValue = (integer) $dataValue; + } + $formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE; + break; case 'float' : $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; $dataValue = (float) $cellDataOfficeAttributes['value']; @@ -640,8 +656,7 @@ class PHPExcel_Reader_OOCalc implements PHPExcel_Reader_IReader // echo 'Forumla result is '.$dataValue.'
'; $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($dataValue); } - if (($cellDataOfficeAttributes['value-type'] == 'date') || - ($cellDataOfficeAttributes['value-type'] == 'time')) { + if ($formatting !== NULL) { $objPHPExcel->getActiveSheet()->getStyle($columnID.$rowID)->getNumberFormat()->setFormatCode($formatting); } if ($hyperlink !== NULL) { From d9f9fd37f4447d509b754d52d4597f357cc453f5 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 23 Jul 2012 13:03:32 +0100 Subject: [PATCH 07/30] Changelog for OOCalc bugfix --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index f4ed935e..de7e90db 100644 --- a/changelog.txt +++ b/changelog.txt @@ -88,6 +88,7 @@ Fixed in develop branch: - Bugfix: (wackonline) OOCalc Reader fix for NULL cells - Bugfix: (seltzlab) Fix to excel2007 Chart Writer when a $plotSeriesValues is empty - Bugfix: (MBaker) Work item 18370 - Error loading xlsx file with column breaks +- Bugfix: (MBaker) OOCalc Reader now handles percentage and currency data types 2012-05-19 (v1.7.7): From 317f00b25904287e53c4183308029dd64084a4a4 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 23 Jul 2012 21:52:14 +0100 Subject: [PATCH 08/30] Bugfix to ensure that General format is not treated as a date format despite containg e for epoch OOCalc Reader modified to process number-rows-repeated Modify OOCalc Reader to only read cells that containing data, or merged cells (depending on setReadDataOnly setting) --- Classes/PHPExcel/Reader/OOCalc.php | 73 +++++++++++++++++++----------- Classes/PHPExcel/Shared/Date.php | 46 ++++++++++--------- changelog.txt | 1 + 3 files changed, 73 insertions(+), 47 deletions(-) diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index ddb56373..b10043a1 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -319,14 +319,23 @@ class PHPExcel_Reader_OOCalc implements PHPExcel_Reader_IReader foreach ($worksheetData as $key => $rowData) { switch ($key) { case 'table-row' : + $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); + $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? + $rowDataTableAttributes['number-rows-repeated'] : 1; $columnIndex = 0; foreach ($rowData as $key => $cellData) { - $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); - ++$columnIndex; + $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']); + $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? + $cellDataTableAttributes['number-columns-repeated'] : 1; + $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']); + if (isset($cellDataOfficeAttributes['value-type'])) { + $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex + $colRepeats - 1); + $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex + $rowRepeats); + } + $columnIndex += $colRepeats; } - ++$rowIndex; - $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); + $rowIndex += $rowRepeats; break; } } @@ -492,6 +501,9 @@ class PHPExcel_Reader_OOCalc implements PHPExcel_Reader_IReader break; } case 'table-row' : + $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); + $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? + $rowDataTableAttributes['number-rows-repeated'] : 1; $columnID = 'A'; foreach($rowData as $key => $cellData) { if ($this->getReadFilter() !== NULL) { @@ -644,44 +656,53 @@ class PHPExcel_Reader_OOCalc implements PHPExcel_Reader_IReader // echo 'Adjusted Formula: '.$cellDataFormula.'
'; } - $repeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? + $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? $cellDataTableAttributes['number-columns-repeated'] : 1; if ($type !== NULL) { - for ($i = 0; $i < $repeats; ++$i) { + for ($i = 0; $i < $colRepeats; ++$i) { if ($i > 0) { ++$columnID; } - $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type); - if ($hasCalculatedValue) { -// echo 'Forumla result is '.$dataValue.'
'; - $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($dataValue); - } - if ($formatting !== NULL) { - $objPHPExcel->getActiveSheet()->getStyle($columnID.$rowID)->getNumberFormat()->setFormatCode($formatting); - } - if ($hyperlink !== NULL) { - $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->getHyperlink()->setUrl($hyperlink); + if ($type !== PHPExcel_Cell_DataType::TYPE_NULL) { + for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) { + $rID = $rowID + $rowAdjust; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type); + if ($hasCalculatedValue) { +// echo 'Forumla result is '.$dataValue.'
'; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue); + } + if ($formatting !== NULL) { + $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode($formatting); + } else { + $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL); + } + if ($hyperlink !== NULL) { + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->getHyperlink()->setUrl($hyperlink); + } + } } } } // Merged cells if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) { - $columnTo = $columnID; - if (isset($cellDataTableAttributes['number-columns-spanned'])) { - $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2); + if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) { + $columnTo = $columnID; + if (isset($cellDataTableAttributes['number-columns-spanned'])) { + $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2); + } + $rowTo = $rowID; + if (isset($cellDataTableAttributes['number-rows-spanned'])) { + $rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1; + } + $cellRange = $columnID.$rowID.':'.$columnTo.$rowTo; + $objPHPExcel->getActiveSheet()->mergeCells($cellRange); } - $rowTo = $rowID; - if (isset($cellDataTableAttributes['number-rows-spanned'])) { - $rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1; - } - $cellRange = $columnID.$rowID.':'.$columnTo.$rowTo; - $objPHPExcel->getActiveSheet()->mergeCells($cellRange); } ++$columnID; } - ++$rowID; + $rowID += $rowRepeats; break; } } diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index d7b8609d..20c9aeb4 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -88,9 +88,9 @@ class PHPExcel_Shared_Date if (($baseDate == self::CALENDAR_WINDOWS_1900) || ($baseDate == self::CALENDAR_MAC_1904)) { self::$ExcelBaseDate = $baseDate; - return True; + return TRUE; } - return False; + return FALSE; } // function setExcelCalendar() @@ -166,12 +166,12 @@ class PHPExcel_Shared_Date * * @param mixed $dateValue PHP serialized date/time or date object * @return mixed Excel date/time value - * or boolean False on failure + * or boolean FALSE on failure */ public static function PHPToExcel($dateValue = 0) { $saveTimeZone = date_default_timezone_get(); date_default_timezone_set('UTC'); - $retValue = False; + $retValue = FALSE; if ((is_object($dateValue)) && ($dateValue instanceof self::$dateTimeObjectType)) { $retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s') @@ -204,12 +204,12 @@ class PHPExcel_Shared_Date // Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel // This affects every date following 28th February 1900 // - $excel1900isLeapYear = True; - if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = False; } + $excel1900isLeapYear = TRUE; + if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = FALSE; } $myExcelBaseDate = 2415020; } else { $myExcelBaseDate = 2416481; - $excel1900isLeapYear = False; + $excel1900isLeapYear = FALSE; } // Julian base date Adjustment @@ -264,6 +264,10 @@ class PHPExcel_Shared_Date public static function isDateTimeFormatCode($pFormatCode = '') { // Switch on formatcode switch ($pFormatCode) { + // General contains an epoch letter 'e', so we trap for it explicitly here + case PHPExcel_Style_NumberFormat::GENERAL: + return FALSE; + // Explicitly defined date formats case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD: case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2: case PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY: @@ -286,32 +290,32 @@ class PHPExcel_Shared_Date case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16: case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17: case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22: - return true; + return TRUE; } // Typically number, currency or accounting (or occasionally fraction) formats if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) { - return false; + return FALSE; } // Try checking for any of the date formatting characters that don't appear within square braces if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) { // We might also have a format mask containing quoted strings... // we don't want to test for any of our characters within the quoted blocks - if (strpos($pFormatCode,'"') !== false) { - $i = false; + if (strpos($pFormatCode,'"') !== FALSE) { + $i = FALSE; foreach(explode('"',$pFormatCode) as $subVal) { // Only test in alternate array entries (the non-quoted blocks) if (($i = !$i) && (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$subVal))) { - return true; + return TRUE; } } - return false; + return FALSE; } - return true; + return TRUE; } // No date... - return false; + return FALSE; } // function isDateTimeFormatCode() @@ -319,23 +323,23 @@ class PHPExcel_Shared_Date * Convert a date/time string to Excel time * * @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10' - * @return float|false Excel date/time serial value + * @return float|FALSE Excel date/time serial value */ public static function stringToExcel($dateValue = '') { if (strlen($dateValue) < 2) - return false; + return FALSE; if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) - return false; + return FALSE; $dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue); if ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) { - return false; + return FALSE; } else { - if (strpos($dateValue, ':') !== false) { + if (strpos($dateValue, ':') !== FALSE) { $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue); if ($timeValue === PHPExcel_Calculation_Functions::VALUE()) { - return false; + return FALSE; } $dateValueNew += $timeValue; } diff --git a/changelog.txt b/changelog.txt index de7e90db..092b3eba 100644 --- a/changelog.txt +++ b/changelog.txt @@ -89,6 +89,7 @@ Fixed in develop branch: - Bugfix: (seltzlab) Fix to excel2007 Chart Writer when a $plotSeriesValues is empty - Bugfix: (MBaker) Work item 18370 - Error loading xlsx file with column breaks - Bugfix: (MBaker) OOCalc Reader now handles percentage and currency data types +- Bugfix: (MBaker) OOCalc Reader modified to process number-rows-repeated 2012-05-19 (v1.7.7): From dbe12c73a2b64a75212167e8705072c74a821cd6 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 24 Jul 2012 07:39:36 +0100 Subject: [PATCH 09/30] Formatting constant GENERAL should be FORMAT_GENERAL --- Classes/PHPExcel/Shared/Date.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index 20c9aeb4..071b988c 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -265,7 +265,7 @@ class PHPExcel_Shared_Date // Switch on formatcode switch ($pFormatCode) { // General contains an epoch letter 'e', so we trap for it explicitly here - case PHPExcel_Style_NumberFormat::GENERAL: + case PHPExcel_Style_NumberFormat::FORMAT_GENERAL: return FALSE; // Explicitly defined date formats case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD: From b7dfeb9bb7b3e4328fe0c1fcf43490a3e2c2113f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 24 Jul 2012 13:21:31 +0100 Subject: [PATCH 10/30] Unit Tests for Date helper functions --- unitTests/PHPExcel/Shared/DateTest.php | 69 +++++++++++++++++++ .../Shared/DateTimeExcelToPHP1900.data | 6 +- .../Shared/DateTimeExcelToPHP1904.data | 3 + .../DateTimeFormattedPHPToExcel1900.data | 12 ++++ .../Shared/DateTimePHPToExcel1900.data | 12 ++++ .../Shared/DateTimePHPToExcel1904.data | 7 ++ 6 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 unitTests/rawTestData/Shared/DateTimeFormattedPHPToExcel1900.data create mode 100644 unitTests/rawTestData/Shared/DateTimePHPToExcel1900.data create mode 100644 unitTests/rawTestData/Shared/DateTimePHPToExcel1904.data diff --git a/unitTests/PHPExcel/Shared/DateTest.php b/unitTests/PHPExcel/Shared/DateTest.php index 6ee3b957..ea6991e6 100644 --- a/unitTests/PHPExcel/Shared/DateTest.php +++ b/unitTests/PHPExcel/Shared/DateTest.php @@ -46,6 +46,9 @@ class DateTest extends PHPUnit_Framework_TestCase $args = func_get_args(); $expectedResult = array_pop($args); + if ($args[0] < 1) { + $expectedResult += gmmktime(0,0,0); + } $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); $this->assertEquals($expectedResult, $result); } @@ -55,6 +58,48 @@ class DateTest extends PHPUnit_Framework_TestCase return new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1900.data'); } + /** + * @dataProvider providerDateTimePHPToExcel1900 + */ + public function testDateTimePHPToExcel1900() + { + $result = call_user_func( + array('PHPExcel_Shared_Date','setExcelCalendar'), + PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 + ); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-5); + } + + public function providerDateTimePHPToExcel1900() + { + return new testDataFileIterator('rawTestData/Shared/DateTimePHPToExcel1900.data'); + } + + /** + * @dataProvider providerDateTimeFormattedPHPToExcel1900 + */ + public function testDateTimeFormattedPHPToExcel1900() + { + $result = call_user_func( + array('PHPExcel_Shared_Date','setExcelCalendar'), + PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 + ); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','FormattedPHPToExcel'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-5); + } + + public function providerDateTimeFormattedPHPToExcel1900() + { + return new testDataFileIterator('rawTestData/Shared/DateTimeFormattedPHPToExcel1900.data'); + } + /** * @dataProvider providerDateTimeExcelToPHP1904 */ @@ -67,6 +112,9 @@ class DateTest extends PHPUnit_Framework_TestCase $args = func_get_args(); $expectedResult = array_pop($args); + if ($args[0] < 1) { + $expectedResult += gmmktime(0,0,0); + } $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); $this->assertEquals($expectedResult, $result); } @@ -76,6 +124,27 @@ class DateTest extends PHPUnit_Framework_TestCase return new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1904.data'); } + /** + * @dataProvider providerDateTimePHPToExcel1904 + */ + public function testDateTimePHPToExcel1904() + { + $result = call_user_func( + array('PHPExcel_Shared_Date','setExcelCalendar'), + PHPExcel_Shared_Date::CALENDAR_MAC_1904 + ); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-5); + } + + public function providerDateTimePHPToExcel1904() + { + return new testDataFileIterator('rawTestData/Shared/DateTimePHPToExcel1904.data'); + } + /** * @dataProvider providerIsDateTimeFormatCode */ diff --git a/unitTests/rawTestData/Shared/DateTimeExcelToPHP1900.data b/unitTests/rawTestData/Shared/DateTimeExcelToPHP1900.data index 85497b89..d348b0aa 100644 --- a/unitTests/rawTestData/Shared/DateTimeExcelToPHP1900.data +++ b/unitTests/rawTestData/Shared/DateTimeExcelToPHP1900.data @@ -10,6 +10,6 @@ 50424, 2147472000 // PHP 32-bit Latest Date 19-Jan-2038 1234.56789, -2102494934 // 18-May-1903 13:37:46 12345.6789, -1142494943 // 18-Oct-1933 16:17:37 -0.5, 1340539200 // 12:00:00 -0.75, 1340560800 // 18:00.00 -0.12345, 1340506666 // 02:57:46 +0.5, 43200 // 12:00:00 +0.75, 64800 // 18:00.00 +0.12345, 10666 // 02:57:46 diff --git a/unitTests/rawTestData/Shared/DateTimeExcelToPHP1904.data b/unitTests/rawTestData/Shared/DateTimeExcelToPHP1904.data index b30cff3e..5501ad17 100644 --- a/unitTests/rawTestData/Shared/DateTimeExcelToPHP1904.data +++ b/unitTests/rawTestData/Shared/DateTimeExcelToPHP1904.data @@ -5,3 +5,6 @@ 25569, 126316800 30292, 534384000 39611, 1339545600 +0.25, 21600 // 06:00:00 +0.3333333333333333333, 28800 // 08:00.00 +0.54321, 46933 // 02:57:46 diff --git a/unitTests/rawTestData/Shared/DateTimeFormattedPHPToExcel1900.data b/unitTests/rawTestData/Shared/DateTimeFormattedPHPToExcel1900.data new file mode 100644 index 00000000..bb6ed3f4 --- /dev/null +++ b/unitTests/rawTestData/Shared/DateTimeFormattedPHPToExcel1900.data @@ -0,0 +1,12 @@ +#Year Month Day Hours Minutes Seconds Result Comments +1901, 12, 14, 714 // PHP 32-bit Earliest Date 14-Dec-1901 +1903, 12, 31, 1461 // 31-Dec-1903 +1904, 1, 1, 1462 // Excel 1904 Calendar Base Date 01-Jan-1904 +1904, 1, 2, 1463 // 02-Jan-1904 +1960, 12, 19, 22269 // 19-Dec-1960 +1970, 1, 1, 25569 // PHP Base Date 01-Jan-1970 +1982, 12, 7, 30292 // 07-Dec-1982 +2008, 6, 12, 39611 // 12-Jun-2008 +2038, 1, 19, 50424 // PHP 32-bit Latest Date 19-Jan-2038 +1903, 5, 18, 13, 37, 46, 1234.56789 // 18-May-1903 13:37:46 +1933, 10, 18, 16, 17, 37, 12345.6789 // 18-Oct-1933 16:17:37 diff --git a/unitTests/rawTestData/Shared/DateTimePHPToExcel1900.data b/unitTests/rawTestData/Shared/DateTimePHPToExcel1900.data new file mode 100644 index 00000000..dc6a9d90 --- /dev/null +++ b/unitTests/rawTestData/Shared/DateTimePHPToExcel1900.data @@ -0,0 +1,12 @@ +#Excel DateTimeStamp Result Comments +-2147472000, 714 // PHP 32-bit Earliest Date 14-Dec-1901 +-2082931200, 1461 // 31-Dec-1903 +-2082844800, 1462 // Excel 1904 Calendar Base Date 01-Jan-1904 +-2082758400, 1463 // 02-Jan-1904 +-285120000, 22269 // 19-Dec-1960 +0, 25569 // PHP Base Date 01-Jan-1970 +408067200, 30292 // 07-Dec-1982 +1213228800, 39611 // 12-Jun-2008 +2147472000, 50424 // PHP 32-bit Latest Date 19-Jan-2038 +-2102494934, 1234.56789 // 18-May-1903 13:37:46 +-1142494943, 12345.6789 // 18-Oct-1933 16:17:37 diff --git a/unitTests/rawTestData/Shared/DateTimePHPToExcel1904.data b/unitTests/rawTestData/Shared/DateTimePHPToExcel1904.data new file mode 100644 index 00000000..98fa4951 --- /dev/null +++ b/unitTests/rawTestData/Shared/DateTimePHPToExcel1904.data @@ -0,0 +1,7 @@ +#Excel DateTimeStamp Result +-1956528000, 1462 +-1956441600, 1463 +-158803200, 22269 +126316800, 25569 +534384000, 30292 +1339545600, 39611 From 013c18b85958942fc4984b855af416322c654245 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 25 Jul 2012 13:15:27 +0100 Subject: [PATCH 11/30] General - merged (with some localisation mods) from a pull request by alexgann - Add Currency detection to the Advanced Value Binder --- Classes/PHPExcel/Cell/AdvancedValueBinder.php | 20 ++++++++++ Classes/PHPExcel/Shared/String.php | 6 +-- Tests/29advancedvaluebinder.php | 39 ++++++++++--------- changelog.txt | 1 + 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/Classes/PHPExcel/Cell/AdvancedValueBinder.php b/Classes/PHPExcel/Cell/AdvancedValueBinder.php index cf0ed140..17a7334f 100644 --- a/Classes/PHPExcel/Cell/AdvancedValueBinder.php +++ b/Classes/PHPExcel/Cell/AdvancedValueBinder.php @@ -88,6 +88,26 @@ class PHPExcel_Cell_AdvancedValueBinder extends PHPExcel_Cell_DefaultValueBinder return true; } + // Check for currency + $currencyCode = PHPExcel_Shared_String::getCurrencyCode(); + if (preg_match('/^'.preg_quote($currencyCode).' ?(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/', $value)) { + // Convert value to number + $cell->setValueExplicit( trim(str_replace($currencyCode, '', $value)), PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getParent()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( + str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE ) + ); + return true; + } elseif (preg_match('/^\$ ?(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/', $value)) { + // Convert value to number + $cell->setValueExplicit( trim(str_replace('$', '', $value)), PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getParent()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE ); + return true; + } + // Check for time without seconds e.g. '9:45', '09:45' if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d$/', $value)) { list($h, $m) = explode(':', $value); diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index a8753418..cee3ea4e 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -612,7 +612,7 @@ class PHPExcel_Shared_String { if (!isset(self::$_decimalSeparator)) { $localeconv = localeconv(); - self::$_decimalSeparator = $localeconv['decimal_point'] != '' + self::$_decimalSeparator = ($localeconv['decimal_point'] != '') ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point']; if (self::$_decimalSeparator == '') { @@ -644,7 +644,7 @@ class PHPExcel_Shared_String { if (!isset(self::$_thousandsSeparator)) { $localeconv = localeconv(); - self::$_thousandsSeparator = $localeconv['thousands_sep'] != '' + self::$_thousandsSeparator = ($localeconv['thousands_sep'] != '') ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep']; } return self::$_thousandsSeparator; @@ -671,7 +671,7 @@ class PHPExcel_Shared_String { if (!isset(self::$_currencyCode)) { $localeconv = localeconv(); - self::$_currencyCode = $localeconv['currency_symbol'] != '' + self::$_currencyCode = ($localeconv['currency_symbol'] != '') ? $localeconv['currency_symbol'] : $localeconv['int_curr_symbol']; if (self::$_currencyCode == '') { diff --git a/Tests/29advancedvaluebinder.php b/Tests/29advancedvaluebinder.php index c58911b1..e2e7d127 100644 --- a/Tests/29advancedvaluebinder.php +++ b/Tests/29advancedvaluebinder.php @@ -104,32 +104,35 @@ $objPHPExcel->getActiveSheet()->setCellValue('B11', '10%'); $objPHPExcel->getActiveSheet()->setCellValue('A12', 'Percentage value #2:'); $objPHPExcel->getActiveSheet()->setCellValue('B12', '12.5%'); -$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Date value #1:'); -$objPHPExcel->getActiveSheet()->setCellValue('B13', '21 December 1983'); +$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Currency value:'); +$objPHPExcel->getActiveSheet()->setCellValue('B13', '$12345'); -$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Date value #2:'); -$objPHPExcel->getActiveSheet()->setCellValue('B14', '19-Dec-1960'); +$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Date value #1:'); +$objPHPExcel->getActiveSheet()->setCellValue('B14', '21 December 1983'); -$objPHPExcel->getActiveSheet()->setCellValue('A15', 'Date value #3:'); -$objPHPExcel->getActiveSheet()->setCellValue('B15', '19/12/1960'); +$objPHPExcel->getActiveSheet()->setCellValue('A15', 'Date value #2:'); +$objPHPExcel->getActiveSheet()->setCellValue('B15', '19-Dec-1960'); -$objPHPExcel->getActiveSheet()->setCellValue('A16', 'Date value #4:'); -$objPHPExcel->getActiveSheet()->setCellValue('B16', '19-12-1960'); +$objPHPExcel->getActiveSheet()->setCellValue('A16', 'Date value #3:'); +$objPHPExcel->getActiveSheet()->setCellValue('B16', '19/12/1960'); -$objPHPExcel->getActiveSheet()->setCellValue('A17', 'Date value #5:'); -$objPHPExcel->getActiveSheet()->setCellValue('B17', '1-Jan'); +$objPHPExcel->getActiveSheet()->setCellValue('A17', 'Date value #4:'); +$objPHPExcel->getActiveSheet()->setCellValue('B17', '19-12-1960'); -$objPHPExcel->getActiveSheet()->setCellValue('A18', 'Time value #1:'); -$objPHPExcel->getActiveSheet()->setCellValue('B18', '01:30'); +$objPHPExcel->getActiveSheet()->setCellValue('A18', 'Date value #5:'); +$objPHPExcel->getActiveSheet()->setCellValue('B18', '1-Jan'); -$objPHPExcel->getActiveSheet()->setCellValue('A19', 'Time value #2:'); -$objPHPExcel->getActiveSheet()->setCellValue('B19', '01:30:15'); +$objPHPExcel->getActiveSheet()->setCellValue('A19', 'Time value #1:'); +$objPHPExcel->getActiveSheet()->setCellValue('B19', '01:30'); -$objPHPExcel->getActiveSheet()->setCellValue('A20', 'Date/Time value:'); -$objPHPExcel->getActiveSheet()->setCellValue('B20', '19-Dec-1960 01:30'); +$objPHPExcel->getActiveSheet()->setCellValue('A20', 'Time value #2:'); +$objPHPExcel->getActiveSheet()->setCellValue('B20', '01:30:15'); -$objPHPExcel->getActiveSheet()->setCellValue('A21', 'Formula:'); -$objPHPExcel->getActiveSheet()->setCellValue('B21', '=SUM(B2:B9)'); +$objPHPExcel->getActiveSheet()->setCellValue('A21', 'Date/Time value:'); +$objPHPExcel->getActiveSheet()->setCellValue('B21', '19-Dec-1960 01:30'); + +$objPHPExcel->getActiveSheet()->setCellValue('A22', 'Formula:'); +$objPHPExcel->getActiveSheet()->setCellValue('B22', '=SUM(B2:B9)'); // Rename worksheet echo date('H:i:s') , " Rename worksheet" , PHP_EOL; diff --git a/changelog.txt b/changelog.txt index 092b3eba..dea27dd3 100644 --- a/changelog.txt +++ b/changelog.txt @@ -79,6 +79,7 @@ Fixed in develop branch: - Feature: (MBaker) Initial version of HTML Reader - Feature: (Progi1984) & (blazzy) Work items 9605 - Implement support for AutoFilter in PHPExcel_Writer_Excel5 - Feature: (MBaker) Modified ERF and ERFC Engineering functions to accept Excel 2010's modified acceptance of negative arguments +- General: (alexgann) Add Currency detection to the Advanced Value Binder - Bugfix: (cyberconte) Patch 12318 - OOCalc cells containing inside the tag - Bugfix: (schir1964) Fix to listWorksheetInfo() method for OOCalc Reader - Bugfix: (MBaker) Support for "e" (epoch) date format mask From 8e41c70d415e33e22ec82c51ab80e6654a400c8d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 25 Jul 2012 23:54:53 +0100 Subject: [PATCH 12/30] General: Work item 18404 - setCellValueExplicitByColumnAndRow() do not return PHPExcel_Worksheet --- Classes/PHPExcel/Worksheet.php | 29 ++++++++++++----------------- changelog.txt | 1 + 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index eb90590f..45556764 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1024,11 +1024,7 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = false) { $cell = $this->getCell($pCoordinate)->setValue($pValue); - - if ($returnCell) { - return $cell; - } - return $this; + return ($returnCell) ? $cell : $this; } /** @@ -1043,11 +1039,7 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $returnCell = false) { $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValue($pValue); - - if ($returnCell) { - return $cell; - } - return $this; + return ($returnCell) ? $cell : $this; } /** @@ -1056,13 +1048,14 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable * @param string $pCoordinate Coordinate of the cell * @param mixed $pValue Value of the cell * @param string $pDataType Explicit data type - * @return PHPExcel_Worksheet + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified */ - public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) + public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) { // Set value - $this->getCell($pCoordinate)->setValueExplicit($pValue, $pDataType); - return $this; + $cell = $this->getCell($pCoordinate)->setValueExplicit($pValue, $pDataType); + return ($returnCell) ? $cell : $this; } /** @@ -1072,11 +1065,13 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable * @param string $pRow Numeric row coordinate of the cell * @param mixed $pValue Value of the cell * @param string $pDataType Explicit data type - * @return PHPExcel_Worksheet + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified */ - public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) + public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) { - return $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValueExplicit($pValue, $pDataType); + $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValueExplicit($pValue, $pDataType); + return ($returnCell) ? $cell : $this; } /** diff --git a/changelog.txt b/changelog.txt index dea27dd3..1ac81085 100644 --- a/changelog.txt +++ b/changelog.txt @@ -80,6 +80,7 @@ Fixed in develop branch: - Feature: (Progi1984) & (blazzy) Work items 9605 - Implement support for AutoFilter in PHPExcel_Writer_Excel5 - Feature: (MBaker) Modified ERF and ERFC Engineering functions to accept Excel 2010's modified acceptance of negative arguments - General: (alexgann) Add Currency detection to the Advanced Value Binder +- General: (MBaker) Work item 18404 - setCellValueExplicitByColumnAndRow() do not return PHPExcel_Worksheet - Bugfix: (cyberconte) Patch 12318 - OOCalc cells containing inside the tag - Bugfix: (schir1964) Fix to listWorksheetInfo() method for OOCalc Reader - Bugfix: (MBaker) Support for "e" (epoch) date format mask From b871674f185c1b657761961908a3e0a057c53f6b Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 26 Jul 2012 20:04:52 +0100 Subject: [PATCH 13/30] Ensure that chart worksheet is correctly set when adding chart to a worksheet --- Classes/PHPExcel/Worksheet.php | 1 + changelog.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 45556764..f997b638 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -525,6 +525,7 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable */ public function addChart(PHPExcel_Chart $pChart = null, $iChartIndex = null) { + $pChart->setWorksheet($this); if (is_null($iChartIndex)) { $this->_chartCollection[] = $pChart; } else { diff --git a/changelog.txt b/changelog.txt index 1ac81085..6d0c51bc 100644 --- a/changelog.txt +++ b/changelog.txt @@ -89,6 +89,7 @@ Fixed in develop branch: - Bugfix: (MBaker) Work items 15905 and 18183 - Allow "no impact" to formats on Conditional Formatting - Bugfix: (wackonline) OOCalc Reader fix for NULL cells - Bugfix: (seltzlab) Fix to excel2007 Chart Writer when a $plotSeriesValues is empty +- Bugfix: (MBaker) Various fixes to Chart handling - Bugfix: (MBaker) Work item 18370 - Error loading xlsx file with column breaks - Bugfix: (MBaker) OOCalc Reader now handles percentage and currency data types - Bugfix: (MBaker) OOCalc Reader modified to process number-rows-repeated From 8ab0200584d11bc270ee0b57abada71713fb7c9b Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 27 Jul 2012 12:22:47 +0100 Subject: [PATCH 14/30] Further chart bugfixes, plus an example of changing chart data for use in templates --- Classes/PHPExcel/Chart/DataSeriesValues.php | 11 --- Classes/PHPExcel/Writer/Excel2007/Chart.php | 3 +- Tests/33chartcreate.php | 2 +- Tests/34chartupdate.php | 75 +++++++++++++++++++++ 4 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 Tests/34chartupdate.php diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index 741e454a..8ae4d0c1 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -278,12 +278,7 @@ class PHPExcel_Chart_DataSeriesValues } public function refresh(PHPExcel_Worksheet $worksheet) { -// echo '$this->_dataSource:',PHP_EOL; -// var_dump($this->_dataSource); if ($this->_dataSource !== NULL) { -// echo '$this->_dataValues:',PHP_EOL; -// var_dump($this->_dataValues); - $calcEngine = PHPExcel_Calculation::getInstance(); $newDataValues = PHPExcel_Calculation::_unwrapResult( $calcEngine->_calculateFormulaValue( @@ -293,13 +288,7 @@ class PHPExcel_Chart_DataSeriesValues ) ); -// echo '$newDataValues:',PHP_EOL; -// var_dump($newDataValues); $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); - $this->_dataValues = array_values(array_shift($newDataValues)); -// $this->_dataValues = array_filter($this->_dataValues,array($this,'_stripNulls')); -// echo '$this->_dataValues:',PHP_EOL; -// var_dump($this->_dataValues); } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 2128582b..7316d8dc 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -962,7 +962,8 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa ($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($groupType != PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { - if ($plotSeriesValues->getFormatCode() !== NULL) { + if (($plotSeriesValues->getFormatCode() !== NULL) && + ($plotSeriesValues->getFormatCode() !== '')) { $objWriter->startElement('c:formatCode'); $objWriter->writeRawData( $plotSeriesValues->getFormatCode() ); $objWriter->endElement(); diff --git a/Tests/33chartcreate.php b/Tests/33chartcreate.php index f688b01c..47aab30d 100644 --- a/Tests/33chartcreate.php +++ b/Tests/33chartcreate.php @@ -28,7 +28,7 @@ date_default_timezone_set('Europe/London'); * @package PHPExcel * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version 1.7.7, 2012-05-19 + * @version ##VERSION##, ##DATE## */ /** Include path **/ diff --git a/Tests/34chartupdate.php b/Tests/34chartupdate.php new file mode 100644 index 00000000..79b509fb --- /dev/null +++ b/Tests/34chartupdate.php @@ -0,0 +1,75 @@ +setIncludeCharts(TRUE); +$objPHPExcel = $objReader->load("33chartcreate.xlsx"); + + +echo date('H:i:s') , " Update cell data values that are displayed in the chart" , PHP_EOL; +$objWorksheet = $objPHPExcel->getActiveSheet(); +$objWorksheet->fromArray( + array( + array(50-12, 50-15, 50-21), + array(50-56, 50-73, 50-86), + array(50-52, 50-61, 50-69), + array(50-30, 50-32, 50), + ), + NULL, + 'B2' +); + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->setIncludeCharts(TRUE); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , PHP_EOL; From 8f3dc270a6a6068b7a0489b334eb41eeb6a4ce1d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 27 Jul 2012 22:06:28 +0100 Subject: [PATCH 15/30] Bugfix: Work Item 18415- mb_stripos empty delimiter --- Classes/PHPExcel/Calculation/TextData.php | 12 +++++++++--- changelog.txt | 2 +- unitTests/rawTestData/Calculation/TextData/FIND.data | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php index aceafc63..3c3ed22a 100644 --- a/Classes/PHPExcel/Calculation/TextData.php +++ b/Classes/PHPExcel/Calculation/TextData.php @@ -239,9 +239,12 @@ class PHPExcel_Calculation_TextData { $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); } - if (($offset > 0) && (strlen($haystack) > $offset)) { + if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { + if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { + return $offset; + } if (function_exists('mb_strpos')) { - $pos = mb_strpos($haystack, $needle, --$offset,'UTF-8'); + $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8'); } else { $pos = strpos($haystack, $needle, --$offset); } @@ -272,7 +275,10 @@ class PHPExcel_Calculation_TextData { $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); } - if (($offset > 0) && (strlen($haystack) > $offset)) { + if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { + if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { + return $offset; + } if (function_exists('mb_stripos')) { $pos = mb_stripos($haystack, $needle, --$offset,'UTF-8'); } else { diff --git a/changelog.txt b/changelog.txt index 6d0c51bc..c8ab3613 100644 --- a/changelog.txt +++ b/changelog.txt @@ -92,7 +92,7 @@ Fixed in develop branch: - Bugfix: (MBaker) Various fixes to Chart handling - Bugfix: (MBaker) Work item 18370 - Error loading xlsx file with column breaks - Bugfix: (MBaker) OOCalc Reader now handles percentage and currency data types -- Bugfix: (MBaker) OOCalc Reader modified to process number-rows-repeated +- Bugfix: (MBaker) Work Item 18415- mb_stripos empty delimiter 2012-05-19 (v1.7.7): diff --git a/unitTests/rawTestData/Calculation/TextData/FIND.data b/unitTests/rawTestData/Calculation/TextData/FIND.data index 677d4f0d..411150da 100644 --- a/unitTests/rawTestData/Calculation/TextData/FIND.data +++ b/unitTests/rawTestData/Calculation/TextData/FIND.data @@ -9,3 +9,5 @@ "k", "Mark Baker", 5, 8 "a", "Mark Baker", 3, 7 "BITE", "BIT", "#VALUE!" +"", "Mark Baker", 1 +"", "Mark Baker", 8, 8 From 6a14bdce4cc9309bef128860d6d66875b89808ee Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 29 Jul 2012 20:56:35 +0100 Subject: [PATCH 16/30] Unit tests for Cell static methods and creation of PHPExcel_Exception rather than use of standard Exception --- Classes/PHPExcel/Cell.php | 445 +++++++++--------- Classes/PHPExcel/Exception.php | 52 ++ unitTests/PHPExcel/CellTest.php | 259 ++++++++++ .../rawTestData/CellAbsoluteCoordinate.data | 12 + .../rawTestData/CellAbsoluteReference.data | 16 + unitTests/rawTestData/CellBuildRange.data | 2 + unitTests/rawTestData/CellCoordinates.data | 6 + .../rawTestData/CellRangeBoundaries.data | 2 + unitTests/rawTestData/CellRangeDimension.data | 2 + unitTests/rawTestData/CellSplitRange.data | 3 + unitTests/rawTestData/ColumnIndex.data | 9 + unitTests/rawTestData/ColumnString.data | 9 + 12 files changed, 606 insertions(+), 211 deletions(-) create mode 100644 Classes/PHPExcel/Exception.php create mode 100644 unitTests/PHPExcel/CellTest.php create mode 100644 unitTests/rawTestData/CellAbsoluteCoordinate.data create mode 100644 unitTests/rawTestData/CellAbsoluteReference.data create mode 100644 unitTests/rawTestData/CellBuildRange.data create mode 100644 unitTests/rawTestData/CellCoordinates.data create mode 100644 unitTests/rawTestData/CellRangeBoundaries.data create mode 100644 unitTests/rawTestData/CellRangeDimension.data create mode 100644 unitTests/rawTestData/CellSplitRange.data create mode 100644 unitTests/rawTestData/ColumnIndex.data create mode 100644 unitTests/rawTestData/ColumnString.data diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index b6c8fcf8..e63d821b 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -1,108 +1,112 @@ _parent->getCellCacheController()->updateCacheData($this); @@ -110,7 +114,7 @@ class PHPExcel_Cell } public function detach() { - $this->_parent = null; + $this->_parent = NULL; } public function attach($parent) { @@ -119,16 +123,16 @@ class PHPExcel_Cell /** - * Create a new Cell + * Create a new Cell * - * @param string $pColumn - * @param int $pRow - * @param mixed $pValue - * @param string $pDataType - * @param PHPExcel_Worksheet $pSheet - * @throws Exception + * @param string $pColumn + * @param int $pRow + * @param mixed $pValue + * @param string $pDataType + * @param PHPExcel_Worksheet $pSheet + * @throws PHPExcel_Exception */ - public function __construct($pColumn = 'A', $pRow = 1, $pValue = null, $pDataType = null, PHPExcel_Worksheet $pSheet = null) + public function __construct($pColumn = 'A', $pRow = 1, $pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL) { // Initialise cell coordinate $this->_column = strtoupper($pColumn); @@ -141,13 +145,13 @@ class PHPExcel_Cell $this->_parent = $pSheet; // Set datatype? - if ($pDataType !== null) { + if ($pDataType !== NULL) { if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; $this->_dataType = $pDataType; } else { if (!self::getValueBinder()->bindValue($this, $pValue)) { - throw new Exception("Value could not be bound to cell."); + throw new PHPExcel_Exception("Value could not be bound to cell."); } } @@ -156,9 +160,9 @@ class PHPExcel_Cell } /** - * Get cell coordinate column + * Get cell coordinate column * - * @return string + * @return string */ public function getColumn() { @@ -166,9 +170,9 @@ class PHPExcel_Cell } /** - * Get cell coordinate row + * Get cell coordinate row * - * @return int + * @return int */ public function getRow() { @@ -176,9 +180,9 @@ class PHPExcel_Cell } /** - * Get cell coordinate + * Get cell coordinate * - * @return string + * @return string */ public function getCoordinate() { @@ -186,9 +190,9 @@ class PHPExcel_Cell } /** - * Get cell value + * Get cell value * - * @return mixed + * @return mixed */ public function getValue() { @@ -196,42 +200,45 @@ class PHPExcel_Cell } /** - * Get cell value with formatting + * Get cell value with formatting * - * @return string + * @return string */ public function getFormattedValue() { - return (string) PHPExcel_Style_NumberFormat::toFormattedString( $this->getCalculatedValue(), - $this->_parent->getParent()->getCellXfByIndex($this->getXfIndex())->getNumberFormat()->getFormatCode() - ); + return (string) PHPExcel_Style_NumberFormat::toFormattedString( + $this->getCalculatedValue(), + $this->_parent->getParent()->getCellXfByIndex($this->getXfIndex()) + ->getNumberFormat()->getFormatCode() + ); } /** - * Set cell value + * Set cell value * - * Sets the value for a cell, automatically determining the datatype using the value binder + * Sets the value for a cell, automatically determining the datatype using the value binder * - * @param mixed $pValue Value - * @return PHPExcel_Cell + * @param mixed $pValue Value + * @return PHPExcel_Cell + * @throws PHPExcel_Exception */ - public function setValue($pValue = null) + public function setValue($pValue = NULL) { if (!self::getValueBinder()->bindValue($this, $pValue)) { - throw new Exception("Value could not be bound to cell."); + throw new PHPExcel_Exception("Value could not be bound to cell."); } return $this; } /** - * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder) + * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder) * - * @param mixed $pValue Value - * @param string $pDataType Explicit data type - * @return PHPExcel_Cell - * @throws Exception + * @param mixed $pValue Value + * @param string $pDataType Explicit data type + * @return PHPExcel_Cell + * @throws PHPExcel_Exception */ - public function setValueExplicit($pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) + public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) { // set the value according to data type switch ($pDataType) { @@ -242,25 +249,20 @@ class PHPExcel_Cell case PHPExcel_Cell_DataType::TYPE_INLINE: $this->_value = PHPExcel_Cell_DataType::checkString($pValue); break; - case PHPExcel_Cell_DataType::TYPE_NUMERIC: $this->_value = (float)$pValue; break; - case PHPExcel_Cell_DataType::TYPE_FORMULA: $this->_value = (string)$pValue; break; - case PHPExcel_Cell_DataType::TYPE_BOOL: $this->_value = (bool)$pValue; break; - case PHPExcel_Cell_DataType::TYPE_ERROR: $this->_value = PHPExcel_Cell_DataType::checkErrorCode($pValue); break; - default: - throw new Exception('Invalid datatype: ' . $pDataType); + throw new PHPExcel_Exception('Invalid datatype: ' . $pDataType); break; } @@ -271,13 +273,14 @@ class PHPExcel_Cell } /** - * Get calculated cell value + * Get calculated cell value * * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling * - * @return mixed + * @return mixed + * @throws PHPExcel_Exception */ - public function getCalculatedValue($resetLog=true) + public function getCalculatedValue($resetLog = TRUE) { // echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().'
'; if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { @@ -292,7 +295,11 @@ class PHPExcel_Cell } // echo 'Calculation Exception: '.$ex->getMessage().'
'; $result = '#N/A'; - throw(new Exception($this->getParent()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage())); + throw( + new PHPExcel_Exception( + $this->getParent()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage() + ) + ); } if ($result === '#Not Yet Implemented') { @@ -305,21 +312,19 @@ class PHPExcel_Cell // if ($this->_value === NULL) { // echo 'Cell '.$this->getCoordinate().' has no value, formula or otherwise
'; -// return null; +// return NULL; // } // echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'
'; return $this->_value; } /** - * Set calculated value (used for caching) + * Set old calculated value (cached) * - * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling - * - * @param mixed $pValue Value - * @return PHPExcel_Cell + * @param mixed $pValue Value + * @return PHPExcel_Cell */ - public function setCalculatedValue($pValue = null) + public function setCalculatedValue($pValue = NULL) { if ($pValue !== NULL) { $this->_calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue; @@ -329,9 +334,14 @@ class PHPExcel_Cell } /** - * Get old calculated value (cached) + * Get old calculated value (cached) + * This returns the value last calculated by MS Excel or whichever spreadsheet program was used to + * create the original spreadsheet file. + * Note that this value is not guaranteed to refelect the actual calculated value because it is + * possible that auto-calculation was disabled in the original spreadsheet, and underlying data + * values used by the formula have changed since it was last calculated. * - * @return mixed + * @return mixed */ public function getOldCalculatedValue() { @@ -339,9 +349,9 @@ class PHPExcel_Cell } /** - * Get cell data type + * Get cell data type * - * @return string + * @return string */ public function getDataType() { @@ -349,10 +359,10 @@ class PHPExcel_Cell } /** - * Set cell data type + * Set cell data type * - * @param string $pDataType - * @return PHPExcel_Cell + * @param string $pDataType + * @return PHPExcel_Cell */ public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING) { @@ -365,44 +375,46 @@ class PHPExcel_Cell } /** - * Has Data validation? + * Does this cell contain Data validation rules? * - * @return boolean + * @return boolean + * @throws PHPExcel_Exception */ public function hasDataValidation() { if (!isset($this->_parent)) { - throw new Exception('Cannot check for data validation when cell is not bound to a worksheet'); + throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet'); } return $this->_parent->dataValidationExists($this->getCoordinate()); } /** - * Get Data validation + * Get Data validation rules * - * @return PHPExcel_Cell_DataValidation + * @return PHPExcel_Cell_DataValidation + * @throws PHPExcel_Exception */ public function getDataValidation() { if (!isset($this->_parent)) { - throw new Exception('Cannot get data validation for cell that is not bound to a worksheet'); + throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet'); } return $this->_parent->getDataValidation($this->getCoordinate()); } /** - * Set Data validation + * Set Data validation rules * - * @param PHPExcel_Cell_DataValidation $pDataValidation - * @throws Exception - * @return PHPExcel_Cell + * @param PHPExcel_Cell_DataValidation $pDataValidation + * @return PHPExcel_Cell + * @throws PHPExcel_Exception */ - public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = null) + public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = NULL) { if (!isset($this->_parent)) { - throw new Exception('Cannot set data validation for cell that is not bound to a worksheet'); + throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet'); } $this->_parent->setDataValidation($this->getCoordinate(), $pDataValidation); @@ -411,45 +423,46 @@ class PHPExcel_Cell } /** - * Has Hyperlink + * Does this cell contain a Hyperlink? * - * @return boolean + * @return boolean + * @throws PHPExcel_Exception */ public function hasHyperlink() { if (!isset($this->_parent)) { - throw new Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); + throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); } return $this->_parent->hyperlinkExists($this->getCoordinate()); } /** - * Get Hyperlink + * Get Hyperlink * - * @throws Exception - * @return PHPExcel_Cell_Hyperlink + * @return PHPExcel_Cell_Hyperlink + * @throws PHPExcel_Exception */ public function getHyperlink() { if (!isset($this->_parent)) { - throw new Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); + throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); } return $this->_parent->getHyperlink($this->getCoordinate()); } /** - * Set Hyperlink + * Set Hyperlink * - * @param PHPExcel_Cell_Hyperlink $pHyperlink - * @throws Exception - * @return PHPExcel_Cell + * @param PHPExcel_Cell_Hyperlink $pHyperlink + * @return PHPExcel_Cell + * @throws PHPExcel_Exception */ - public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = null) + public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL) { if (!isset($this->_parent)) { - throw new Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); + throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); } $this->_parent->setHyperlink($this->getCoordinate(), $pHyperlink); @@ -458,19 +471,19 @@ class PHPExcel_Cell } /** - * Get parent + * Get parent worksheet * - * @return PHPExcel_Worksheet + * @return PHPExcel_Worksheet */ public function getParent() { return $this->_parent; } /** - * Re-bind parent + * Re-bind parent * - * @param PHPExcel_Worksheet $parent - * @return PHPExcel_Cell + * @param PHPExcel_Worksheet $parent + * @return PHPExcel_Cell */ public function rebindParent(PHPExcel_Worksheet $parent) { $this->_parent = $parent; @@ -479,17 +492,17 @@ class PHPExcel_Cell } /** - * Is cell in a specific range? + * Is cell in a specific range? * - * @param string $pRange Cell range (e.g. A1:A1) - * @return boolean + * @param string $pRange Cell range (e.g. A1:A1) + * @return boolean */ public function isInRange($pRange = 'A1:A1') { - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange); + list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); // Translate properties - $myColumn = PHPExcel_Cell::columnIndexFromString($this->getColumn()); + $myColumn = self::columnIndexFromString($this->getColumn()); $myRow = $this->getRow(); // Verify if cell is in range @@ -499,80 +512,90 @@ class PHPExcel_Cell } /** - * Coordinate from string + * Coordinate from string * - * @param string $pCoordinateString - * @return array Array containing column and row (indexes 0 and 1) - * @throws Exception + * @param string $pCoordinateString + * @return array Array containing column and row (indexes 0 and 1) + * @throws PHPExcel_Exception */ public static function coordinateFromString($pCoordinateString = 'A1') { if (preg_match("/^([$]?[A-Z]{1,3})([$]?\d{1,7})$/", $pCoordinateString, $matches)) { return array($matches[1],$matches[2]); - } elseif ((strpos($pCoordinateString,':') !== false) || (strpos($pCoordinateString,',') !== false)) { - throw new Exception('Cell coordinate string can not be a range of cells.'); + } elseif ((strpos($pCoordinateString,':') !== FALSE) || (strpos($pCoordinateString,',') !== FALSE)) { + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); } elseif ($pCoordinateString == '') { - throw new Exception('Cell coordinate can not be zero-length string.'); - } else { - throw new Exception('Invalid cell coordinate '.$pCoordinateString); + throw new PHPExcel_Exception('Cell coordinate can not be zero-length string'); } + + throw new PHPExcel_Exception('Invalid cell coordinate '.$pCoordinateString); } /** - * Make string row, column or cell coordinate absolute + * Make string row, column or cell coordinate absolute * - * @param string $pCoordinateString e.g. 'A' or '1' or 'A1' - * @return string Absolute coordinate e.g. '$A' or '$1' or '$A$1' - * @throws Exception + * @param string $pCoordinateString e.g. 'A' or '1' or 'A1' + * Note that this value can be a row or column reference as well as a cell reference + * @return string Absolute coordinate e.g. '$A' or '$1' or '$A$1' + * @throws PHPExcel_Exception */ public static function absoluteReference($pCoordinateString = 'A1') { - if (strpos($pCoordinateString,':') === false && strpos($pCoordinateString,',') === false) { + if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { + // Split out any worksheet name from the reference + $worksheet = ''; + $cellAddress = explode('!',$pCoordinateString); + if (count($cellAddress) > 1) { + list($worksheet,$pCoordinateString) = $cellAddress; + } + if ($worksheet > '') $worksheet .= '!'; + // Create absolute coordinate if (ctype_digit($pCoordinateString)) { - return '$'.$pCoordinateString; + return $worksheet . '$' . $pCoordinateString; } elseif (ctype_alpha($pCoordinateString)) { - return '$'.strtoupper($pCoordinateString); + return $worksheet . '$' . strtoupper($pCoordinateString); } - return self::absoluteCoordinate($pCoordinateString); - } else { - throw new Exception("Coordinate string should not be a cell range."); + return $worksheet . self::absoluteCoordinate($pCoordinateString); } + + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); } /** - * Make string coordinate absolute + * Make string coordinate absolute * - * @param string $pCoordinateString e.g. 'A1' - * @return string Absolute coordinate e.g. '$A$1' - * @throws Exception + * @param string $pCoordinateString e.g. 'A1' + * @return string Absolute coordinate e.g. '$A$1' + * @throws PHPExcel_Exception */ public static function absoluteCoordinate($pCoordinateString = 'A1') { - if (strpos($pCoordinateString,':') === false && strpos($pCoordinateString,',') === false) { - // Create absolute coordinate + if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { + // Split out any worksheet name from the coordinate $worksheet = ''; $cellAddress = explode('!',$pCoordinateString); - if (count($cellAddress) == 2) { + if (count($cellAddress) > 1) { list($worksheet,$pCoordinateString) = $cellAddress; } + if ($worksheet > '') $worksheet .= '!'; - list($column, $row) = PHPExcel_Cell::coordinateFromString($pCoordinateString); - if ($column[0] == '$') $column = substr($column,1); - if ($row[0] == '$') $row = substr($row,1); - if ($worksheet > '') - $worksheet .= '!'; + // Create absolute coordinate + list($column, $row) = self::coordinateFromString($pCoordinateString); + $column = ltrim($column,'$'); + $row = ltrim($row,'$'); return $worksheet . '$' . $column . '$' . $row; - } else { - throw new Exception("Coordinate string should not be a cell range."); } + + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); } /** - * Split range into coordinate strings + * Split range into coordinate strings * - * @param string $pRange - * @return array Array containg one or more arrays containing one or two coordinate strings + * @param string $pRange e.g. 'B4:D9' or 'B4:D9,H2:O11' + * @return array Array containg one or more arrays containing one or two coordinate strings + * e.g. array('B4','D9') or array(array('B4','D9'),array('H2','O11')) */ public static function splitRange($pRange = 'A1:A1') { @@ -585,17 +608,17 @@ class PHPExcel_Cell } /** - * Build range from coordinate strings + * Build range from coordinate strings * - * @param array $pRange Array containg one or more arrays containing one or two coordinate strings - * @return string String representation of $pRange - * @throws Exception + * @param array $pRange Array containg one or more arrays containing one or two coordinate strings + * @return string String representation of $pRange + * @throws PHPExcel_Exception */ public static function buildRange($pRange) { // Verify range if (!is_array($pRange) || empty($pRange) || !is_array($pRange[0])) { - throw new Exception('Range does not contain any information.'); + throw new PHPExcel_Exception('Range does not contain any information'); } // Build range @@ -610,10 +633,10 @@ class PHPExcel_Cell } /** - * Calculate range boundaries + * Calculate range boundaries * - * @param string $pRange Cell range (e.g. A1:A1) - * @return array Range coordinates (Start Cell, End Cell) where Start Cell and End Cell are arrays (Column Number, Row Number) + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range coordinates (Start Cell, End Cell) where Start Cell and End Cell are arrays (Column Number, Row Number) */ public static function rangeBoundaries($pRange = 'A1:A1') { @@ -621,42 +644,42 @@ class PHPExcel_Cell $pRange = strtoupper($pRange); // Extract range - if (strpos($pRange, ':') === false) { + if (strpos($pRange, ':') === FALSE) { $rangeA = $rangeB = $pRange; } else { list($rangeA, $rangeB) = explode(':', $pRange); } // Calculate range outer borders - $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA); - $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB); + $rangeStart = self::coordinateFromString($rangeA); + $rangeEnd = self::coordinateFromString($rangeB); // Translate column into index - $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]); - $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]); + $rangeStart[0] = self::columnIndexFromString($rangeStart[0]); + $rangeEnd[0] = self::columnIndexFromString($rangeEnd[0]); return array($rangeStart, $rangeEnd); } /** - * Calculate range dimension + * Calculate range dimension * - * @param string $pRange Cell range (e.g. A1:A1) - * @return array Range dimension (width, height) + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range dimension (width, height) */ public static function rangeDimension($pRange = 'A1:A1') { // Calculate range outer borders - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange); + list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); return array( ($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1) ); } /** - * Calculate range boundaries + * Calculate range boundaries * - * @param string $pRange Cell range (e.g. A1:A1) - * @return array Range boundaries (staring Column, starting Row, Final Column, Final Row) + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range boundaries (staring Column, starting Row, Final Column, Final Row) */ public static function getRangeBoundaries($pRange = 'A1:A1') { @@ -664,7 +687,7 @@ class PHPExcel_Cell $pRange = strtoupper($pRange); // Extract range - if (strpos($pRange, ':') === false) { + if (strpos($pRange, ':') === FALSE) { $rangeA = $rangeB = $pRange; } else { list($rangeA, $rangeB) = explode(':', $pRange); @@ -674,11 +697,11 @@ class PHPExcel_Cell } /** - * Column index from string + * Column index from string * - * @param string $pString - * @return int Column index (base 1 !!!) - * @throws Exception + * @param string $pString + * @return int Column index (base 1 !!!) + * @throws Exception */ public static function columnIndexFromString($pString = 'A') { @@ -714,14 +737,14 @@ class PHPExcel_Cell return $_indexCache[$pString]; } } - throw new Exception("Column string index can not be " . ((isset($pString{0})) ? "longer than 3 characters" : "empty") . "."); + throw new PHPExcel_Exception("Column string index can not be " . ((isset($pString{0})) ? "longer than 3 characters" : "empty")); } /** - * String from columnindex + * String from columnindex * - * @param int $pColumnIndex Column index (base 0 !!!) - * @return string + * @param int $pColumnIndex Column index (base 0 !!!) + * @return string */ public static function stringFromColumnIndex($pColumnIndex = 0) { @@ -747,10 +770,10 @@ class PHPExcel_Cell } /** - * Extract all cell references in range + * Extract all cell references in range * - * @param string $pRange Range (e.g. A1 or A1:A10 or A1:A10 A100:A1000) - * @return array Array containing single cell references + * @param string $pRange Range (e.g. A1 or A1:A10 or A1:A10 A100:A1000) + * @return array Array containing single cell references */ public static function extractAllCellReferencesInRange($pRange = 'A1') { // Returnvalue @@ -760,13 +783,13 @@ class PHPExcel_Cell $cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange))); foreach ($cellBlocks as $cellBlock) { // Single cell? - if (strpos($cellBlock,':') === false && strpos($cellBlock,',') === false) { + if (strpos($cellBlock,':') === FALSE && strpos($cellBlock,',') === FALSE) { $returnValue[] = $cellBlock; continue; } // Range... - $ranges = PHPExcel_Cell::splitRange($cellBlock); + $ranges = self::splitRange($cellBlock); foreach($ranges as $range) { // Single cell? if (!isset($range[1])) { @@ -813,7 +836,7 @@ class PHPExcel_Cell return -1; } elseif ($a->_row > $b->_row) { return 1; - } elseif (PHPExcel_Cell::columnIndexFromString($a->_column) < PHPExcel_Cell::columnIndexFromString($b->_column)) { + } elseif (self::columnIndexFromString($a->_column) < self::columnIndexFromString($b->_column)) { return -1; } else { return 1; @@ -839,7 +862,7 @@ class PHPExcel_Cell * @param PHPExcel_Cell_IValueBinder $binder * @throws Exception */ - public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = null) { + public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) { if ($binder === NULL) { throw new Exception("A PHPExcel_Cell_IValueBinder is required for PHPExcel to function correctly."); } diff --git a/Classes/PHPExcel/Exception.php b/Classes/PHPExcel/Exception.php new file mode 100644 index 00000000..a4354531 --- /dev/null +++ b/Classes/PHPExcel/Exception.php @@ -0,0 +1,52 @@ +line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/unitTests/PHPExcel/CellTest.php b/unitTests/PHPExcel/CellTest.php new file mode 100644 index 00000000..0f7f3eb7 --- /dev/null +++ b/unitTests/PHPExcel/CellTest.php @@ -0,0 +1,259 @@ +assertEquals($expectedResult, $result); + } + + public function providerColumnString() + { + return new testDataFileIterator('rawTestData/ColumnString.data'); + } + + public function testColumnIndexFromStringTooLong() + { + $cellAddress = 'ABCD'; + try { + $result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Column string index can not be longer than 3 characters'); + return; + } + $this->fail('An expected exception has not been raised.'); + } + + public function testColumnIndexFromStringTooShort() + { + $cellAddress = ''; + try { + $result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Column string index can not be empty'); + return; + } + $this->fail('An expected exception has not been raised.'); + } + + /** + * @dataProvider providerColumnIndex + */ + public function testStringFromColumnIndex() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','stringFromColumnIndex'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerColumnIndex() + { + return new testDataFileIterator('rawTestData/ColumnIndex.data'); + } + + /** + * @dataProvider providerCoordinates + */ + public function testCoordinateFromString() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','coordinateFromString'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerCoordinates() + { + return new testDataFileIterator('rawTestData/CellCoordinates.data'); + } + + public function testCoordinateFromStringWithRangeAddress() + { + $cellAddress = 'A1:AI2012'; + try { + $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); + return; + } + $this->fail('An expected exception has not been raised.'); + } + + public function testCoordinateFromStringWithEmptyAddress() + { + $cellAddress = ''; + try { + $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Cell coordinate can not be zero-length string'); + return; + } + $this->fail('An expected exception has not been raised.'); + } + + public function testCoordinateFromStringWithInvalidAddress() + { + $cellAddress = 'AI'; + try { + $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Invalid cell coordinate '.$cellAddress); + return; + } + $this->fail('An expected exception has not been raised.'); + } + + /** + * @dataProvider providerAbsoluteCoordinates + */ + public function testAbsoluteCoordinateFromString() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','absoluteCoordinate'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerAbsoluteCoordinates() + { + return new testDataFileIterator('rawTestData/CellAbsoluteCoordinate.data'); + } + + public function testAbsoluteCoordinateFromStringWithRangeAddress() + { + $cellAddress = 'A1:AI2012'; + try { + $result = call_user_func(array('PHPExcel_Cell','absoluteCoordinate'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); + return; + } + $this->fail('An expected exception has not been raised.'); + } + + /** + * @dataProvider providerAbsoluteReferences + */ + public function testAbsoluteReferenceFromString() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','absoluteReference'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerAbsoluteReferences() + { + return new testDataFileIterator('rawTestData/CellAbsoluteReference.data'); + } + + public function testAbsoluteReferenceFromStringWithRangeAddress() + { + $cellAddress = 'A1:AI2012'; + try { + $result = call_user_func(array('PHPExcel_Cell','absoluteReference'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); + return; + } + $this->fail('An expected exception has not been raised.'); + } + + /** + * @dataProvider providerSplitRange + */ + public function testSplitRange() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','splitRange'),$args); + foreach($result as $key => $split) { + $this->assertEquals($expectedResult[$key], $split); + } + } + + public function providerSplitRange() + { + return new testDataFileIterator('rawTestData/CellSplitRange.data'); + } + + /** + * @dataProvider providerBuildRange + */ + public function testBuildRange() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','buildRange'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerBuildRange() + { + return new testDataFileIterator('rawTestData/CellBuildRange.data'); + } + + public function testBuildRangeInvalid() + { + $cellRange = ''; + try { + $result = call_user_func(array('PHPExcel_Cell','buildRange'),$cellRange); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Range does not contain any information'); + return; + } + $this->fail('An expected exception has not been raised.'); + } + + /** + * @dataProvider providerRangeBoundaries + */ + public function testRangeBoundaries() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','rangeBoundaries'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerRangeBoundaries() + { + return new testDataFileIterator('rawTestData/CellRangeBoundaries.data'); + } + + /** + * @dataProvider providerRangeDimension + */ + public function testRangeDimension() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','rangeDimension'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerRangeDimension() + { + return new testDataFileIterator('rawTestData/CellRangeDimension.data'); + } + +} diff --git a/unitTests/rawTestData/CellAbsoluteCoordinate.data b/unitTests/rawTestData/CellAbsoluteCoordinate.data new file mode 100644 index 00000000..ad642947 --- /dev/null +++ b/unitTests/rawTestData/CellAbsoluteCoordinate.data @@ -0,0 +1,12 @@ +"A1", "$A$1" +"A12", "$A$12" +"J1", "$J$1" +"J20", "$J$20" +"AI1", "$AI$1" +"AI2012", "$AI$2012" +"'Worksheet1'!AI256", "'Worksheet1'!$AI$256" +"Worksheet1!AI256", "Worksheet1!$AI$256" +"'Data Worksheet'!AI256", "'Data Worksheet'!$AI$256" +"'Worksheet1'!$AI256", "'Worksheet1'!$AI$256" +"'Worksheet1'!AI$256", "'Worksheet1'!$AI$256" +"'Worksheet1'!$AI$256", "'Worksheet1'!$AI$256" diff --git a/unitTests/rawTestData/CellAbsoluteReference.data b/unitTests/rawTestData/CellAbsoluteReference.data new file mode 100644 index 00000000..8aa314a2 --- /dev/null +++ b/unitTests/rawTestData/CellAbsoluteReference.data @@ -0,0 +1,16 @@ +"A1", "$A$1" +"A12", "$A$12" +"J1", "$J$1" +"J20", "$J$20" +"AI1", "$AI$1" +"AI2012", "$AI$2012" +"'Worksheet1'!AI256", "'Worksheet1'!$AI$256" +"Worksheet1!AI256", "Worksheet1!$AI$256" +"'Data Worksheet'!AI256", "'Data Worksheet'!$AI$256" +"AI", "$AI" +2012, "$2012" +"Worksheet1!AI", "Worksheet1!$AI" +"Worksheet1!256", "Worksheet1!$256" +"'Worksheet1'!$AI256", "'Worksheet1'!$AI$256" +"'Worksheet1'!AI$256", "'Worksheet1'!$AI$256" +"'Worksheet1'!$AI$256", "'Worksheet1'!$AI$256" diff --git a/unitTests/rawTestData/CellBuildRange.data b/unitTests/rawTestData/CellBuildRange.data new file mode 100644 index 00000000..78e951ba --- /dev/null +++ b/unitTests/rawTestData/CellBuildRange.data @@ -0,0 +1,2 @@ +{"B4"|"E9"}, "B4:E9" +{"B4"|"E9";"H2"|"O11"}, "B4:E9,H2:O11" diff --git a/unitTests/rawTestData/CellCoordinates.data b/unitTests/rawTestData/CellCoordinates.data new file mode 100644 index 00000000..e64ce559 --- /dev/null +++ b/unitTests/rawTestData/CellCoordinates.data @@ -0,0 +1,6 @@ +"A1", {"A";1} +"A12", {"A";12} +"J1", {"J";1} +"J20", {"J";20} +"AI1", {"AI";1} +"AI2012", {"AI";2012} diff --git a/unitTests/rawTestData/CellRangeBoundaries.data b/unitTests/rawTestData/CellRangeBoundaries.data new file mode 100644 index 00000000..2fca6dc2 --- /dev/null +++ b/unitTests/rawTestData/CellRangeBoundaries.data @@ -0,0 +1,2 @@ +"B4:E9", {2|4;5|9} +"B4", {2|4;2|4} diff --git a/unitTests/rawTestData/CellRangeDimension.data b/unitTests/rawTestData/CellRangeDimension.data new file mode 100644 index 00000000..1718f121 --- /dev/null +++ b/unitTests/rawTestData/CellRangeDimension.data @@ -0,0 +1,2 @@ +"B4:E9", {4;6} +"B4", {1;1} diff --git a/unitTests/rawTestData/CellSplitRange.data b/unitTests/rawTestData/CellSplitRange.data new file mode 100644 index 00000000..b055d4ae --- /dev/null +++ b/unitTests/rawTestData/CellSplitRange.data @@ -0,0 +1,3 @@ +"B4:E9", {"B4"|"E9"} +"B4", {"B4"} +"B4:E9,H2:O11", {"B4"|"E9";"H2"|"O11"} diff --git a/unitTests/rawTestData/ColumnIndex.data b/unitTests/rawTestData/ColumnIndex.data new file mode 100644 index 00000000..9a1679b6 --- /dev/null +++ b/unitTests/rawTestData/ColumnIndex.data @@ -0,0 +1,9 @@ +0, "A" +25, "Z" +26, "AA" +27, "AB" +51, "AZ" +52, "BA" +701, "ZZ" +702, "AAA" +1378, "BAA" diff --git a/unitTests/rawTestData/ColumnString.data b/unitTests/rawTestData/ColumnString.data new file mode 100644 index 00000000..5573759e --- /dev/null +++ b/unitTests/rawTestData/ColumnString.data @@ -0,0 +1,9 @@ +"A", 1 +"Z", 26 +"AA", 27 +"AB", 28 +"AZ", 52 +"BA", 53 +"ZZ", 702 +"AAA", 703 +"BAA", 1379 From 5c32ecee0adbabf726ea5eb7c5911705de7ffd9a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 29 Jul 2012 23:38:41 +0100 Subject: [PATCH 17/30] Fixes to unit test data --- unitTests/rawTestData/CellBuildRange.data | 2 +- unitTests/rawTestData/CellSplitRange.data | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unitTests/rawTestData/CellBuildRange.data b/unitTests/rawTestData/CellBuildRange.data index 78e951ba..8d6efbff 100644 --- a/unitTests/rawTestData/CellBuildRange.data +++ b/unitTests/rawTestData/CellBuildRange.data @@ -1,2 +1,2 @@ {"B4"|"E9"}, "B4:E9" -{"B4"|"E9";"H2"|"O11"}, "B4:E9,H2:O11" +{"B4"|"E9";"H2"|"O11"}, '"B4:E9,H2:O11"' diff --git a/unitTests/rawTestData/CellSplitRange.data b/unitTests/rawTestData/CellSplitRange.data index b055d4ae..215fce25 100644 --- a/unitTests/rawTestData/CellSplitRange.data +++ b/unitTests/rawTestData/CellSplitRange.data @@ -1,3 +1,3 @@ "B4:E9", {"B4"|"E9"} "B4", {"B4"} -"B4:E9,H2:O11", {"B4"|"E9";"H2"|"O11"} +'"B4:E9,H2:O11"', {"B4"|"E9";"H2"|"O11"} From 83c083392ae163bd030f98e27319df9736847eb2 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 31 Jul 2012 13:00:09 +0100 Subject: [PATCH 18/30] GH18 - Modify extractAllCellReferencesInRange() behaviour for , and space range separators --- Classes/PHPExcel/Cell.php | 21 +++++++--- unitTests/PHPExcel/CellTest.php | 38 ++++++++++++++++++- .../CellExtractAllCellReferencesInRange.data | 9 +++++ .../rawTestData/CellGetRangeBoundaries.data | 2 + 4 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 unitTests/rawTestData/CellExtractAllCellReferencesInRange.data create mode 100644 unitTests/rawTestData/CellGetRangeBoundaries.data diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index e63d821b..6bf16ee6 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -593,9 +593,10 @@ class PHPExcel_Cell /** * Split range into coordinate strings * - * @param string $pRange e.g. 'B4:D9' or 'B4:D9,H2:O11' + * @param string $pRange e.g. 'B4:D9' or 'B4:D9,H2:O11' or 'B4' * @return array Array containg one or more arrays containing one or two coordinate strings * e.g. array('B4','D9') or array(array('B4','D9'),array('H2','O11')) + * or array('B4') */ public static function splitRange($pRange = 'A1:A1') { @@ -636,7 +637,8 @@ class PHPExcel_Cell * Calculate range boundaries * * @param string $pRange Cell range (e.g. A1:A1) - * @return array Range coordinates (Start Cell, End Cell) where Start Cell and End Cell are arrays (Column Number, Row Number) + * @return array Range coordinates array(Start Cell, End Cell) + * where Start Cell and End Cell are arrays (Column Number, Row Number) */ public static function rangeBoundaries($pRange = 'A1:A1') { @@ -679,7 +681,8 @@ class PHPExcel_Cell * Calculate range boundaries * * @param string $pRange Cell range (e.g. A1:A1) - * @return array Range boundaries (staring Column, starting Row, Final Column, Final Row) + * @return array Range coordinates array(Start Cell, End Cell) + * where Start Cell and End Cell are arrays (Column ID, Row Number) */ public static function getRangeBoundaries($pRange = 'A1:A1') { @@ -772,7 +775,7 @@ class PHPExcel_Cell /** * Extract all cell references in range * - * @param string $pRange Range (e.g. A1 or A1:A10 or A1:A10 A100:A1000) + * @param string $pRange Range (e.g. A1 or A1:C10 or A1:E10 A20:E25) * @return array Array containing single cell references */ public static function extractAllCellReferencesInRange($pRange = 'A1') { @@ -819,8 +822,16 @@ class PHPExcel_Cell } } + // Sort the result by column and row + $sortKeys = array(); + foreach (array_unique($returnValue) as $coord) { + list($column,$row) = sscanf($coord,'%[A-Z]%d'); + $sortKeys[sprintf('%3s%09d',$column,$row)] = $coord; + } + ksort($sortKeys); + // Return value - return $returnValue; + return array_values($sortKeys); } /** diff --git a/unitTests/PHPExcel/CellTest.php b/unitTests/PHPExcel/CellTest.php index 0f7f3eb7..11df404c 100644 --- a/unitTests/PHPExcel/CellTest.php +++ b/unitTests/PHPExcel/CellTest.php @@ -187,7 +187,11 @@ class CellTest extends PHPUnit_Framework_TestCase $expectedResult = array_pop($args); $result = call_user_func_array(array('PHPExcel_Cell','splitRange'),$args); foreach($result as $key => $split) { - $this->assertEquals($expectedResult[$key], $split); + if (!is_array($expectedResult[$key])) { + $this->assertEquals($expectedResult[$key], $split[0]); + } else { + $this->assertEquals($expectedResult[$key], $split); + } } } @@ -256,4 +260,36 @@ class CellTest extends PHPUnit_Framework_TestCase return new testDataFileIterator('rawTestData/CellRangeDimension.data'); } + /** + * @dataProvider providerGetRangeBoundaries + */ + public function testGetRangeBoundaries() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','getRangeBoundaries'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerGetRangeBoundaries() + { + return new testDataFileIterator('rawTestData/CellGetRangeBoundaries.data'); + } + + /** + * @dataProvider providerExtractAllCellReferencesInRange + */ + public function testExtractAllCellReferencesInRange() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','extractAllCellReferencesInRange'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerExtractAllCellReferencesInRange() + { + return new testDataFileIterator('rawTestData/CellExtractAllCellReferencesInRange.data'); + } + } diff --git a/unitTests/rawTestData/CellExtractAllCellReferencesInRange.data b/unitTests/rawTestData/CellExtractAllCellReferencesInRange.data new file mode 100644 index 00000000..4b44a83a --- /dev/null +++ b/unitTests/rawTestData/CellExtractAllCellReferencesInRange.data @@ -0,0 +1,9 @@ +"B4:B6", {"B4";"B5";"B6"} +'"B4:B6,D4:D6"', {"B4";"B5";"B6";"D4";"D5";"D6"} +'"B4:B6 D4:D6"', {"B4";"B5";"B6";"D4";"D5";"D6"} +"B4:D6", {"B4";"B5";"B6";"C4";"C5";"C6";"D4";"D5";"D6"} +'"B4:D6,C5:E7"', {"B4";"B5";"B6";"C4";"C5";"C6";"C7";"D4";"D5";"D6";"D7";"E5";"E6";"E7"} +'"B4:D6 C5:E7"', {"B4";"B5";"B6";"C4";"C5";"C6";"C7";"D4";"D5";"D6";"D7";"E5";"E6";"E7"} +"B2:D4 C5:D5 E3:E5 D6:E6 F4:F6", {"B2";"B3";"B4";"C2";"C3";"C4";"C5";"D2";"D3";"D4";"D5";"D6";"E3";"E4";"E5";"E6";"F4";"F5";"F6"} +"B2:D4 C3:E5 D4:F6", {"B2";"B3";"B4";"C2";"C3";"C4";"C5";"D2";"D3";"D4";"D5";"D6";"E3";"E4";"E5";"E6";"F4";"F5";"F6"} +"B4:B6 B8", {"B4";"B5";"B6";"B8"} diff --git a/unitTests/rawTestData/CellGetRangeBoundaries.data b/unitTests/rawTestData/CellGetRangeBoundaries.data new file mode 100644 index 00000000..f01a5fd9 --- /dev/null +++ b/unitTests/rawTestData/CellGetRangeBoundaries.data @@ -0,0 +1,2 @@ +"B4:E9", {"B"|4;"E"|9} +"B4", {"B"|4;"B"|4} From f12189b29d78dae17b777a48f74b09b21a89f80a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 31 Jul 2012 21:56:11 +0100 Subject: [PATCH 19/30] Reorganised unit test directories --- .../{ => Classes}/PHPExcel/AutoloaderTest.php | 110 +- .../PHPExcel/Calculation/DateTimeTest.php | 928 +++++------ .../PHPExcel/Calculation/EngineeringTest.php | 1392 ++++++++--------- .../PHPExcel/Calculation/FinancialTest.php | 1028 ++++++------ .../PHPExcel/Calculation/FunctionsTest.php | 548 +++---- .../PHPExcel/Calculation/LogicalTest.php | 220 +-- .../PHPExcel/Calculation/MathTrigTest.php | 968 ++++++------ .../PHPExcel/Calculation/TextDataTest.php | 686 ++++---- unitTests/{ => Classes}/PHPExcel/CellTest.php | 0 .../PHPExcel/Chart/DataSeriesValuesTest.php | 0 .../PHPExcel/Chart/LayoutTest.php | 0 .../PHPExcel/Chart/LegendTest.php | 0 .../PHPExcel/Shared/CodePageTest.php | 0 .../PHPExcel/Shared/DateTest.php | 0 .../PHPExcel/Shared/StringTest.php | 0 unitTests/phpunit.xml | 2 +- 16 files changed, 2941 insertions(+), 2941 deletions(-) rename unitTests/{ => Classes}/PHPExcel/AutoloaderTest.php (96%) rename unitTests/{ => Classes}/PHPExcel/Calculation/DateTimeTest.php (97%) rename unitTests/{ => Classes}/PHPExcel/Calculation/EngineeringTest.php (96%) rename unitTests/{ => Classes}/PHPExcel/Calculation/FinancialTest.php (96%) rename unitTests/{ => Classes}/PHPExcel/Calculation/FunctionsTest.php (96%) rename unitTests/{ => Classes}/PHPExcel/Calculation/LogicalTest.php (96%) rename unitTests/{ => Classes}/PHPExcel/Calculation/MathTrigTest.php (96%) rename unitTests/{ => Classes}/PHPExcel/Calculation/TextDataTest.php (96%) rename unitTests/{ => Classes}/PHPExcel/CellTest.php (100%) rename unitTests/{ => Classes}/PHPExcel/Chart/DataSeriesValuesTest.php (100%) rename unitTests/{ => Classes}/PHPExcel/Chart/LayoutTest.php (100%) rename unitTests/{ => Classes}/PHPExcel/Chart/LegendTest.php (100%) rename unitTests/{ => Classes}/PHPExcel/Shared/CodePageTest.php (100%) rename unitTests/{ => Classes}/PHPExcel/Shared/DateTest.php (100%) rename unitTests/{ => Classes}/PHPExcel/Shared/StringTest.php (100%) diff --git a/unitTests/PHPExcel/AutoloaderTest.php b/unitTests/Classes/PHPExcel/AutoloaderTest.php similarity index 96% rename from unitTests/PHPExcel/AutoloaderTest.php rename to unitTests/Classes/PHPExcel/AutoloaderTest.php index 542be23f..286ef627 100644 --- a/unitTests/PHPExcel/AutoloaderTest.php +++ b/unitTests/Classes/PHPExcel/AutoloaderTest.php @@ -1,56 +1,56 @@ -assertTrue(is_bool($result)); - // ... indicating failure - $this->assertFalse($result); - } - - public function testAutoloaderInvalidPHPExcelClass() - { - $className = 'PHPExcel_Invalid_Class'; - - $result = PHPExcel_Autoloader::Load($className); - // Must return a boolean... - $this->assertTrue(is_bool($result)); - // ... indicating failure - $this->assertFalse($result); - } - - public function testAutoloadValidPHPExcelClass() - { - $className = 'PHPExcel_IOFactory'; - - $result = PHPExcel_Autoloader::Load($className); - // Check that class has been loaded - $this->assertTrue(class_exists($className)); - } - - public function testAutoloadInstantiateSuccess() - { - $result = new PHPExcel_Calculation_Function(1,2,3); - // Must return an object... - $this->assertTrue(is_object($result)); - // ... of the correct type - $this->assertTrue(is_a($result,'PHPExcel_Calculation_Function')); - } - +assertTrue(is_bool($result)); + // ... indicating failure + $this->assertFalse($result); + } + + public function testAutoloaderInvalidPHPExcelClass() + { + $className = 'PHPExcel_Invalid_Class'; + + $result = PHPExcel_Autoloader::Load($className); + // Must return a boolean... + $this->assertTrue(is_bool($result)); + // ... indicating failure + $this->assertFalse($result); + } + + public function testAutoloadValidPHPExcelClass() + { + $className = 'PHPExcel_IOFactory'; + + $result = PHPExcel_Autoloader::Load($className); + // Check that class has been loaded + $this->assertTrue(class_exists($className)); + } + + public function testAutoloadInstantiateSuccess() + { + $result = new PHPExcel_Calculation_Function(1,2,3); + // Must return an object... + $this->assertTrue(is_object($result)); + // ... of the correct type + $this->assertTrue(is_a($result,'PHPExcel_Calculation_Function')); + } + } \ No newline at end of file diff --git a/unitTests/PHPExcel/Calculation/DateTimeTest.php b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php similarity index 97% rename from unitTests/PHPExcel/Calculation/DateTimeTest.php rename to unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php index 31676d16..57692a34 100644 --- a/unitTests/PHPExcel/Calculation/DateTimeTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php @@ -1,464 +1,464 @@ -assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerDATE() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/DATE.data'); - } - - public function testDATEtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::DATE(2012,1,31); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(1327968000, $result, NULL, 1E-8); - } - - public function testDATEtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::DATE(2012,1,31); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - // Must return an object... - $this->assertTrue(is_object($result)); - // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); - // ... with the correct value - $this->assertEquals($result->format('d-M-Y'),'31-Jan-2012'); - } - - public function testDATEwith1904Calendar() - { - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); - $result = PHPExcel_Calculation_DateTime::DATE(1918,11,11); - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); - $this->assertEquals($result,5428); - } - - public function testDATEwith1904CalendarError() - { - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); - $result = PHPExcel_Calculation_DateTime::DATE(1901,1,31); - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); - $this->assertEquals($result,'#NUM!'); - } - - /** - * @dataProvider providerDATEVALUE - */ - public function testDATEVALUE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEVALUE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerDATEVALUE() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/DATEVALUE.data'); - } - - public function testDATEVALUEtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::DATEVALUE('2012-1-31'); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(1327968000, $result, NULL, 1E-8); - } - - public function testDATEVALUEtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::DATEVALUE('2012-1-31'); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - // Must return an object... - $this->assertTrue(is_object($result)); - // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); - // ... with the correct value - $this->assertEquals($result->format('d-M-Y'),'31-Jan-2012'); - } - - /** - * @dataProvider providerYEAR - */ - public function testYEAR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEAR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerYEAR() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/YEAR.data'); - } - - /** - * @dataProvider providerMONTH - */ - public function testMONTH() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MONTHOFYEAR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerMONTH() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/MONTH.data'); - } - - /** - * @dataProvider providerWEEKNUM - */ - public function testWEEKNUM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WEEKOFYEAR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerWEEKNUM() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/WEEKNUM.data'); - } - - /** - * @dataProvider providerWEEKDAY - */ - public function testWEEKDAY() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFWEEK'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerWEEKDAY() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/WEEKDAY.data'); - } - - /** - * @dataProvider providerDAY - */ - public function testDAY() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFMONTH'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerDAY() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/DAY.data'); - } - - /** - * @dataProvider providerTIME - */ - public function testTIME() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIME'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerTIME() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/TIME.data'); - } - - public function testTIMEtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::TIME(7,30,20); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(27020, $result, NULL, 1E-8); - } - - public function testTIMEtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::TIME(7,30,20); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - // Must return an object... - $this->assertTrue(is_object($result)); - // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); - // ... with the correct value - $this->assertEquals($result->format('H:i:s'),'07:30:20'); - } - - /** - * @dataProvider providerTIMEVALUE - */ - public function testTIMEVALUE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIMEVALUE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerTIMEVALUE() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/TIMEVALUE.data'); - } - - public function testTIMEVALUEtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::TIMEVALUE('7:30:20'); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(23420, $result, NULL, 1E-8); - } - - public function testTIMEVALUEtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::TIMEVALUE('7:30:20'); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - // Must return an object... - $this->assertTrue(is_object($result)); - // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); - // ... with the correct value - $this->assertEquals($result->format('H:i:s'),'07:30:20'); - } - - /** - * @dataProvider providerHOUR - */ - public function testHOUR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','HOUROFDAY'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerHOUR() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/HOUR.data'); - } - - /** - * @dataProvider providerMINUTE - */ - public function testMINUTE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MINUTEOFHOUR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerMINUTE() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/MINUTE.data'); - } - - /** - * @dataProvider providerSECOND - */ - public function testSECOND() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','SECONDOFMINUTE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerSECOND() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/SECOND.data'); - } - - /** - * @dataProvider providerNETWORKDAYS - */ - public function testNETWORKDAYS() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','NETWORKDAYS'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerNETWORKDAYS() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/NETWORKDAYS.data'); - } - - /** - * @dataProvider providerWORKDAY - */ - public function testWORKDAY() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WORKDAY'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerWORKDAY() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/WORKDAY.data'); - } - - /** - * @dataProvider providerEDATE - */ - public function testEDATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EDATE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerEDATE() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/EDATE.data'); - } - - public function testEDATEtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(1324857600, $result, NULL, 1E-8); - } - - public function testEDATEtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - // Must return an object... - $this->assertTrue(is_object($result)); - // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); - // ... with the correct value - $this->assertEquals($result->format('d-M-Y'),'26-Dec-2011'); - } - - /** - * @dataProvider providerEOMONTH - */ - public function testEOMONTH() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EOMONTH'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerEOMONTH() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/EOMONTH.data'); - } - - public function testEOMONTHtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(1325289600, $result, NULL, 1E-8); - } - - public function testEOMONTHtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - // Must return an object... - $this->assertTrue(is_object($result)); - // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); - // ... with the correct value - $this->assertEquals($result->format('d-M-Y'),'31-Dec-2011'); - } - - /** - * @dataProvider providerDATEDIF - */ - public function testDATEDIF() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEDIF'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerDATEDIF() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/DATEDIF.data'); - } - - /** - * @dataProvider providerDAYS360 - */ - public function testDAYS360() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYS360'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerDAYS360() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/DAYS360.data'); - } - - /** - * @dataProvider providerYEARFRAC - */ - public function testYEARFRAC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEARFRAC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerYEARFRAC() - { - return new testDataFileIterator('rawTestData/Calculation/DateTime/YEARFRAC.data'); - } - -} +assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerDATE() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/DATE.data'); + } + + public function testDATEtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::DATE(2012,1,31); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(1327968000, $result, NULL, 1E-8); + } + + public function testDATEtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::DATE(2012,1,31); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + // Must return an object... + $this->assertTrue(is_object($result)); + // ... of the correct type + $this->assertTrue(is_a($result,'DateTime')); + // ... with the correct value + $this->assertEquals($result->format('d-M-Y'),'31-Jan-2012'); + } + + public function testDATEwith1904Calendar() + { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + $result = PHPExcel_Calculation_DateTime::DATE(1918,11,11); + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + $this->assertEquals($result,5428); + } + + public function testDATEwith1904CalendarError() + { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + $result = PHPExcel_Calculation_DateTime::DATE(1901,1,31); + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + $this->assertEquals($result,'#NUM!'); + } + + /** + * @dataProvider providerDATEVALUE + */ + public function testDATEVALUE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEVALUE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerDATEVALUE() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/DATEVALUE.data'); + } + + public function testDATEVALUEtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::DATEVALUE('2012-1-31'); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(1327968000, $result, NULL, 1E-8); + } + + public function testDATEVALUEtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::DATEVALUE('2012-1-31'); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + // Must return an object... + $this->assertTrue(is_object($result)); + // ... of the correct type + $this->assertTrue(is_a($result,'DateTime')); + // ... with the correct value + $this->assertEquals($result->format('d-M-Y'),'31-Jan-2012'); + } + + /** + * @dataProvider providerYEAR + */ + public function testYEAR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEAR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerYEAR() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/YEAR.data'); + } + + /** + * @dataProvider providerMONTH + */ + public function testMONTH() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MONTHOFYEAR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerMONTH() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/MONTH.data'); + } + + /** + * @dataProvider providerWEEKNUM + */ + public function testWEEKNUM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WEEKOFYEAR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerWEEKNUM() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/WEEKNUM.data'); + } + + /** + * @dataProvider providerWEEKDAY + */ + public function testWEEKDAY() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFWEEK'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerWEEKDAY() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/WEEKDAY.data'); + } + + /** + * @dataProvider providerDAY + */ + public function testDAY() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFMONTH'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerDAY() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/DAY.data'); + } + + /** + * @dataProvider providerTIME + */ + public function testTIME() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIME'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerTIME() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/TIME.data'); + } + + public function testTIMEtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::TIME(7,30,20); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(27020, $result, NULL, 1E-8); + } + + public function testTIMEtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::TIME(7,30,20); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + // Must return an object... + $this->assertTrue(is_object($result)); + // ... of the correct type + $this->assertTrue(is_a($result,'DateTime')); + // ... with the correct value + $this->assertEquals($result->format('H:i:s'),'07:30:20'); + } + + /** + * @dataProvider providerTIMEVALUE + */ + public function testTIMEVALUE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIMEVALUE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerTIMEVALUE() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/TIMEVALUE.data'); + } + + public function testTIMEVALUEtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::TIMEVALUE('7:30:20'); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(23420, $result, NULL, 1E-8); + } + + public function testTIMEVALUEtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::TIMEVALUE('7:30:20'); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + // Must return an object... + $this->assertTrue(is_object($result)); + // ... of the correct type + $this->assertTrue(is_a($result,'DateTime')); + // ... with the correct value + $this->assertEquals($result->format('H:i:s'),'07:30:20'); + } + + /** + * @dataProvider providerHOUR + */ + public function testHOUR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','HOUROFDAY'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerHOUR() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/HOUR.data'); + } + + /** + * @dataProvider providerMINUTE + */ + public function testMINUTE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MINUTEOFHOUR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerMINUTE() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/MINUTE.data'); + } + + /** + * @dataProvider providerSECOND + */ + public function testSECOND() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','SECONDOFMINUTE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerSECOND() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/SECOND.data'); + } + + /** + * @dataProvider providerNETWORKDAYS + */ + public function testNETWORKDAYS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','NETWORKDAYS'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerNETWORKDAYS() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/NETWORKDAYS.data'); + } + + /** + * @dataProvider providerWORKDAY + */ + public function testWORKDAY() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WORKDAY'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerWORKDAY() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/WORKDAY.data'); + } + + /** + * @dataProvider providerEDATE + */ + public function testEDATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EDATE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerEDATE() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/EDATE.data'); + } + + public function testEDATEtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(1324857600, $result, NULL, 1E-8); + } + + public function testEDATEtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + // Must return an object... + $this->assertTrue(is_object($result)); + // ... of the correct type + $this->assertTrue(is_a($result,'DateTime')); + // ... with the correct value + $this->assertEquals($result->format('d-M-Y'),'26-Dec-2011'); + } + + /** + * @dataProvider providerEOMONTH + */ + public function testEOMONTH() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EOMONTH'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerEOMONTH() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/EOMONTH.data'); + } + + public function testEOMONTHtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(1325289600, $result, NULL, 1E-8); + } + + public function testEOMONTHtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + // Must return an object... + $this->assertTrue(is_object($result)); + // ... of the correct type + $this->assertTrue(is_a($result,'DateTime')); + // ... with the correct value + $this->assertEquals($result->format('d-M-Y'),'31-Dec-2011'); + } + + /** + * @dataProvider providerDATEDIF + */ + public function testDATEDIF() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEDIF'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerDATEDIF() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/DATEDIF.data'); + } + + /** + * @dataProvider providerDAYS360 + */ + public function testDAYS360() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYS360'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerDAYS360() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/DAYS360.data'); + } + + /** + * @dataProvider providerYEARFRAC + */ + public function testYEARFRAC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEARFRAC'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerYEARFRAC() + { + return new testDataFileIterator('rawTestData/Calculation/DateTime/YEARFRAC.data'); + } + +} diff --git a/unitTests/PHPExcel/Calculation/EngineeringTest.php b/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php similarity index 96% rename from unitTests/PHPExcel/Calculation/EngineeringTest.php rename to unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php index 030ccb53..647da09f 100644 --- a/unitTests/PHPExcel/Calculation/EngineeringTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php @@ -1,696 +1,696 @@ -assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerBESSELI() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELI.data'); - } - - /** - * @dataProvider providerBESSELJ - */ - public function testBESSELJ() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELJ'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerBESSELJ() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELJ.data'); - } - - /** - * @dataProvider providerBESSELK - */ - public function testBESSELK() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELK'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerBESSELK() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELK.data'); - } - - /** - * @dataProvider providerBESSELY - */ - public function testBESSELY() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELY'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerBESSELY() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELY.data'); - } - - /** - * @dataProvider providerCOMPLEX - */ - public function testCOMPLEX() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','COMPLEX'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerCOMPLEX() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/COMPLEX.data'); - } - - /** - * @dataProvider providerIMAGINARY - */ - public function testIMAGINARY() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMAGINARY'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIMAGINARY() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMAGINARY.data'); - } - - /** - * @dataProvider providerIMREAL - */ - public function testIMREAL() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMREAL'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIMREAL() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMREAL.data'); - } - - /** - * @dataProvider providerIMABS - */ - public function testIMABS() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMABS'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIMABS() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMABS.data'); - } - - /** - * @dataProvider providerIMARGUMENT - */ - public function testIMARGUMENT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMARGUMENT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIMARGUMENT() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMARGUMENT.data'); - } - - /** - * @dataProvider providerIMCONJUGATE - */ - public function testIMCONJUGATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCONJUGATE'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMCONJUGATE() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMCONJUGATE.data'); - } - - /** - * @dataProvider providerIMCOS - */ - public function testIMCOS() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCOS'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMCOS() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMCOS.data'); - } - - /** - * @dataProvider providerIMDIV - */ - public function testIMDIV() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMDIV'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMDIV() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMDIV.data'); - } - - /** - * @dataProvider providerIMEXP - */ - public function testIMEXP() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMEXP'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMEXP() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMEXP.data'); - } - - /** - * @dataProvider providerIMLN - */ - public function testIMLN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLN'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMLN() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLN.data'); - } - - /** - * @dataProvider providerIMLOG2 - */ - public function testIMLOG2() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG2'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMLOG2() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLOG2.data'); - } - - /** - * @dataProvider providerIMLOG10 - */ - public function testIMLOG10() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG10'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMLOG10() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLOG10.data'); - } - - /** - * @dataProvider providerIMPOWER - */ - public function testIMPOWER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPOWER'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMPOWER() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMPOWER.data'); - } - - /** - * @dataProvider providerIMPRODUCT - */ - public function testIMPRODUCT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPRODUCT'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMPRODUCT() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMPRODUCT.data'); - } - - /** - * @dataProvider providerIMSIN - */ - public function testIMSIN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSIN'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMSIN() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSIN.data'); - } - - /** - * @dataProvider providerIMSQRT - */ - public function testIMSQRT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSQRT'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMSQRT() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSQRT.data'); - } - - /** - * @dataProvider providerIMSUB - */ - public function testIMSUB() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUB'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMSUB() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUB.data'); - } - - /** - * @dataProvider providerIMSUM - */ - public function testIMSUM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } - - public function providerIMSUM() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUM.data'); - } - - /** - * @dataProvider providerERF - */ - public function testERF() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERF'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerERF() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/ERF.data'); - } - - /** - * @dataProvider providerERFC - */ - public function testERFC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERFC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerERFC() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/ERFC.data'); - } - - /** - * @dataProvider providerBIN2DEC - */ - public function testBIN2DEC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTODEC'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerBIN2DEC() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2DEC.data'); - } - - /** - * @dataProvider providerBIN2HEX - */ - public function testBIN2HEX() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOHEX'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerBIN2HEX() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2HEX.data'); - } - - /** - * @dataProvider providerBIN2OCT - */ - public function testBIN2OCT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOOCT'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerBIN2OCT() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2OCT.data'); - } - - /** - * @dataProvider providerDEC2BIN - */ - public function testDEC2BIN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOBIN'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerDEC2BIN() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2BIN.data'); - } - - /** - * @dataProvider providerDEC2HEX - */ - public function testDEC2HEX() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOHEX'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerDEC2HEX() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2HEX.data'); - } - - /** - * @dataProvider providerDEC2OCT - */ - public function testDEC2OCT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOOCT'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerDEC2OCT() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2OCT.data'); - } - - /** - * @dataProvider providerHEX2BIN - */ - public function testHEX2BIN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOBIN'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerHEX2BIN() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2BIN.data'); - } - - /** - * @dataProvider providerHEX2DEC - */ - public function testHEX2DEC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTODEC'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerHEX2DEC() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2DEC.data'); - } - - /** - * @dataProvider providerHEX2OCT - */ - public function testHEX2OCT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOOCT'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerHEX2OCT() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2OCT.data'); - } - - /** - * @dataProvider providerOCT2BIN - */ - public function testOCT2BIN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOBIN'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerOCT2BIN() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2BIN.data'); - } - - /** - * @dataProvider providerOCT2DEC - */ - public function testOCT2DEC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTODEC'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerOCT2DEC() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2DEC.data'); - } - - /** - * @dataProvider providerOCT2HEX - */ - public function testOCT2HEX() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOHEX'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerOCT2HEX() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2HEX.data'); - } - - /** - * @dataProvider providerDELTA - */ - public function testDELTA() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DELTA'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerDELTA() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/DELTA.data'); - } - - /** - * @dataProvider providerGESTEP - */ - public function testGESTEP() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','GESTEP'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerGESTEP() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/GESTEP.data'); - } - - public function testGetConversionGroups() - { - $result = PHPExcel_Calculation_Engineering::getConversionGroups(); - $this->assertInternalType('array', $result); - } - - public function testGetConversionGroupUnits() - { - $result = PHPExcel_Calculation_Engineering::getConversionGroupUnits(); - $this->assertInternalType('array', $result); - } - - public function testGetConversionGroupUnitDetails() - { - $result = PHPExcel_Calculation_Engineering::getConversionGroupUnitDetails(); - $this->assertInternalType('array', $result); - } - - public function testGetConversionMultipliers() - { - $result = PHPExcel_Calculation_Engineering::getConversionMultipliers(); - $this->assertInternalType('array', $result); - } - - /** - * @dataProvider providerCONVERTUOM - */ - public function testCONVERTUOM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','CONVERTUOM'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } - - public function providerCONVERTUOM() - { - return new testDataFileIterator('rawTestData/Calculation/Engineering/CONVERTUOM.data'); - } - -} +assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerBESSELI() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELI.data'); + } + + /** + * @dataProvider providerBESSELJ + */ + public function testBESSELJ() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELJ'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerBESSELJ() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELJ.data'); + } + + /** + * @dataProvider providerBESSELK + */ + public function testBESSELK() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELK'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerBESSELK() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELK.data'); + } + + /** + * @dataProvider providerBESSELY + */ + public function testBESSELY() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELY'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerBESSELY() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELY.data'); + } + + /** + * @dataProvider providerCOMPLEX + */ + public function testCOMPLEX() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','COMPLEX'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerCOMPLEX() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/COMPLEX.data'); + } + + /** + * @dataProvider providerIMAGINARY + */ + public function testIMAGINARY() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMAGINARY'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIMAGINARY() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMAGINARY.data'); + } + + /** + * @dataProvider providerIMREAL + */ + public function testIMREAL() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMREAL'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIMREAL() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMREAL.data'); + } + + /** + * @dataProvider providerIMABS + */ + public function testIMABS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMABS'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIMABS() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMABS.data'); + } + + /** + * @dataProvider providerIMARGUMENT + */ + public function testIMARGUMENT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMARGUMENT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIMARGUMENT() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMARGUMENT.data'); + } + + /** + * @dataProvider providerIMCONJUGATE + */ + public function testIMCONJUGATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCONJUGATE'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMCONJUGATE() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMCONJUGATE.data'); + } + + /** + * @dataProvider providerIMCOS + */ + public function testIMCOS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCOS'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMCOS() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMCOS.data'); + } + + /** + * @dataProvider providerIMDIV + */ + public function testIMDIV() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMDIV'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMDIV() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMDIV.data'); + } + + /** + * @dataProvider providerIMEXP + */ + public function testIMEXP() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMEXP'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMEXP() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMEXP.data'); + } + + /** + * @dataProvider providerIMLN + */ + public function testIMLN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLN'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMLN() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLN.data'); + } + + /** + * @dataProvider providerIMLOG2 + */ + public function testIMLOG2() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG2'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMLOG2() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLOG2.data'); + } + + /** + * @dataProvider providerIMLOG10 + */ + public function testIMLOG10() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG10'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMLOG10() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLOG10.data'); + } + + /** + * @dataProvider providerIMPOWER + */ + public function testIMPOWER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPOWER'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMPOWER() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMPOWER.data'); + } + + /** + * @dataProvider providerIMPRODUCT + */ + public function testIMPRODUCT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPRODUCT'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMPRODUCT() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMPRODUCT.data'); + } + + /** + * @dataProvider providerIMSIN + */ + public function testIMSIN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSIN'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMSIN() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSIN.data'); + } + + /** + * @dataProvider providerIMSQRT + */ + public function testIMSQRT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSQRT'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMSQRT() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSQRT.data'); + } + + /** + * @dataProvider providerIMSUB + */ + public function testIMSUB() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUB'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMSUB() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUB.data'); + } + + /** + * @dataProvider providerIMSUM + */ + public function testIMSUM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } + + public function providerIMSUM() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUM.data'); + } + + /** + * @dataProvider providerERF + */ + public function testERF() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERF'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerERF() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/ERF.data'); + } + + /** + * @dataProvider providerERFC + */ + public function testERFC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERFC'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerERFC() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/ERFC.data'); + } + + /** + * @dataProvider providerBIN2DEC + */ + public function testBIN2DEC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTODEC'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerBIN2DEC() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2DEC.data'); + } + + /** + * @dataProvider providerBIN2HEX + */ + public function testBIN2HEX() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOHEX'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerBIN2HEX() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2HEX.data'); + } + + /** + * @dataProvider providerBIN2OCT + */ + public function testBIN2OCT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOOCT'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerBIN2OCT() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2OCT.data'); + } + + /** + * @dataProvider providerDEC2BIN + */ + public function testDEC2BIN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOBIN'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerDEC2BIN() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2BIN.data'); + } + + /** + * @dataProvider providerDEC2HEX + */ + public function testDEC2HEX() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOHEX'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerDEC2HEX() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2HEX.data'); + } + + /** + * @dataProvider providerDEC2OCT + */ + public function testDEC2OCT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOOCT'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerDEC2OCT() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2OCT.data'); + } + + /** + * @dataProvider providerHEX2BIN + */ + public function testHEX2BIN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOBIN'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerHEX2BIN() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2BIN.data'); + } + + /** + * @dataProvider providerHEX2DEC + */ + public function testHEX2DEC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTODEC'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerHEX2DEC() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2DEC.data'); + } + + /** + * @dataProvider providerHEX2OCT + */ + public function testHEX2OCT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOOCT'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerHEX2OCT() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2OCT.data'); + } + + /** + * @dataProvider providerOCT2BIN + */ + public function testOCT2BIN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOBIN'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerOCT2BIN() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2BIN.data'); + } + + /** + * @dataProvider providerOCT2DEC + */ + public function testOCT2DEC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTODEC'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerOCT2DEC() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2DEC.data'); + } + + /** + * @dataProvider providerOCT2HEX + */ + public function testOCT2HEX() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOHEX'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerOCT2HEX() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2HEX.data'); + } + + /** + * @dataProvider providerDELTA + */ + public function testDELTA() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DELTA'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerDELTA() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/DELTA.data'); + } + + /** + * @dataProvider providerGESTEP + */ + public function testGESTEP() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','GESTEP'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerGESTEP() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/GESTEP.data'); + } + + public function testGetConversionGroups() + { + $result = PHPExcel_Calculation_Engineering::getConversionGroups(); + $this->assertInternalType('array', $result); + } + + public function testGetConversionGroupUnits() + { + $result = PHPExcel_Calculation_Engineering::getConversionGroupUnits(); + $this->assertInternalType('array', $result); + } + + public function testGetConversionGroupUnitDetails() + { + $result = PHPExcel_Calculation_Engineering::getConversionGroupUnitDetails(); + $this->assertInternalType('array', $result); + } + + public function testGetConversionMultipliers() + { + $result = PHPExcel_Calculation_Engineering::getConversionMultipliers(); + $this->assertInternalType('array', $result); + } + + /** + * @dataProvider providerCONVERTUOM + */ + public function testCONVERTUOM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','CONVERTUOM'),$args); + $this->assertEquals($expectedResult, $result, NULL); + } + + public function providerCONVERTUOM() + { + return new testDataFileIterator('rawTestData/Calculation/Engineering/CONVERTUOM.data'); + } + +} diff --git a/unitTests/PHPExcel/Calculation/FinancialTest.php b/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php similarity index 96% rename from unitTests/PHPExcel/Calculation/FinancialTest.php rename to unitTests/Classes/PHPExcel/Calculation/FinancialTest.php index 2a333341..b27a6a7d 100644 --- a/unitTests/PHPExcel/Calculation/FinancialTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php @@ -1,514 +1,514 @@ -assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerACCRINT() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/ACCRINT.data'); - } - - /** - * @dataProvider providerACCRINTM - */ - public function testACCRINTM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINTM'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerACCRINTM() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/ACCRINTM.data'); - } - - /** - * @dataProvider providerAMORDEGRC - */ - public function testAMORDEGRC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORDEGRC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerAMORDEGRC() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/AMORDEGRC.data'); - } - - /** - * @dataProvider providerAMORLINC - */ - public function testAMORLINC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORLINC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerAMORLINC() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/AMORLINC.data'); - } - - /** - * @dataProvider providerCOUPDAYBS - */ - public function testCOUPDAYBS() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYBS'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerCOUPDAYBS() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYBS.data'); - } - - /** - * @dataProvider providerCOUPDAYS - */ - public function testCOUPDAYS() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYS'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerCOUPDAYS() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYS.data'); - } - - /** - * @dataProvider providerCOUPDAYSNC - */ - public function testCOUPDAYSNC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYSNC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerCOUPDAYSNC() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYSNC.data'); - } - - /** - * @dataProvider providerCOUPNCD - */ - public function testCOUPNCD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNCD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerCOUPNCD() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPNCD.data'); - } - - /** - * @dataProvider providerCOUPNUM - */ - public function testCOUPNUM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNUM'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerCOUPNUM() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPNUM.data'); - } - - /** - * @dataProvider providerCOUPPCD - */ - public function testCOUPPCD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPPCD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerCOUPPCD() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPPCD.data'); - } - - /** - * @dataProvider providerCUMIPMT - */ - public function testCUMIPMT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMIPMT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerCUMIPMT() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/CUMIPMT.data'); - } - - /** - * @dataProvider providerCUMPRINC - */ - public function testCUMPRINC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMPRINC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerCUMPRINC() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/CUMPRINC.data'); - } - - /** - * @dataProvider providerDB - */ - public function testDB() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DB'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerDB() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/DB.data'); - } - - /** - * @dataProvider providerDDB - */ - public function testDDB() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DDB'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerDDB() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/DDB.data'); - } - - /** - * @dataProvider providerDISC - */ - public function testDISC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DISC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerDISC() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/DISC.data'); - } - - /** - * @dataProvider providerDOLLARDE - */ - public function testDOLLARDE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARDE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerDOLLARDE() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/DOLLARDE.data'); - } - - /** - * @dataProvider providerDOLLARFR - */ - public function testDOLLARFR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARFR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerDOLLARFR() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/DOLLARFR.data'); - } - - /** - * @dataProvider providerEFFECT - */ - public function testEFFECT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','EFFECT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerEFFECT() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/EFFECT.data'); - } - - /** - * @dataProvider providerFV - */ - public function testFV() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FV'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerFV() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/FV.data'); - } - - /** - * @dataProvider providerFVSCHEDULE - */ - public function testFVSCHEDULE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FVSCHEDULE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerFVSCHEDULE() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/FVSCHEDULE.data'); - } - - /** - * @dataProvider providerINTRATE - */ - public function testINTRATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','INTRATE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerINTRATE() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/INTRATE.data'); - } - - /** - * @dataProvider providerIPMT - */ - public function testIPMT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IPMT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIPMT() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/IPMT.data'); - } - - /** - * @dataProvider providerIRR - */ - public function testIRR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IRR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIRR() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/IRR.data'); - } - - /** - * @dataProvider providerISPMT - */ - public function testISPMT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ISPMT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerISPMT() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/ISPMT.data'); - } - - /** - * @dataProvider providerMIRR - */ - public function testMIRR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','MIRR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerMIRR() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/MIRR.data'); - } - - /** - * @dataProvider providerNOMINAL - */ - public function testNOMINAL() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NOMINAL'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerNOMINAL() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/NOMINAL.data'); - } - - /** - * @dataProvider providerNPER - */ - public function testNPER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPER'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerNPER() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/NPER.data'); - } - - /** - * @dataProvider providerNPV - */ - public function testNPV() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPV'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerNPV() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/NPV.data'); - } - - /** - * @dataProvider providerPRICE - */ - public function testPRICE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','PRICE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerPRICE() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/PRICE.data'); - } - - /** - * @dataProvider providerRATE - */ - public function testRATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','RATE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerRATE() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/RATE.data'); - } - - /** - * @dataProvider providerXIRR - */ - public function testXIRR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','XIRR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerXIRR() - { - return new testDataFileIterator('rawTestData/Calculation/Financial/XIRR.data'); - } - -} +assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerACCRINT() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/ACCRINT.data'); + } + + /** + * @dataProvider providerACCRINTM + */ + public function testACCRINTM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINTM'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerACCRINTM() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/ACCRINTM.data'); + } + + /** + * @dataProvider providerAMORDEGRC + */ + public function testAMORDEGRC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORDEGRC'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerAMORDEGRC() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/AMORDEGRC.data'); + } + + /** + * @dataProvider providerAMORLINC + */ + public function testAMORLINC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORLINC'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerAMORLINC() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/AMORLINC.data'); + } + + /** + * @dataProvider providerCOUPDAYBS + */ + public function testCOUPDAYBS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYBS'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerCOUPDAYBS() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYBS.data'); + } + + /** + * @dataProvider providerCOUPDAYS + */ + public function testCOUPDAYS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYS'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerCOUPDAYS() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYS.data'); + } + + /** + * @dataProvider providerCOUPDAYSNC + */ + public function testCOUPDAYSNC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYSNC'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerCOUPDAYSNC() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYSNC.data'); + } + + /** + * @dataProvider providerCOUPNCD + */ + public function testCOUPNCD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNCD'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerCOUPNCD() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPNCD.data'); + } + + /** + * @dataProvider providerCOUPNUM + */ + public function testCOUPNUM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNUM'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerCOUPNUM() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPNUM.data'); + } + + /** + * @dataProvider providerCOUPPCD + */ + public function testCOUPPCD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPPCD'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerCOUPPCD() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPPCD.data'); + } + + /** + * @dataProvider providerCUMIPMT + */ + public function testCUMIPMT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMIPMT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerCUMIPMT() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/CUMIPMT.data'); + } + + /** + * @dataProvider providerCUMPRINC + */ + public function testCUMPRINC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMPRINC'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerCUMPRINC() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/CUMPRINC.data'); + } + + /** + * @dataProvider providerDB + */ + public function testDB() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DB'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerDB() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/DB.data'); + } + + /** + * @dataProvider providerDDB + */ + public function testDDB() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DDB'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerDDB() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/DDB.data'); + } + + /** + * @dataProvider providerDISC + */ + public function testDISC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DISC'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerDISC() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/DISC.data'); + } + + /** + * @dataProvider providerDOLLARDE + */ + public function testDOLLARDE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARDE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerDOLLARDE() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/DOLLARDE.data'); + } + + /** + * @dataProvider providerDOLLARFR + */ + public function testDOLLARFR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARFR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerDOLLARFR() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/DOLLARFR.data'); + } + + /** + * @dataProvider providerEFFECT + */ + public function testEFFECT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','EFFECT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerEFFECT() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/EFFECT.data'); + } + + /** + * @dataProvider providerFV + */ + public function testFV() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FV'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerFV() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/FV.data'); + } + + /** + * @dataProvider providerFVSCHEDULE + */ + public function testFVSCHEDULE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FVSCHEDULE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerFVSCHEDULE() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/FVSCHEDULE.data'); + } + + /** + * @dataProvider providerINTRATE + */ + public function testINTRATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','INTRATE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerINTRATE() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/INTRATE.data'); + } + + /** + * @dataProvider providerIPMT + */ + public function testIPMT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IPMT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIPMT() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/IPMT.data'); + } + + /** + * @dataProvider providerIRR + */ + public function testIRR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IRR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIRR() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/IRR.data'); + } + + /** + * @dataProvider providerISPMT + */ + public function testISPMT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ISPMT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerISPMT() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/ISPMT.data'); + } + + /** + * @dataProvider providerMIRR + */ + public function testMIRR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','MIRR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerMIRR() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/MIRR.data'); + } + + /** + * @dataProvider providerNOMINAL + */ + public function testNOMINAL() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NOMINAL'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerNOMINAL() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/NOMINAL.data'); + } + + /** + * @dataProvider providerNPER + */ + public function testNPER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPER'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerNPER() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/NPER.data'); + } + + /** + * @dataProvider providerNPV + */ + public function testNPV() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPV'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerNPV() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/NPV.data'); + } + + /** + * @dataProvider providerPRICE + */ + public function testPRICE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','PRICE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerPRICE() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/PRICE.data'); + } + + /** + * @dataProvider providerRATE + */ + public function testRATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','RATE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerRATE() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/RATE.data'); + } + + /** + * @dataProvider providerXIRR + */ + public function testXIRR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','XIRR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerXIRR() + { + return new testDataFileIterator('rawTestData/Calculation/Financial/XIRR.data'); + } + +} diff --git a/unitTests/PHPExcel/Calculation/FunctionsTest.php b/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php similarity index 96% rename from unitTests/PHPExcel/Calculation/FunctionsTest.php rename to unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php index e9206864..5e6ef962 100644 --- a/unitTests/PHPExcel/Calculation/FunctionsTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php @@ -1,274 +1,274 @@ -assertEquals('#Not Yet Implemented', $result); - } - - public function testDIV0() - { - $result = PHPExcel_Calculation_Functions::DIV0(); - $this->assertEquals('#DIV/0!', $result); - } - - public function testNA() - { - $result = PHPExcel_Calculation_Functions::NA(); - $this->assertEquals('#N/A', $result); - } - - public function testNaN() - { - $result = PHPExcel_Calculation_Functions::NaN(); - $this->assertEquals('#NUM!', $result); - } - - public function testNAME() - { - $result = PHPExcel_Calculation_Functions::NAME(); - $this->assertEquals('#NAME?', $result); - } - - public function testREF() - { - $result = PHPExcel_Calculation_Functions::REF(); - $this->assertEquals('#REF!', $result); - } - - public function testNULL() - { - $result = PHPExcel_Calculation_Functions::NULL(); - $this->assertEquals('#NULL!', $result); - } - - public function testVALUE() - { - $result = PHPExcel_Calculation_Functions::VALUE(); - $this->assertEquals('#VALUE!', $result); - } - - /** - * @dataProvider providerIS_BLANK - */ - public function testIS_BLANK() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_BLANK'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIS_BLANK() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_BLANK.data'); - } - - /** - * @dataProvider providerIS_ERR - */ - public function testIS_ERR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIS_ERR() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ERR.data'); - } - - /** - * @dataProvider providerIS_ERROR - */ - public function testIS_ERROR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERROR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIS_ERROR() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ERROR.data'); - } - - /** - * @dataProvider providerERROR_TYPE - */ - public function testERROR_TYPE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','ERROR_TYPE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerERROR_TYPE() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/ERROR_TYPE.data'); - } - - /** - * @dataProvider providerIS_LOGICAL - */ - public function testIS_LOGICAL() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_LOGICAL'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIS_LOGICAL() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_LOGICAL.data'); - } - - /** - * @dataProvider providerIS_NA - */ - public function testIS_NA() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NA'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIS_NA() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NA.data'); - } - - /** - * @dataProvider providerIS_NUMBER - */ - public function testIS_NUMBER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NUMBER'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIS_NUMBER() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NUMBER.data'); - } - - /** - * @dataProvider providerIS_TEXT - */ - public function testIS_TEXT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_TEXT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIS_TEXT() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_TEXT.data'); - } - - /** - * @dataProvider providerIS_NONTEXT - */ - public function testIS_NONTEXT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NONTEXT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIS_NONTEXT() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NONTEXT.data'); - } - - /** - * @dataProvider providerIS_EVEN - */ - public function testIS_EVEN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_EVEN'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIS_EVEN() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_EVEN.data'); - } - - /** - * @dataProvider providerIS_ODD - */ - public function testIS_ODD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ODD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerIS_ODD() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ODD.data'); - } - - /** - * @dataProvider providerTYPE - */ - public function testTYPE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','TYPE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerTYPE() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/TYPE.data'); - } - - /** - * @dataProvider providerN - */ - public function testN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','N'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } - - public function providerN() - { - return new testDataFileIterator('rawTestData/Calculation/Functions/N.data'); - } - -} +assertEquals('#Not Yet Implemented', $result); + } + + public function testDIV0() + { + $result = PHPExcel_Calculation_Functions::DIV0(); + $this->assertEquals('#DIV/0!', $result); + } + + public function testNA() + { + $result = PHPExcel_Calculation_Functions::NA(); + $this->assertEquals('#N/A', $result); + } + + public function testNaN() + { + $result = PHPExcel_Calculation_Functions::NaN(); + $this->assertEquals('#NUM!', $result); + } + + public function testNAME() + { + $result = PHPExcel_Calculation_Functions::NAME(); + $this->assertEquals('#NAME?', $result); + } + + public function testREF() + { + $result = PHPExcel_Calculation_Functions::REF(); + $this->assertEquals('#REF!', $result); + } + + public function testNULL() + { + $result = PHPExcel_Calculation_Functions::NULL(); + $this->assertEquals('#NULL!', $result); + } + + public function testVALUE() + { + $result = PHPExcel_Calculation_Functions::VALUE(); + $this->assertEquals('#VALUE!', $result); + } + + /** + * @dataProvider providerIS_BLANK + */ + public function testIS_BLANK() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_BLANK'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIS_BLANK() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_BLANK.data'); + } + + /** + * @dataProvider providerIS_ERR + */ + public function testIS_ERR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIS_ERR() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ERR.data'); + } + + /** + * @dataProvider providerIS_ERROR + */ + public function testIS_ERROR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERROR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIS_ERROR() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ERROR.data'); + } + + /** + * @dataProvider providerERROR_TYPE + */ + public function testERROR_TYPE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','ERROR_TYPE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerERROR_TYPE() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/ERROR_TYPE.data'); + } + + /** + * @dataProvider providerIS_LOGICAL + */ + public function testIS_LOGICAL() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_LOGICAL'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIS_LOGICAL() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_LOGICAL.data'); + } + + /** + * @dataProvider providerIS_NA + */ + public function testIS_NA() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NA'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIS_NA() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NA.data'); + } + + /** + * @dataProvider providerIS_NUMBER + */ + public function testIS_NUMBER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NUMBER'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIS_NUMBER() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NUMBER.data'); + } + + /** + * @dataProvider providerIS_TEXT + */ + public function testIS_TEXT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_TEXT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIS_TEXT() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_TEXT.data'); + } + + /** + * @dataProvider providerIS_NONTEXT + */ + public function testIS_NONTEXT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NONTEXT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIS_NONTEXT() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NONTEXT.data'); + } + + /** + * @dataProvider providerIS_EVEN + */ + public function testIS_EVEN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_EVEN'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIS_EVEN() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_EVEN.data'); + } + + /** + * @dataProvider providerIS_ODD + */ + public function testIS_ODD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ODD'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerIS_ODD() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ODD.data'); + } + + /** + * @dataProvider providerTYPE + */ + public function testTYPE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','TYPE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerTYPE() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/TYPE.data'); + } + + /** + * @dataProvider providerN + */ + public function testN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','N'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerN() + { + return new testDataFileIterator('rawTestData/Calculation/Functions/N.data'); + } + +} diff --git a/unitTests/PHPExcel/Calculation/LogicalTest.php b/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php similarity index 96% rename from unitTests/PHPExcel/Calculation/LogicalTest.php rename to unitTests/Classes/PHPExcel/Calculation/LogicalTest.php index b7d2f0a7..46749d12 100644 --- a/unitTests/PHPExcel/Calculation/LogicalTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php @@ -1,110 +1,110 @@ -assertEquals(TRUE, $result); - } - - public function testFALSE() - { - $result = PHPExcel_Calculation_Logical::FALSE(); - $this->assertEquals(FALSE, $result); - } - - /** - * @dataProvider providerAND - */ - public function testAND() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_AND'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerAND() - { - return new testDataFileIterator('rawTestData/Calculation/Logical/AND.data'); - } - - /** - * @dataProvider providerOR - */ - public function testOR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_OR'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerOR() - { - return new testDataFileIterator('rawTestData/Calculation/Logical/OR.data'); - } - - /** - * @dataProvider providerNOT - */ - public function testNOT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','NOT'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerNOT() - { - return new testDataFileIterator('rawTestData/Calculation/Logical/NOT.data'); - } - - /** - * @dataProvider providerIF - */ - public function testIF() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','STATEMENT_IF'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerIF() - { - return new testDataFileIterator('rawTestData/Calculation/Logical/IF.data'); - } - - /** - * @dataProvider providerIFERROR - */ - public function testIFERROR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','IFERROR'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerIFERROR() - { - return new testDataFileIterator('rawTestData/Calculation/Logical/IFERROR.data'); - } - -} +assertEquals(TRUE, $result); + } + + public function testFALSE() + { + $result = PHPExcel_Calculation_Logical::FALSE(); + $this->assertEquals(FALSE, $result); + } + + /** + * @dataProvider providerAND + */ + public function testAND() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_AND'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerAND() + { + return new testDataFileIterator('rawTestData/Calculation/Logical/AND.data'); + } + + /** + * @dataProvider providerOR + */ + public function testOR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_OR'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerOR() + { + return new testDataFileIterator('rawTestData/Calculation/Logical/OR.data'); + } + + /** + * @dataProvider providerNOT + */ + public function testNOT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','NOT'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerNOT() + { + return new testDataFileIterator('rawTestData/Calculation/Logical/NOT.data'); + } + + /** + * @dataProvider providerIF + */ + public function testIF() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','STATEMENT_IF'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerIF() + { + return new testDataFileIterator('rawTestData/Calculation/Logical/IF.data'); + } + + /** + * @dataProvider providerIFERROR + */ + public function testIFERROR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','IFERROR'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerIFERROR() + { + return new testDataFileIterator('rawTestData/Calculation/Logical/IFERROR.data'); + } + +} diff --git a/unitTests/PHPExcel/Calculation/MathTrigTest.php b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php similarity index 96% rename from unitTests/PHPExcel/Calculation/MathTrigTest.php rename to unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php index 74b2c7c4..ce448d6a 100644 --- a/unitTests/PHPExcel/Calculation/MathTrigTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php @@ -1,484 +1,484 @@ -assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerATAN2() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/ATAN2.data'); - } - - /** - * @dataProvider providerCEILING - */ - public function testCEILING() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','CEILING'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerCEILING() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/CEILING.data'); - } - - /** - * @dataProvider providerCOMBIN - */ - public function testCOMBIN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','COMBIN'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerCOMBIN() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/COMBIN.data'); - } - - /** - * @dataProvider providerEVEN - */ - public function testEVEN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','EVEN'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerEVEN() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/EVEN.data'); - } - - /** - * @dataProvider providerODD - */ - public function testODD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ODD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerODD() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/ODD.data'); - } - - /** - * @dataProvider providerFACT - */ - public function testFACT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerFACT() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/FACT.data'); - } - - /** - * @dataProvider providerFACTDOUBLE - */ - public function testFACTDOUBLE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACTDOUBLE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerFACTDOUBLE() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/FACTDOUBLE.data'); - } - - /** - * @dataProvider providerFLOOR - */ - public function testFLOOR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FLOOR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerFLOOR() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/FLOOR.data'); - } - - /** - * @dataProvider providerGCD - */ - public function testGCD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','GCD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerGCD() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/GCD.data'); - } - - /** - * @dataProvider providerLCM - */ - public function testLCM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LCM'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerLCM() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/LCM.data'); - } - - /** - * @dataProvider providerINT - */ - public function testINT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','INT'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerINT() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/INT.data'); - } - - /** - * @dataProvider providerSIGN - */ - public function testSIGN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SIGN'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerSIGN() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/SIGN.data'); - } - - /** - * @dataProvider providerPOWER - */ - public function testPOWER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','POWER'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerPOWER() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/POWER.data'); - } - - /** - * @dataProvider providerLOG - */ - public function testLOG() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LOG_BASE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerLOG() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/LOG.data'); - } - - /** - * @dataProvider providerMOD - */ - public function testMOD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MOD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerMOD() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MOD.data'); - } - - /** - * @dataProvider providerMDETERM - */ - public function testMDETERM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MDETERM'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerMDETERM() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MDETERM.data'); - } - - /** - * @dataProvider providerMINVERSE - */ - public function testMINVERSE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MINVERSE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerMINVERSE() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MINVERSE.data'); - } - - /** - * @dataProvider providerMMULT - */ - public function testMMULT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MMULT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerMMULT() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MMULT.data'); - } - - /** - * @dataProvider providerMULTINOMIAL - */ - public function testMULTINOMIAL() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MULTINOMIAL'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerMULTINOMIAL() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MULTINOMIAL.data'); - } - - /** - * @dataProvider providerMROUND - */ - public function testMROUND() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MROUND'),$args); - PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_ARRAY); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerMROUND() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MROUND.data'); - } - - /** - * @dataProvider providerPRODUCT - */ - public function testPRODUCT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','PRODUCT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerPRODUCT() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/PRODUCT.data'); - } - - /** - * @dataProvider providerQUOTIENT - */ - public function testQUOTIENT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','QUOTIENT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerQUOTIENT() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/QUOTIENT.data'); - } - - /** - * @dataProvider providerROUNDUP - */ - public function testROUNDUP() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDUP'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerROUNDUP() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROUNDUP.data'); - } - - /** - * @dataProvider providerROUNDDOWN - */ - public function testROUNDDOWN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDDOWN'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerROUNDDOWN() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROUNDDOWN.data'); - } - - /** - * @dataProvider providerSERIESSUM - */ - public function testSERIESSUM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SERIESSUM'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerSERIESSUM() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/SERIESSUM.data'); - } - - /** - * @dataProvider providerSUMSQ - */ - public function testSUMSQ() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SUMSQ'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerSUMSQ() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/SUMSQ.data'); - } - - /** - * @dataProvider providerTRUNC - */ - public function testTRUNC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','TRUNC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerTRUNC() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/TRUNC.data'); - } - - /** - * @dataProvider providerROMAN - */ - public function testROMAN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROMAN'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerROMAN() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROMAN.data'); - } - - /** - * @dataProvider providerSQRTPI - */ - public function testSQRTPI() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SQRTPI'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } - - public function providerSQRTPI() - { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/SQRTPI.data'); - } - -} +assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerATAN2() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/ATAN2.data'); + } + + /** + * @dataProvider providerCEILING + */ + public function testCEILING() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','CEILING'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerCEILING() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/CEILING.data'); + } + + /** + * @dataProvider providerCOMBIN + */ + public function testCOMBIN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','COMBIN'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerCOMBIN() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/COMBIN.data'); + } + + /** + * @dataProvider providerEVEN + */ + public function testEVEN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','EVEN'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerEVEN() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/EVEN.data'); + } + + /** + * @dataProvider providerODD + */ + public function testODD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ODD'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerODD() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/ODD.data'); + } + + /** + * @dataProvider providerFACT + */ + public function testFACT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerFACT() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/FACT.data'); + } + + /** + * @dataProvider providerFACTDOUBLE + */ + public function testFACTDOUBLE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACTDOUBLE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerFACTDOUBLE() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/FACTDOUBLE.data'); + } + + /** + * @dataProvider providerFLOOR + */ + public function testFLOOR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FLOOR'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerFLOOR() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/FLOOR.data'); + } + + /** + * @dataProvider providerGCD + */ + public function testGCD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','GCD'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerGCD() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/GCD.data'); + } + + /** + * @dataProvider providerLCM + */ + public function testLCM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LCM'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerLCM() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/LCM.data'); + } + + /** + * @dataProvider providerINT + */ + public function testINT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','INT'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerINT() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/INT.data'); + } + + /** + * @dataProvider providerSIGN + */ + public function testSIGN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SIGN'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerSIGN() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/SIGN.data'); + } + + /** + * @dataProvider providerPOWER + */ + public function testPOWER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','POWER'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerPOWER() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/POWER.data'); + } + + /** + * @dataProvider providerLOG + */ + public function testLOG() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LOG_BASE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerLOG() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/LOG.data'); + } + + /** + * @dataProvider providerMOD + */ + public function testMOD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MOD'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerMOD() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MOD.data'); + } + + /** + * @dataProvider providerMDETERM + */ + public function testMDETERM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MDETERM'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerMDETERM() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MDETERM.data'); + } + + /** + * @dataProvider providerMINVERSE + */ + public function testMINVERSE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MINVERSE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerMINVERSE() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MINVERSE.data'); + } + + /** + * @dataProvider providerMMULT + */ + public function testMMULT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MMULT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerMMULT() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MMULT.data'); + } + + /** + * @dataProvider providerMULTINOMIAL + */ + public function testMULTINOMIAL() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MULTINOMIAL'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerMULTINOMIAL() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MULTINOMIAL.data'); + } + + /** + * @dataProvider providerMROUND + */ + public function testMROUND() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MROUND'),$args); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_ARRAY); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerMROUND() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MROUND.data'); + } + + /** + * @dataProvider providerPRODUCT + */ + public function testPRODUCT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','PRODUCT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerPRODUCT() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/PRODUCT.data'); + } + + /** + * @dataProvider providerQUOTIENT + */ + public function testQUOTIENT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','QUOTIENT'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerQUOTIENT() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/QUOTIENT.data'); + } + + /** + * @dataProvider providerROUNDUP + */ + public function testROUNDUP() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDUP'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerROUNDUP() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROUNDUP.data'); + } + + /** + * @dataProvider providerROUNDDOWN + */ + public function testROUNDDOWN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDDOWN'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerROUNDDOWN() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROUNDDOWN.data'); + } + + /** + * @dataProvider providerSERIESSUM + */ + public function testSERIESSUM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SERIESSUM'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerSERIESSUM() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/SERIESSUM.data'); + } + + /** + * @dataProvider providerSUMSQ + */ + public function testSUMSQ() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SUMSQ'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerSUMSQ() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/SUMSQ.data'); + } + + /** + * @dataProvider providerTRUNC + */ + public function testTRUNC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','TRUNC'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerTRUNC() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/TRUNC.data'); + } + + /** + * @dataProvider providerROMAN + */ + public function testROMAN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROMAN'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerROMAN() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROMAN.data'); + } + + /** + * @dataProvider providerSQRTPI + */ + public function testSQRTPI() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SQRTPI'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerSQRTPI() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/SQRTPI.data'); + } + +} diff --git a/unitTests/PHPExcel/Calculation/TextDataTest.php b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php similarity index 96% rename from unitTests/PHPExcel/Calculation/TextDataTest.php rename to unitTests/Classes/PHPExcel/Calculation/TextDataTest.php index 50d27bbd..717e8fef 100644 --- a/unitTests/PHPExcel/Calculation/TextDataTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php @@ -1,343 +1,343 @@ -assertEquals($expectedResult, $result); - } - - public function providerCHAR() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/CHAR.data'); - } - - /** - * @dataProvider providerCODE - */ - public function testCODE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','ASCIICODE'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerCODE() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/CODE.data'); - } - - /** - * @dataProvider providerCONCATENATE - */ - public function testCONCATENATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','CONCATENATE'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerCONCATENATE() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/CONCATENATE.data'); - } - - /** - * @dataProvider providerLEFT - */ - public function testLEFT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LEFT'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerLEFT() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/LEFT.data'); - } - - /** - * @dataProvider providerMID - */ - public function testMID() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','MID'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerMID() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/MID.data'); - } - - /** - * @dataProvider providerRIGHT - */ - public function testRIGHT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RIGHT'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerRIGHT() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/RIGHT.data'); - } - - /** - * @dataProvider providerLOWER - */ - public function testLOWER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LOWERCASE'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerLOWER() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/LOWER.data'); - } - - /** - * @dataProvider providerUPPER - */ - public function testUPPER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','UPPERCASE'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerUPPER() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/UPPER.data'); - } - - /** - * @dataProvider providerPROPER - */ - public function testPROPER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','PROPERCASE'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerPROPER() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/PROPER.data'); - } - - /** - * @dataProvider providerLEN - */ - public function testLEN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','STRINGLENGTH'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerLEN() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/LEN.data'); - } - - /** - * @dataProvider providerSEARCH - */ - public function testSEARCH() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHINSENSITIVE'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerSEARCH() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/SEARCH.data'); - } - - /** - * @dataProvider providerFIND - */ - public function testFIND() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHSENSITIVE'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerFIND() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/FIND.data'); - } - - /** - * @dataProvider providerREPLACE - */ - public function testREPLACE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','REPLACE'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerREPLACE() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/REPLACE.data'); - } - - /** - * @dataProvider providerSUBSTITUTE - */ - public function testSUBSTITUTE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SUBSTITUTE'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerSUBSTITUTE() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/SUBSTITUTE.data'); - } - - /** - * @dataProvider providerTRIM - */ - public function testTRIM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMSPACES'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerTRIM() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/TRIM.data'); - } - - /** - * @dataProvider providerCLEAN - */ - public function testCLEAN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMNONPRINTABLE'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerCLEAN() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/CLEAN.data'); - } - - /** - * @dataProvider providerDOLLAR - */ - public function testDOLLAR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','DOLLAR'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerDOLLAR() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/DOLLAR.data'); - } - - /** - * @dataProvider providerFIXED - */ - public function testFIXED() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','FIXEDFORMAT'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerFIXED() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/FIXED.data'); - } - - /** - * @dataProvider providerT - */ - public function testT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RETURNSTRING'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerT() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/T.data'); - } - - /** - * @dataProvider providerTEXT - */ - public function testTEXT() - { - // Enforce decimal and thousands separator values to UK/US, and currency code to USD - call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.'); - call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),','); - call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$'); - - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TEXTFORMAT'),$args); - $this->assertEquals($expectedResult, $result); - } - - public function providerTEXT() - { - return new testDataFileIterator('rawTestData/Calculation/TextData/TEXT.data'); - } - -} +assertEquals($expectedResult, $result); + } + + public function providerCHAR() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/CHAR.data'); + } + + /** + * @dataProvider providerCODE + */ + public function testCODE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','ASCIICODE'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerCODE() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/CODE.data'); + } + + /** + * @dataProvider providerCONCATENATE + */ + public function testCONCATENATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','CONCATENATE'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerCONCATENATE() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/CONCATENATE.data'); + } + + /** + * @dataProvider providerLEFT + */ + public function testLEFT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LEFT'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerLEFT() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/LEFT.data'); + } + + /** + * @dataProvider providerMID + */ + public function testMID() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','MID'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerMID() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/MID.data'); + } + + /** + * @dataProvider providerRIGHT + */ + public function testRIGHT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RIGHT'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerRIGHT() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/RIGHT.data'); + } + + /** + * @dataProvider providerLOWER + */ + public function testLOWER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LOWERCASE'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerLOWER() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/LOWER.data'); + } + + /** + * @dataProvider providerUPPER + */ + public function testUPPER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','UPPERCASE'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerUPPER() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/UPPER.data'); + } + + /** + * @dataProvider providerPROPER + */ + public function testPROPER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','PROPERCASE'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerPROPER() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/PROPER.data'); + } + + /** + * @dataProvider providerLEN + */ + public function testLEN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','STRINGLENGTH'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerLEN() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/LEN.data'); + } + + /** + * @dataProvider providerSEARCH + */ + public function testSEARCH() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHINSENSITIVE'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerSEARCH() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/SEARCH.data'); + } + + /** + * @dataProvider providerFIND + */ + public function testFIND() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHSENSITIVE'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerFIND() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/FIND.data'); + } + + /** + * @dataProvider providerREPLACE + */ + public function testREPLACE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','REPLACE'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerREPLACE() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/REPLACE.data'); + } + + /** + * @dataProvider providerSUBSTITUTE + */ + public function testSUBSTITUTE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SUBSTITUTE'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerSUBSTITUTE() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/SUBSTITUTE.data'); + } + + /** + * @dataProvider providerTRIM + */ + public function testTRIM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMSPACES'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerTRIM() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/TRIM.data'); + } + + /** + * @dataProvider providerCLEAN + */ + public function testCLEAN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMNONPRINTABLE'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerCLEAN() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/CLEAN.data'); + } + + /** + * @dataProvider providerDOLLAR + */ + public function testDOLLAR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','DOLLAR'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerDOLLAR() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/DOLLAR.data'); + } + + /** + * @dataProvider providerFIXED + */ + public function testFIXED() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','FIXEDFORMAT'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerFIXED() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/FIXED.data'); + } + + /** + * @dataProvider providerT + */ + public function testT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RETURNSTRING'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerT() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/T.data'); + } + + /** + * @dataProvider providerTEXT + */ + public function testTEXT() + { + // Enforce decimal and thousands separator values to UK/US, and currency code to USD + call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.'); + call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),','); + call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$'); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TEXTFORMAT'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerTEXT() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/TEXT.data'); + } + +} diff --git a/unitTests/PHPExcel/CellTest.php b/unitTests/Classes/PHPExcel/CellTest.php similarity index 100% rename from unitTests/PHPExcel/CellTest.php rename to unitTests/Classes/PHPExcel/CellTest.php diff --git a/unitTests/PHPExcel/Chart/DataSeriesValuesTest.php b/unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php similarity index 100% rename from unitTests/PHPExcel/Chart/DataSeriesValuesTest.php rename to unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php diff --git a/unitTests/PHPExcel/Chart/LayoutTest.php b/unitTests/Classes/PHPExcel/Chart/LayoutTest.php similarity index 100% rename from unitTests/PHPExcel/Chart/LayoutTest.php rename to unitTests/Classes/PHPExcel/Chart/LayoutTest.php diff --git a/unitTests/PHPExcel/Chart/LegendTest.php b/unitTests/Classes/PHPExcel/Chart/LegendTest.php similarity index 100% rename from unitTests/PHPExcel/Chart/LegendTest.php rename to unitTests/Classes/PHPExcel/Chart/LegendTest.php diff --git a/unitTests/PHPExcel/Shared/CodePageTest.php b/unitTests/Classes/PHPExcel/Shared/CodePageTest.php similarity index 100% rename from unitTests/PHPExcel/Shared/CodePageTest.php rename to unitTests/Classes/PHPExcel/Shared/CodePageTest.php diff --git a/unitTests/PHPExcel/Shared/DateTest.php b/unitTests/Classes/PHPExcel/Shared/DateTest.php similarity index 100% rename from unitTests/PHPExcel/Shared/DateTest.php rename to unitTests/Classes/PHPExcel/Shared/DateTest.php diff --git a/unitTests/PHPExcel/Shared/StringTest.php b/unitTests/Classes/PHPExcel/Shared/StringTest.php similarity index 100% rename from unitTests/PHPExcel/Shared/StringTest.php rename to unitTests/Classes/PHPExcel/Shared/StringTest.php diff --git a/unitTests/phpunit.xml b/unitTests/phpunit.xml index a054c803..8cb6cf56 100644 --- a/unitTests/phpunit.xml +++ b/unitTests/phpunit.xml @@ -17,7 +17,7 @@ - ./PHPExcel + ./Classes From 0b60b611040ff5ad33f3f81c03074d2866366d0b Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 1 Aug 2012 17:25:10 +0100 Subject: [PATCH 20/30] Bugfix: takaakik) Work Item 15455 - getNestingLevel() Error on Excel5 Read Bugfix: ix to Excel5 Reader when cell annotations are defined before their referenced text objects --- Classes/PHPExcel/Chart/DataSeries.php | 6 + Classes/PHPExcel/Reader/Excel5.php | 179 +++++++++++++------------- Classes/PHPExcel/Shared/Date.php | 6 +- Tests/33chartcreate.php | 19 +++ changelog.txt | 4 +- 5 files changed, 122 insertions(+), 92 deletions(-) diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index 2068102e..b58b4025 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -339,6 +339,12 @@ class PHPExcel_Chart_DataSeries foreach($this->_plotValues as $plotValues) { $plotValues->refresh($worksheet); } + foreach($this->_plotLabel as $plotValues) { + $plotValues->refresh($worksheet); + } + foreach($this->_plotCategory as $plotValues) { + $plotValues->refresh($worksheet); + } } } diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 7862eda6..358bfee9 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -944,101 +944,92 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader // echo '
'; // the first shape container never has a corresponding OBJ record, hence $n + 1 - $spContainer = $allSpContainers[$n + 1]; + if (isset($allSpContainers[$n + 1]) && is_object($allSpContainers[$n + 1])) { + $spContainer = $allSpContainers[$n + 1]; - // we skip all spContainers that are a part of a group shape since we cannot yet handle those - if ($spContainer->getNestingLevel() > 1) { - continue; - } - - // calculate the width and height of the shape - list($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($spContainer->getStartCoordinates()); - list($endColumn, $endRow) = PHPExcel_Cell::coordinateFromString($spContainer->getEndCoordinates()); - - $startOffsetX = $spContainer->getStartOffsetX(); - $startOffsetY = $spContainer->getStartOffsetY(); - $endOffsetX = $spContainer->getEndOffsetX(); - $endOffsetY = $spContainer->getEndOffsetY(); - - $width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX); - $height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY); - - // calculate offsetX and offsetY of the shape - $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024; - $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256; - - switch ($obj['otObjType']) { - - case 0x19: - // Note -// echo 'Cell Annotation Object
'; -// echo 'Object ID is ',$obj['idObjID'],'
'; -// - if (isset($this->_cellNotes[$obj['idObjID']])) { - $cellNote = $this->_cellNotes[$obj['idObjID']]; - -// echo '_cellNotes[',$obj['idObjID'],']: '; -// var_dump($cellNote); -// echo '
'; -// - if (isset($this->_textObjects[$obj['idObjID']])) { - $textObject = $this->_textObjects[$obj['idObjID']]; -// echo '_textObject: '; -// var_dump($textObject); -// echo '
'; -// - $this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject; - $text = $textObject['text']; - } -// echo $text,'
'; - } - break; - - case 0x08: -// echo 'Picture Object
'; - // picture - - // get index to BSE entry (1-based) - $BSEindex = $spContainer->getOPT(0x0104); - $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection(); - $BSE = $BSECollection[$BSEindex - 1]; - $blipType = $BSE->getBlipType(); - - // need check because some blip types are not supported by Escher reader such as EMF - if ($blip = $BSE->getBlip()) { - $ih = imagecreatefromstring($blip->getData()); - $drawing = new PHPExcel_Worksheet_MemoryDrawing(); - $drawing->setImageResource($ih); - - // width, height, offsetX, offsetY - $drawing->setResizeProportional(false); - $drawing->setWidth($width); - $drawing->setHeight($height); - $drawing->setOffsetX($offsetX); - $drawing->setOffsetY($offsetY); - - switch ($blipType) { - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: - $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); - $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG); - break; - - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: - $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG); - $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG); - break; - } - - $drawing->setWorksheet($this->_phpSheet); - $drawing->setCoordinates($spContainer->getStartCoordinates()); + // we skip all spContainers that are a part of a group shape since we cannot yet handle those + if ($spContainer->getNestingLevel() > 1) { + continue; } - break; + // calculate the width and height of the shape + list($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($spContainer->getStartCoordinates()); + list($endColumn, $endRow) = PHPExcel_Cell::coordinateFromString($spContainer->getEndCoordinates()); - default: - // other object type - break; + $startOffsetX = $spContainer->getStartOffsetX(); + $startOffsetY = $spContainer->getStartOffsetY(); + $endOffsetX = $spContainer->getEndOffsetX(); + $endOffsetY = $spContainer->getEndOffsetY(); + $width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX); + $height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY); + + // calculate offsetX and offsetY of the shape + $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024; + $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256; + + switch ($obj['otObjType']) { + case 0x19: + // Note +// echo 'Cell Annotation Object
'; +// echo 'Object ID is ',$obj['idObjID'],'
'; +// + if (isset($this->_cellNotes[$obj['idObjID']])) { + $cellNote = $this->_cellNotes[$obj['idObjID']]; + + if (isset($this->_textObjects[$obj['idObjID']])) { + $textObject = $this->_textObjects[$obj['idObjID']]; + $this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject; + } + } + break; + + case 0x08: +// echo 'Picture Object
'; + // picture + + // get index to BSE entry (1-based) + $BSEindex = $spContainer->getOPT(0x0104); + $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection(); + $BSE = $BSECollection[$BSEindex - 1]; + $blipType = $BSE->getBlipType(); + + // need check because some blip types are not supported by Escher reader such as EMF + if ($blip = $BSE->getBlip()) { + $ih = imagecreatefromstring($blip->getData()); + $drawing = new PHPExcel_Worksheet_MemoryDrawing(); + $drawing->setImageResource($ih); + + // width, height, offsetX, offsetY + $drawing->setResizeProportional(false); + $drawing->setWidth($width); + $drawing->setHeight($height); + $drawing->setOffsetX($offsetX); + $drawing->setOffsetY($offsetY); + + switch ($blipType) { + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: + $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); + $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG); + break; + + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: + $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG); + $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG); + break; + } + + $drawing->setWorksheet($this->_phpSheet); + $drawing->setCoordinates($spContainer->getStartCoordinates()); + } + + break; + + default: + // other object type + break; + + } } } @@ -1055,6 +1046,14 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader if (!empty($this->_cellNotes)) { foreach($this->_cellNotes as $note => $noteDetails) { + if (!isset($noteDetails['objTextData'])) { + if (isset($this->_textObjects[$note])) { + $textObject = $this->_textObjects[$note]; + $noteDetails['objTextData'] = $textObject; + } else { + $noteDetails['objTextData']['text'] = ''; + } + } // echo 'Cell annotation ',$note,'
'; // var_dump($noteDetails); // echo '
'; diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index 071b988c..1507d588 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -238,7 +238,11 @@ class PHPExcel_Shared_Date * @return boolean */ public static function isDateTime(PHPExcel_Cell $pCell) { - return self::isDateTimeFormat($pCell->getParent()->getStyle($pCell->getCoordinate())->getNumberFormat()); + return self::isDateTimeFormat( + $pCell->getParent()->getStyle( + $pCell->getCoordinate() + )->getNumberFormat() + ); } // function isDateTime() diff --git a/Tests/33chartcreate.php b/Tests/33chartcreate.php index 47aab30d..6da43d73 100644 --- a/Tests/33chartcreate.php +++ b/Tests/33chartcreate.php @@ -50,16 +50,34 @@ $objWorksheet->fromArray( ); // Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataseriesLabels = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', null, 1), // 2010 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', null, 1), // 2011 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', null, 1), // 2012 ); // Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ); // Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues = array( new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', null, 4), new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', null, 4), @@ -76,6 +94,7 @@ $series = new PHPExcel_Chart_DataSeries( $dataSeriesValues // plotValues ); // Set additional dataseries parameters +// Make it a vertical column rather than a horizontal bar graph $series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL); // Set the series in the plot area diff --git a/changelog.txt b/changelog.txt index c8ab3613..ec0a7638 100644 --- a/changelog.txt +++ b/changelog.txt @@ -92,7 +92,9 @@ Fixed in develop branch: - Bugfix: (MBaker) Various fixes to Chart handling - Bugfix: (MBaker) Work item 18370 - Error loading xlsx file with column breaks - Bugfix: (MBaker) OOCalc Reader now handles percentage and currency data types -- Bugfix: (MBaker) Work Item 18415- mb_stripos empty delimiter +- Bugfix: (MBaker) Work Item 18415 - mb_stripos empty delimiter +- Bugfix: (takaakik) Work Item 15455 - getNestingLevel() Error on Excel5 Read +- Bugfix: (MBaker) Fix to Excel5 Reader when cell annotations are defined before their referenced text objects 2012-05-19 (v1.7.7): From 7fae37247bf97c41609eeee4fcf51e60cb96ab17 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 1 Aug 2012 21:41:00 +0100 Subject: [PATCH 21/30] General: Magic __toString() method added to Cell object to return raw data value as a string --- Classes/PHPExcel/Cell.php | 10 ++++++++++ changelog.txt | 2 ++ 2 files changed, 12 insertions(+) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 6bf16ee6..6dec3a83 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -935,5 +935,15 @@ class PHPExcel_Cell return $this->_formulaAttributes; } + /** + * Convert to string + * + * @return string + */ + public function __toString() + { + return (string) $this->getValue(); + } + } diff --git a/changelog.txt b/changelog.txt index ec0a7638..55342932 100644 --- a/changelog.txt +++ b/changelog.txt @@ -81,6 +81,8 @@ Fixed in develop branch: - Feature: (MBaker) Modified ERF and ERFC Engineering functions to accept Excel 2010's modified acceptance of negative arguments - General: (alexgann) Add Currency detection to the Advanced Value Binder - General: (MBaker) Work item 18404 - setCellValueExplicitByColumnAndRow() do not return PHPExcel_Worksheet +- General: (MBaker) Work item 18324 - Reader factory doesn't read anymore XLTX and XLT files +- General: (MBaker) Magic __toString() method added to Cell object to return raw data value as a string - Bugfix: (cyberconte) Patch 12318 - OOCalc cells containing inside the tag - Bugfix: (schir1964) Fix to listWorksheetInfo() method for OOCalc Reader - Bugfix: (MBaker) Support for "e" (epoch) date format mask From cdf9dfdcbea2d82f03a18c4082aa544cf80b8a6f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 3 Aug 2012 21:21:32 +0100 Subject: [PATCH 22/30] Unit tests, plus a couple of minor validation bugfixes --- Classes/PHPExcel/Shared/Font.php | 14 ++- Classes/PHPExcel/Style/Color.php | 41 ++++---- .../Classes/PHPExcel/Cell/HyperlinkTest.php | 88 +++++++++++++++++ .../Classes/PHPExcel/Shared/FontTest.php | 94 +++++++++++++++++++ .../PHPExcel/Shared/PasswordHasherTest.php | 33 +++++++ .../Classes/PHPExcel/Style/ColorTest.php | 81 ++++++++++++++++ .../Shared/CentimeterSizeToPixels.data | 5 + .../rawTestData/Shared/FontSizeToPixels.data | 16 ++++ .../rawTestData/Shared/InchSizeToPixels.data | 5 + .../rawTestData/Shared/PasswordHashes.data | 9 ++ .../Style/ColorChangeBrightness.data | 14 +++ unitTests/rawTestData/Style/ColorGetBlue.data | 6 ++ .../rawTestData/Style/ColorGetGreen.data | 6 ++ unitTests/rawTestData/Style/ColorGetRed.data | 6 ++ 14 files changed, 398 insertions(+), 20 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php create mode 100644 unitTests/Classes/PHPExcel/Shared/FontTest.php create mode 100644 unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php create mode 100644 unitTests/Classes/PHPExcel/Style/ColorTest.php create mode 100644 unitTests/rawTestData/Shared/CentimeterSizeToPixels.data create mode 100644 unitTests/rawTestData/Shared/FontSizeToPixels.data create mode 100644 unitTests/rawTestData/Shared/InchSizeToPixels.data create mode 100644 unitTests/rawTestData/Shared/PasswordHashes.data create mode 100644 unitTests/rawTestData/Style/ColorChangeBrightness.data create mode 100644 unitTests/rawTestData/Style/ColorGetBlue.data create mode 100644 unitTests/rawTestData/Style/ColorGetGreen.data create mode 100644 unitTests/rawTestData/Style/ColorGetRed.data diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php index 47f6b727..62260d8c 100644 --- a/Classes/PHPExcel/Shared/Font.php +++ b/Classes/PHPExcel/Shared/Font.php @@ -39,6 +39,11 @@ class PHPExcel_Shared_Font const AUTOSIZE_METHOD_APPROX = 'approx'; const AUTOSIZE_METHOD_EXACT = 'exact'; + private static $_autoSizeMethods = array( + self::AUTOSIZE_METHOD_APPROX, + self::AUTOSIZE_METHOD_EXACT, + ); + /** Character set codes used by BIFF5-8 in Font records */ const CHARSET_ANSI_LATIN = 0x00; const CHARSET_SYSTEM_DEFAULT = 0x01; @@ -187,10 +192,17 @@ class PHPExcel_Shared_Font * Set autoSize method * * @param string $pValue + * @return boolean Success or failure */ - public static function setAutoSizeMethod($pValue = 'approx') + public static function setAutoSizeMethod($pValue = self::AUTOSIZE_METHOD_APPROX) { + if (!in_array($pValue,self::$_autoSizeMethods)) { + return FALSE; + } + self::$autoSizeMethod = $pValue; + + return TRUE; } /** diff --git a/Classes/PHPExcel/Style/Color.php b/Classes/PHPExcel/Style/Color.php index a94a0eda..89c919b6 100644 --- a/Classes/PHPExcel/Style/Color.php +++ b/Classes/PHPExcel/Style/Color.php @@ -213,7 +213,7 @@ class PHPExcel_Style_Color implements PHPExcel_IComparable * @throws Exception * @return PHPExcel_Style_Color */ - public function applyFromArray($pStyles = null) { + public function applyFromArray($pStyles = NULL) { if (is_array($pStyles)) { if ($this->_isSupervisor) { $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); @@ -303,8 +303,8 @@ class PHPExcel_Style_Color implements PHPExcel_IComparable * decimal value * @return string The extracted colour component */ - private static function _getColourComponent($RGB,$offset,$hex=true) { - $colour = substr($RGB,$offset,2); + private static function _getColourComponent($RGB,$offset,$hex=TRUE) { + $colour = substr($RGB, $offset, 2); if (!$hex) $colour = hexdec($colour); return $colour; @@ -318,11 +318,11 @@ class PHPExcel_Style_Color implements PHPExcel_IComparable * decimal value * @return string The red colour component */ - public static function getRed($RGB,$hex=true) { + public static function getRed($RGB,$hex=TRUE) { if (strlen($RGB) == 8) { - return self::_getColourComponent($RGB,2,$hex); + return self::_getColourComponent($RGB, 2, $hex); } elseif (strlen($RGB) == 6) { - return self::_getColourComponent($RGB,0,$hex); + return self::_getColourComponent($RGB, 0, $hex); } } @@ -334,11 +334,11 @@ class PHPExcel_Style_Color implements PHPExcel_IComparable * decimal value * @return string The green colour component */ - public static function getGreen($RGB,$hex=true) { + public static function getGreen($RGB,$hex=TRUE) { if (strlen($RGB) == 8) { - return self::_getColourComponent($RGB,4,$hex); + return self::_getColourComponent($RGB, 4, $hex); } elseif (strlen($RGB) == 6) { - return self::_getColourComponent($RGB,2,$hex); + return self::_getColourComponent($RGB, 2, $hex); } } @@ -350,25 +350,27 @@ class PHPExcel_Style_Color implements PHPExcel_IComparable * decimal value * @return string The blue colour component */ - public static function getBlue($RGB,$hex=true) { + public static function getBlue($RGB,$hex=TRUE) { if (strlen($RGB) == 8) { - return self::_getColourComponent($RGB,6,$hex); + return self::_getColourComponent($RGB, 6, $hex); } elseif (strlen($RGB) == 6) { - return self::_getColourComponent($RGB,4,$hex); + return self::_getColourComponent($RGB, 4, $hex); } } /** * Adjust the brightness of a color * - * @param string $hex The colour as an RGB value (e.g. FF00CCCC or CCDDEE + * @param string $hex The colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE) * @param float $adjustPercentage The percentage by which to adjust the colour as a float from -1 to 1 - * @return string The adjusted colour as an RGB value (e.g. FF00CCCC or CCDDEE + * @return string The adjusted colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE) */ public static function changeBrightness($hex, $adjustPercentage) { - $red = self::getRed($hex,false); - $green = self::getGreen($hex,false); - $blue = self::getBlue($hex,false); + $rgba = (strlen($hex) == 8); + + $red = self::getRed($hex, FALSE); + $green = self::getGreen($hex, FALSE); + $blue = self::getBlue($hex, FALSE); if ($adjustPercentage > 0) { $red += (255 - $red) * $adjustPercentage; $green += (255 - $green) * $adjustPercentage; @@ -386,10 +388,11 @@ class PHPExcel_Style_Color implements PHPExcel_IComparable if ($blue < 0) $blue = 0; elseif ($blue > 255) $blue = 255; - return strtoupper( str_pad(dechex($red), 2, '0', 0) . + $rgb = strtoupper( str_pad(dechex($red), 2, '0', 0) . str_pad(dechex($green), 2, '0', 0) . str_pad(dechex($blue), 2, '0', 0) ); + return (($rgba) ? 'FF' : '') . $rgb; } /** @@ -400,7 +403,7 @@ class PHPExcel_Style_Color implements PHPExcel_IComparable * should be returned if the indexed colour doesn't exist * @return PHPExcel_Style_Color */ - public static function indexedColor($pIndex, $background=false) { + public static function indexedColor($pIndex, $background=FALSE) { // Clean parameter $pIndex = intval($pIndex); diff --git a/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php b/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php new file mode 100644 index 00000000..54910cfd --- /dev/null +++ b/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php @@ -0,0 +1,88 @@ +getUrl(); + $this->assertEquals($urlValue,$result); + } + + public function testSetUrl() + { + $initialUrlValue = 'http://www.phpexcel.net'; + $newUrlValue = 'http://github.com/PHPOffice/PHPExcel'; + + $testInstance = new PHPExcel_Cell_Hyperlink($initialUrlValue); + $result = $testInstance->setUrl($newUrlValue); + $this->assertTrue($result instanceof PHPExcel_Cell_Hyperlink); + + $result = $testInstance->getUrl(); + $this->assertEquals($newUrlValue,$result); + } + + public function testGetTooltip() + { + $tooltipValue = 'PHPExcel Web Site'; + + $testInstance = new PHPExcel_Cell_Hyperlink(NULL, $tooltipValue); + + $result = $testInstance->getTooltip(); + $this->assertEquals($tooltipValue,$result); + } + + public function testSetTooltip() + { + $initialTooltipValue = 'PHPExcel Web Site'; + $newTooltipValue = 'PHPExcel Repository on Github'; + + $testInstance = new PHPExcel_Cell_Hyperlink(NULL, $initialTooltipValue); + $result = $testInstance->setTooltip($newTooltipValue); + $this->assertTrue($result instanceof PHPExcel_Cell_Hyperlink); + + $result = $testInstance->getTooltip(); + $this->assertEquals($newTooltipValue,$result); + } + + public function testIsInternal() + { + $initialUrlValue = 'http://www.phpexcel.net'; + $newUrlValue = 'sheet://Worksheet1!A1'; + + $testInstance = new PHPExcel_Cell_Hyperlink($initialUrlValue); + $result = $testInstance->isInternal(); + $this->assertFalse($result); + + $testInstance->setUrl($newUrlValue); + $result = $testInstance->isInternal(); + $this->assertTrue($result); + } + + public function testGetHashCode() + { + $urlValue = 'http://www.phpexcel.net'; + $tooltipValue = 'PHPExcel Web Site'; + $initialExpectedHash = 'd84d713aed1dbbc8a7c5af183d6c7dbb'; + + $testInstance = new PHPExcel_Cell_Hyperlink($urlValue, $tooltipValue); + + $result = $testInstance->getHashCode(); + $this->assertEquals($initialExpectedHash,$result); + } + +} diff --git a/unitTests/Classes/PHPExcel/Shared/FontTest.php b/unitTests/Classes/PHPExcel/Shared/FontTest.php new file mode 100644 index 00000000..6ce5a026 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Shared/FontTest.php @@ -0,0 +1,94 @@ +assertEquals($expectedResult, $result); + } + + public function testSetAutoSizeMethod() + { + $autosizeMethodValues = array( + PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT, + PHPExcel_Shared_Font::AUTOSIZE_METHOD_APPROX, + ); + + foreach($autosizeMethodValues as $autosizeMethodValue) { + $result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'),$autosizeMethodValue); + $this->assertTrue($result); + } + } + + public function testSetAutoSizeMethodWithInvalidValue() + { + $unsupportedAutosizeMethod = 'guess'; + + $result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'),$unsupportedAutosizeMethod); + $this->assertFalse($result); + } + + /** + * @dataProvider providerFontSizeToPixels + */ + public function testFontSizeToPixels() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Font','fontSizeToPixels'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerFontSizeToPixels() + { + return new testDataFileIterator('rawTestData/Shared/FontSizeToPixels.data'); + } + + /** + * @dataProvider providerInchSizeToPixels + */ + public function testInchSizeToPixels() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Font','inchSizeToPixels'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerInchSizeToPixels() + { + return new testDataFileIterator('rawTestData/Shared/InchSizeToPixels.data'); + } + + /** + * @dataProvider providerCentimeterSizeToPixels + */ + public function testCentimeterSizeToPixels() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Font','centimeterSizeToPixels'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerCentimeterSizeToPixels() + { + return new testDataFileIterator('rawTestData/Shared/CentimeterSizeToPixels.data'); + } + +} diff --git a/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php b/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php new file mode 100644 index 00000000..24a26178 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php @@ -0,0 +1,33 @@ +assertEquals($expectedResult, $result); + } + + public function providerHashPassword() + { + return new testDataFileIterator('rawTestData/Shared/PasswordHashes.data'); + } + +} diff --git a/unitTests/Classes/PHPExcel/Style/ColorTest.php b/unitTests/Classes/PHPExcel/Style/ColorTest.php new file mode 100644 index 00000000..f157b1a3 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Style/ColorTest.php @@ -0,0 +1,81 @@ +assertEquals($expectedResult, $result); + } + + public function providerColorGetRed() + { + return new testDataFileIterator('rawTestData/Style/ColorGetRed.data'); + } + + /** + * @dataProvider providerColorGetGreen + */ + public function testGetGreen() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Style_Color','getGreen'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerColorGetGreen() + { + return new testDataFileIterator('rawTestData/Style/ColorGetGreen.data'); + } + + /** + * @dataProvider providerColorGetBlue + */ + public function testGetBlue() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Style_Color','getBlue'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerColorGetBlue() + { + return new testDataFileIterator('rawTestData/Style/ColorGetBlue.data'); + } + + /** + * @dataProvider providerColorChangeBrightness + */ + public function testChangeBrightness() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Style_Color','changeBrightness'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerColorChangeBrightness() + { + return new testDataFileIterator('rawTestData/Style/ColorChangeBrightness.data'); + } + +} diff --git a/unitTests/rawTestData/Shared/CentimeterSizeToPixels.data b/unitTests/rawTestData/Shared/CentimeterSizeToPixels.data new file mode 100644 index 00000000..fc48f21a --- /dev/null +++ b/unitTests/rawTestData/Shared/CentimeterSizeToPixels.data @@ -0,0 +1,5 @@ +0.1, 3.7795275591 +0.2, 7.5590551182 +0.5, 18.8976377955 +1.0, 37.795275591 +2.0, 75.590551182 diff --git a/unitTests/rawTestData/Shared/FontSizeToPixels.data b/unitTests/rawTestData/Shared/FontSizeToPixels.data new file mode 100644 index 00000000..af89196d --- /dev/null +++ b/unitTests/rawTestData/Shared/FontSizeToPixels.data @@ -0,0 +1,16 @@ +6, 8 +7, 9 +8, 10 +9, 12 +10, 13 +11, 14 +12, 16 +14, 18 +16, 21 +18, 24 +20, 26 +22, 29 +24, 32 +36, 48 +48, 64 +60, 80 diff --git a/unitTests/rawTestData/Shared/InchSizeToPixels.data b/unitTests/rawTestData/Shared/InchSizeToPixels.data new file mode 100644 index 00000000..147eaa98 --- /dev/null +++ b/unitTests/rawTestData/Shared/InchSizeToPixels.data @@ -0,0 +1,5 @@ +0.1, 9.6 +0.2, 19.2 +0.5, 48.0 +1.0, 96.0 +2.0, 192.0 diff --git a/unitTests/rawTestData/Shared/PasswordHashes.data b/unitTests/rawTestData/Shared/PasswordHashes.data new file mode 100644 index 00000000..8ceffa45 --- /dev/null +++ b/unitTests/rawTestData/Shared/PasswordHashes.data @@ -0,0 +1,9 @@ +"PHPExcel", "8053" +"Mark Baker", "877D" +"I<3Am3l1a/*", "E3C8" +"μυστικό κωδικό πρόσβασης", "FFFF26DD" +"গোপন পাসওয়ার্ড", "E858" +"Секретный пароль", "EA5F" +"秘密口令", "C07E" +"leyndarmál lykilorð", "99E8" +"", "CE4B" diff --git a/unitTests/rawTestData/Style/ColorChangeBrightness.data b/unitTests/rawTestData/Style/ColorChangeBrightness.data new file mode 100644 index 00000000..de5eeaf5 --- /dev/null +++ b/unitTests/rawTestData/Style/ColorChangeBrightness.data @@ -0,0 +1,14 @@ +"FFAABBCC", 0.1, "FFB2C1D1" // RGBA +"FFAABBCC", -0.1, "FF99A8B7" // RGBA +"AABBCC", 0.1, "B2C1D1" // RGB +"AABBCC", -0.1, "99A8B7" // RGB +"FF0000", 0.1, "FF1919" +"FF0000", -0.1, "E50000" +"FF8080", 0.1, "FF8C8C" +"FF8080", -0.1, "E57373" +"FF0000", 0.15, "FF2626" +"FF0000", -0.15, "D80000" +"FF8080", 0.15, "FF9393" +"FF8080", -0.15, "D86C6C" +"FFF008", 0.5, "FFF783" +"FFF008", -0.5, "7F7804" diff --git a/unitTests/rawTestData/Style/ColorGetBlue.data b/unitTests/rawTestData/Style/ColorGetBlue.data new file mode 100644 index 00000000..4e01d1c7 --- /dev/null +++ b/unitTests/rawTestData/Style/ColorGetBlue.data @@ -0,0 +1,6 @@ +"FFAABBCC", "CC" // RGBA (hex) +"FFAABBCC", FALSE, 204 // RGBA (decimal) +"AABBCC", "CC" // RGB (hex) +"AABBCC", FALSE, 204 // RGB (decimal) +"FFFF00", "00" +"FFFF00", FALSE, 0 diff --git a/unitTests/rawTestData/Style/ColorGetGreen.data b/unitTests/rawTestData/Style/ColorGetGreen.data new file mode 100644 index 00000000..0ace6103 --- /dev/null +++ b/unitTests/rawTestData/Style/ColorGetGreen.data @@ -0,0 +1,6 @@ +"FFAABBCC", "BB" // RGBA (hex) +"FFAABBCC", FALSE, 187 // RGBA (decimal) +"AABBCC", "BB" // RGB (hex) +"AABBCC", FALSE, 187 // RGB (decimal) +"FF00FF", "00" +"FF00FF", FALSE, 0 diff --git a/unitTests/rawTestData/Style/ColorGetRed.data b/unitTests/rawTestData/Style/ColorGetRed.data new file mode 100644 index 00000000..1692a6ad --- /dev/null +++ b/unitTests/rawTestData/Style/ColorGetRed.data @@ -0,0 +1,6 @@ +"FFAABBCC", "AA" // RGBA (hex) +"FFAABBCC", FALSE, 170 // RGBA (decimal) +"AABBCC", "AA" // RGB (hex) +"AABBCC", FALSE, 170 // RGB (decimal) +"00FFFF", "00" +"00FFFF", FALSE, 0 From b8150a1b9c006813a752a45bfe6b8e8a99ef5e55 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 3 Aug 2012 22:26:48 +0100 Subject: [PATCH 23/30] Chris Garaffa's corrections to documentation --- .../PHPExcel developer documentation.doc | Bin 803840 -> 807424 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Documentation/PHPExcel developer documentation.doc b/Documentation/PHPExcel developer documentation.doc index 8efe0a356fdefbab37c5edbfd44b529cc32aa265..c89a6aa20166adb1a024b2e5d450120be56a5f33 100644 GIT binary patch delta 66495 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%0AtmgYO4a+E)e4LrMr}_Xs5Mj@Fi7bQDZEi= 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 delta 64260 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 Date: Sat, 4 Aug 2012 16:08:28 +0100 Subject: [PATCH 24/30] Bugfix: Work item 18377 - Chart Title compatibility on Excel 2007 --- Classes/PHPExcel/Writer/Excel2007/Chart.php | 4 ++-- Classes/PHPExcel/Writer/Excel2007/StringTable.php | 2 +- changelog.txt | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 7316d8dc..4b0376cb 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -444,7 +444,7 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa if (is_array($caption)) $caption = $caption[0]; $objWriter->startElement('a:t'); - $objWriter->writeAttribute('xml:space', 'preserve'); +// $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $caption )); $objWriter->endElement(); @@ -570,7 +570,7 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa if (is_array($caption)) $caption = $caption[0]; $objWriter->startElement('a:t'); - $objWriter->writeAttribute('xml:space', 'preserve'); +// $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $caption )); $objWriter->endElement(); diff --git a/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Classes/PHPExcel/Writer/Excel2007/StringTable.php index 5399ef94..ee77be4f 100644 --- a/Classes/PHPExcel/Writer/Excel2007/StringTable.php +++ b/Classes/PHPExcel/Writer/Excel2007/StringTable.php @@ -286,7 +286,7 @@ class PHPExcel_Writer_Excel2007_StringTable extends PHPExcel_Writer_Excel2007_Wr // t $objWriter->startElement($prefix.'t'); - $objWriter->writeAttribute('xml:space', 'preserve'); +// $objWriter->writeAttribute('xml:space', 'preserve'); // Excel2010 accepts, Excel2007 complains $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); $objWriter->endElement(); diff --git a/changelog.txt b/changelog.txt index 6d0c51bc..46765c03 100644 --- a/changelog.txt +++ b/changelog.txt @@ -93,6 +93,7 @@ Fixed in develop branch: - Bugfix: (MBaker) Work item 18370 - Error loading xlsx file with column breaks - Bugfix: (MBaker) OOCalc Reader now handles percentage and currency data types - Bugfix: (MBaker) OOCalc Reader modified to process number-rows-repeated +- Bugfix: (MBaker) Work item 18377 - Chart Title compatibility on Excel 2007 2012-05-19 (v1.7.7): From 4edc6863699d50638b7b231205482b675985f876 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 4 Aug 2012 17:34:10 +0100 Subject: [PATCH 25/30] Added README file --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..abfaaed2 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# PHPExcel - OpenXML - Read, Write and Create spreadsheet documents in PHP - Spreadsheet engine +PHPExcel is a library written in pure PHP and providing a set of classes that allow you to write to and read from different spreadsheet file formats, like Excel (BIFF) .xls, Excel 2007 (OfficeOpenXML) .xlsx, CSV, Libre/OpenOffice Calc .ods, Gnumeric, PDF, HTML, ... This project is built around Microsoft's OpenXML standard and PHP. + + +## File Formats supported + +### Reading + * BIFF 5-8 (.xls) Excel 95 and above + * Office Open XML (.xlsx) Excel 2007 and above + * SpreadsheetML (.xml) Excel 2003 + * Open Document Format/OASIS (.ods) + * Gnumeric + * HTML + * SYLK + * CSV + +### Writing + * BIFF 8 (.xls) Excel 95 and above + * Office Open XML (.xlsx) Excel 2007 and above + * HTML + * CSV + * PDF (using either the tcPDF, DomPDF or mPDF libraries, which need to be installed separately) + + +## Requirements + * PHP version 5.2.0 or higher + * PHP extension php_zip enabled (required if you need PHPExcel to handle .xlsx .ods or .gnumeric files) + * PHP extension php_xml enabled + * PHP extension php_gd2 enabled (optional, but required for exact column width autocalculation) + + +## Want to contribute? +Fork us! + +## License +PHPExcel is licensed under [LGPL (GNU LESSER GENERAL PUBLIC LICENSE)](https://github.com/PHPOffice/PHPExcel/blob/master/license.txt) \ No newline at end of file From 8ba160ed28d51d6d1bf4690416a6c7297aa076b6 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 5 Aug 2012 18:54:20 +0100 Subject: [PATCH 26/30] Modify Test examples to echo nicely from both CLI and in a web browser --- Classes/PHPExcel/Reader/HTML.php | 6 +- Tests/01simple-download-pdf.php | 8 +- Tests/01simple-download-xls.php | 6 +- Tests/01simple-download-xlsx.php | 6 +- Tests/01simple.php | 26 +++--- Tests/02types-xls.php | 96 +++++++++++----------- Tests/02types.php | 96 +++++++++++----------- Tests/03formulas.php | 39 +++++---- Tests/04printing.php | 32 +++++--- Tests/05featuredemo.php | 18 +++- Tests/06largescale-xls.php | 27 +++--- Tests/06largescale.php | 27 +++--- Tests/07reader.php | 17 ++-- Tests/08conditionalformatting.php | 83 ++++++++++--------- Tests/09pagebreaks.php | 24 ++++-- Tests/10autofilter.php | 18 ++-- Tests/11documentsecurity-xls.php | 25 +++--- Tests/11documentsecurity.php | 25 +++--- Tests/18extendedcalculation.php | 132 +----------------------------- install.txt | 2 +- unitTests/bootstrap.php | 2 +- 21 files changed, 339 insertions(+), 376 deletions(-) diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index dafc7c5f..5299481d 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2011 PHPExcel + * Copyright (c) 2006 - 2012 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ if (!defined('PHPEXCEL_ROOT')) { * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_HTML implements PHPExcel_Reader_IReader { diff --git a/Tests/01simple-download-pdf.php b/Tests/01simple-download-pdf.php index dccbcd04..5fe4a847 100644 --- a/Tests/01simple-download-pdf.php +++ b/Tests/01simple-download-pdf.php @@ -27,9 +27,13 @@ /** Error reporting */ error_reporting(E_ALL); - +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); date_default_timezone_set('Europe/London'); +if (PHP_SAPI == 'cli') + die('This example should only be run from a Web Browser'); + /** Include PHPExcel */ require_once '../Classes/PHPExcel.php'; @@ -84,7 +88,7 @@ if (!PHPExcel_Settings::setPdfRenderer( )) { die( 'NOTICE: Please set the $rendererName and $rendererLibraryPath values' . - PHP_EOL . + '
' . 'at the top of this script as appropriate for your directory structure' ); } diff --git a/Tests/01simple-download-xls.php b/Tests/01simple-download-xls.php index f6b60648..c1d670dc 100644 --- a/Tests/01simple-download-xls.php +++ b/Tests/01simple-download-xls.php @@ -27,9 +27,13 @@ /** Error reporting */ error_reporting(E_ALL); - +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); date_default_timezone_set('Europe/London'); +if (PHP_SAPI == 'cli') + die('This example should only be run from a Web Browser'); + /** Include PHPExcel */ require_once '../Classes/PHPExcel.php'; diff --git a/Tests/01simple-download-xlsx.php b/Tests/01simple-download-xlsx.php index 5accf27f..fd98a9fb 100644 --- a/Tests/01simple-download-xlsx.php +++ b/Tests/01simple-download-xlsx.php @@ -27,9 +27,13 @@ /** Error reporting */ error_reporting(E_ALL); - +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); date_default_timezone_set('Europe/London'); +if (PHP_SAPI == 'cli') + die('This example should only be run from a Web Browser'); + /** Include PHPExcel */ require_once '../Classes/PHPExcel.php'; diff --git a/Tests/01simple.php b/Tests/01simple.php index c89352dc..eff79bdb 100644 --- a/Tests/01simple.php +++ b/Tests/01simple.php @@ -27,19 +27,22 @@ /** Error reporting */ error_reporting(E_ALL); - +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); date_default_timezone_set('Europe/London'); +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); + /** Include PHPExcel */ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("PHPExcel Test Document") @@ -50,7 +53,7 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Add some data -echo date('H:i:s') , " Add some data" , PHP_EOL; +echo date('H:i:s') , " Add some data" , EOL; $objPHPExcel->setActiveSheetIndex(0) ->setCellValue('A1', 'Hello') ->setCellValue('B2', 'world!') @@ -63,7 +66,7 @@ $objPHPExcel->setActiveSheetIndex(0) ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç'); // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Simple'); @@ -72,19 +75,20 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Save Excel5 file -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Tests/02types-xls.php b/Tests/02types-xls.php index b5249988..ba84d6a2 100644 --- a/Tests/02types-xls.php +++ b/Tests/02types-xls.php @@ -27,19 +27,22 @@ /** Error reporting */ error_reporting(E_ALL); - +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); date_default_timezone_set('Europe/London'); +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); + /** Include PHPExcel */ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -49,65 +52,65 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setCategory("Test result file"); // Set default font -echo date('H:i:s') , " Set default font" , PHP_EOL; -$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial'); -$objPHPExcel->getDefaultStyle()->getFont()->setSize(10); +echo date('H:i:s') , " Set default font" , EOL; +$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial') + ->setSize(10); // Add some data, resembling some different data types -echo date('H:i:s') , " Add some data" , PHP_EOL; -$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String'); -$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Simple'); -$objPHPExcel->getActiveSheet()->setCellValue('C1', 'PHPExcel'); +echo date('H:i:s') , " Add some data" , EOL; +$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String') + ->setCellValue('B1', 'Simple') + ->setCellValue('C1', 'PHPExcel'); -$objPHPExcel->getActiveSheet()->setCellValue('A2', 'String'); -$objPHPExcel->getActiveSheet()->setCellValue('B2', 'Symbols'); -$objPHPExcel->getActiveSheet()->setCellValue('C2', '!+&=()~§±æþ'); +$objPHPExcel->getActiveSheet()->setCellValue('A2', 'String') + ->setCellValue('B2', 'Symbols') + ->setCellValue('C2', '!+&=()~§±æþ'); -$objPHPExcel->getActiveSheet()->setCellValue('A3', 'String'); -$objPHPExcel->getActiveSheet()->setCellValue('B3', 'UTF-8'); -$objPHPExcel->getActiveSheet()->setCellValue('C3', 'Создать MS Excel Книги из PHP скриптов'); +$objPHPExcel->getActiveSheet()->setCellValue('A3', 'String') + ->setCellValue('B3', 'UTF-8') + ->setCellValue('C3', 'Создать MS Excel Книги из PHP скриптов'); -$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Number'); -$objPHPExcel->getActiveSheet()->setCellValue('B4', 'Integer'); -$objPHPExcel->getActiveSheet()->setCellValue('C4', 12); +$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Number') + ->setCellValue('B4', 'Integer') + ->setCellValue('C4', 12); -$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Number'); -$objPHPExcel->getActiveSheet()->setCellValue('B5', 'Float'); -$objPHPExcel->getActiveSheet()->setCellValue('C5', 34.56); +$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Number') + ->setCellValue('B5', 'Float') + ->setCellValue('C5', 34.56); -$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Number'); -$objPHPExcel->getActiveSheet()->setCellValue('B6', 'Negative'); -$objPHPExcel->getActiveSheet()->setCellValue('C6', -7.89); +$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Number') + ->setCellValue('B6', 'Negative') + ->setCellValue('C6', -7.89); -$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Boolean'); -$objPHPExcel->getActiveSheet()->setCellValue('B7', 'True'); -$objPHPExcel->getActiveSheet()->setCellValue('C7', true); +$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Boolean') + ->setCellValue('B7', 'True') + ->setCellValue('C7', true); -$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Boolean'); -$objPHPExcel->getActiveSheet()->setCellValue('B8', 'False'); -$objPHPExcel->getActiveSheet()->setCellValue('C8', false); +$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Boolean') + ->setCellValue('B8', 'False') + ->setCellValue('C8', false); $dateTimeNow = time(); -$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Date/Time'); -$objPHPExcel->getActiveSheet()->setCellValue('B9', 'Date'); -$objPHPExcel->getActiveSheet()->setCellValue('C9', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); +$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Date/Time') + ->setCellValue('B9', 'Date') + ->setCellValue('C9', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); $objPHPExcel->getActiveSheet()->getStyle('C9')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2); -$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Date/Time'); -$objPHPExcel->getActiveSheet()->setCellValue('B10', 'Time'); -$objPHPExcel->getActiveSheet()->setCellValue('C10', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); +$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Date/Time') + ->setCellValue('B10', 'Time') + ->setCellValue('C10', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); $objPHPExcel->getActiveSheet()->getStyle('C10')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4); -$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Date/Time'); -$objPHPExcel->getActiveSheet()->setCellValue('B11', 'Date and Time'); -$objPHPExcel->getActiveSheet()->setCellValue('C11', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); +$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Date/Time') + ->setCellValue('B11', 'Date and Time') + ->setCellValue('C11', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); $objPHPExcel->getActiveSheet()->getStyle('C11')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME); $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true); // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Datatypes'); @@ -116,20 +119,21 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; -echo date('H:i:s') , " Reload workbook from saved file" , PHP_EOL; +echo date('H:i:s') , " Reload workbook from saved file" , EOL; $objPHPExcel = PHPExcel_IOFactory::load(str_replace('.php', '.xls', __FILE__)); var_dump($objPHPExcel->getActiveSheet()->toArray()); // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/02types.php b/Tests/02types.php index a6a31364..fcfd6778 100644 --- a/Tests/02types.php +++ b/Tests/02types.php @@ -27,19 +27,22 @@ /** Error reporting */ error_reporting(E_ALL); - +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); date_default_timezone_set('Europe/London'); +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); + /** Include PHPExcel */ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -49,65 +52,65 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setCategory("Test result file"); // Set default font -echo date('H:i:s') , " Set default font" , PHP_EOL; -$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial'); -$objPHPExcel->getDefaultStyle()->getFont()->setSize(10); +echo date('H:i:s') , " Set default font" , EOL; +$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial') + ->setSize(10); // Add some data, resembling some different data types -echo date('H:i:s') , " Add some data" , PHP_EOL; -$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String'); -$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Simple'); -$objPHPExcel->getActiveSheet()->setCellValue('C1', 'PHPExcel'); +echo date('H:i:s') , " Add some data" , EOL; +$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String') + ->setCellValue('B1', 'Simple') + ->setCellValue('C1', 'PHPExcel'); -$objPHPExcel->getActiveSheet()->setCellValue('A2', 'String'); -$objPHPExcel->getActiveSheet()->setCellValue('B2', 'Symbols'); -$objPHPExcel->getActiveSheet()->setCellValue('C2', '!+&=()~§±æþ'); +$objPHPExcel->getActiveSheet()->setCellValue('A2', 'String') + ->setCellValue('B2', 'Symbols') + ->setCellValue('C2', '!+&=()~§±æþ'); -$objPHPExcel->getActiveSheet()->setCellValue('A3', 'String'); -$objPHPExcel->getActiveSheet()->setCellValue('B3', 'UTF-8'); -$objPHPExcel->getActiveSheet()->setCellValue('C3', 'Создать MS Excel Книги из PHP скриптов'); +$objPHPExcel->getActiveSheet()->setCellValue('A3', 'String') + ->setCellValue('B3', 'UTF-8') + ->setCellValue('C3', 'Создать MS Excel Книги из PHP скриптов'); -$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Number'); -$objPHPExcel->getActiveSheet()->setCellValue('B4', 'Integer'); -$objPHPExcel->getActiveSheet()->setCellValue('C4', 12); +$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Number') + ->setCellValue('B4', 'Integer') + ->setCellValue('C4', 12); -$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Number'); -$objPHPExcel->getActiveSheet()->setCellValue('B5', 'Float'); -$objPHPExcel->getActiveSheet()->setCellValue('C5', 34.56); +$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Number') + ->setCellValue('B5', 'Float') + ->setCellValue('C5', 34.56); -$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Number'); -$objPHPExcel->getActiveSheet()->setCellValue('B6', 'Negative'); -$objPHPExcel->getActiveSheet()->setCellValue('C6', -7.89); +$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Number') + ->setCellValue('B6', 'Negative') + ->setCellValue('C6', -7.89); -$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Boolean'); -$objPHPExcel->getActiveSheet()->setCellValue('B7', 'True'); -$objPHPExcel->getActiveSheet()->setCellValue('C7', true); +$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Boolean') + ->setCellValue('B7', 'True') + ->setCellValue('C7', true); -$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Boolean'); -$objPHPExcel->getActiveSheet()->setCellValue('B8', 'False'); -$objPHPExcel->getActiveSheet()->setCellValue('C8', false); +$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Boolean') + ->setCellValue('B8', 'False') + ->setCellValue('C8', false); $dateTimeNow = time(); -$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Date/Time'); -$objPHPExcel->getActiveSheet()->setCellValue('B9', 'Date'); -$objPHPExcel->getActiveSheet()->setCellValue('C9', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); +$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Date/Time') + ->setCellValue('B9', 'Date') + ->setCellValue('C9', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); $objPHPExcel->getActiveSheet()->getStyle('C9')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2); -$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Date/Time'); -$objPHPExcel->getActiveSheet()->setCellValue('B10', 'Time'); -$objPHPExcel->getActiveSheet()->setCellValue('C10', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); +$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Date/Time') + ->setCellValue('B10', 'Time') + ->setCellValue('C10', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); $objPHPExcel->getActiveSheet()->getStyle('C10')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4); -$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Date/Time'); -$objPHPExcel->getActiveSheet()->setCellValue('B11', 'Date and Time'); -$objPHPExcel->getActiveSheet()->setCellValue('C11', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); +$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Date/Time') + ->setCellValue('B11', 'Date and Time') + ->setCellValue('C11', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow )); $objPHPExcel->getActiveSheet()->getStyle('C11')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME); $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true); // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Datatypes'); @@ -116,20 +119,21 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; -echo date('H:i:s') , " Reload workbook from saved file" , PHP_EOL; +echo date('H:i:s') , " Reload workbook from saved file" , EOL; $objPHPExcel = PHPExcel_IOFactory::load(str_replace('.php', '.xlsx', __FILE__)); var_dump($objPHPExcel->getActiveSheet()->toArray()); // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/03formulas.php b/Tests/03formulas.php index 97260845..64712c85 100644 --- a/Tests/03formulas.php +++ b/Tests/03formulas.php @@ -27,19 +27,22 @@ /** Error reporting */ error_reporting(E_ALL); - +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); date_default_timezone_set('Europe/London'); +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); + /** Include PHPExcel */ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -50,7 +53,7 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Add some data, we will use some formulas here -echo date('H:i:s') , " Add some data" , PHP_EOL; +echo date('H:i:s') , " Add some data" , EOL; $objPHPExcel->getActiveSheet()->setCellValue('A5', 'Sum:'); $objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range #1') @@ -59,7 +62,7 @@ $objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range #1') ->setCellValue('B4', 13) ->setCellValue('B5', '=SUM(B2:B4)'); echo date('H:i:s') , " Sum of Range #1 is " , - $objPHPExcel->getActiveSheet()->getCell('B5')->getCalculatedValue() , PHP_EOL; + $objPHPExcel->getActiveSheet()->getCell('B5')->getCalculatedValue() , EOL; $objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range #2') ->setCellValue('C2', 5) @@ -67,31 +70,31 @@ $objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range #2') ->setCellValue('C4', 17) ->setCellValue('C5', '=SUM(C2:C4)'); echo date('H:i:s') , " Sum of Range #2 is " , - $objPHPExcel->getActiveSheet()->getCell('C5')->getCalculatedValue() , PHP_EOL; + $objPHPExcel->getActiveSheet()->getCell('C5')->getCalculatedValue() , EOL; $objPHPExcel->getActiveSheet()->setCellValue('A7', 'Total of both ranges:'); $objPHPExcel->getActiveSheet()->setCellValue('B7', '=SUM(B5:C5)'); echo date('H:i:s') , " Sum of both Ranges is " , - $objPHPExcel->getActiveSheet()->getCell('B7')->getCalculatedValue() , PHP_EOL; + $objPHPExcel->getActiveSheet()->getCell('B7')->getCalculatedValue() , EOL; $objPHPExcel->getActiveSheet()->setCellValue('A8', 'Minimum of both ranges:'); $objPHPExcel->getActiveSheet()->setCellValue('B8', '=MIN(B2:C4)'); echo date('H:i:s') , " Minimum value in either Range is " , - $objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue() , PHP_EOL; + $objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue() , EOL; $objPHPExcel->getActiveSheet()->setCellValue('A9', 'Maximum of both ranges:'); $objPHPExcel->getActiveSheet()->setCellValue('B9', '=MAX(B2:C4)'); echo date('H:i:s') , " Maximum value in either Range is " , - $objPHPExcel->getActiveSheet()->getCell('B9')->getCalculatedValue() , PHP_EOL; + $objPHPExcel->getActiveSheet()->getCell('B9')->getCalculatedValue() , EOL; $objPHPExcel->getActiveSheet()->setCellValue('A10', 'Average of both ranges:'); $objPHPExcel->getActiveSheet()->setCellValue('B10', '=AVERAGE(B2:C4)'); echo date('H:i:s') , " Average value of both Ranges is " , - $objPHPExcel->getActiveSheet()->getCell('B10')->getCalculatedValue() , PHP_EOL; + $objPHPExcel->getActiveSheet()->getCell('B10')->getCalculatedValue() , EOL; // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Formulas'); @@ -100,14 +103,20 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +// Save Excel5 file +echo date('H:i:s') , " Write to Excel5 format" , EOL; +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); +$objWriter->save(str_replace('.php', '.xls', __FILE__)); +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Tests/04printing.php b/Tests/04printing.php index 4375d053..2e8c0f0f 100644 --- a/Tests/04printing.php +++ b/Tests/04printing.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,11 +39,11 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -50,19 +54,19 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Add some data, we will use printing features -echo date('H:i:s') , " Add some data" , PHP_EOL; +echo date('H:i:s') , " Add some data" , EOL; for ($i = 1; $i < 200; $i++) { $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, $i); $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, 'Test value'); } // Set header and footer. When no different headers for odd/even are used, odd header is assumed. -echo date('H:i:s') , " Set header/footer" , PHP_EOL; +echo date('H:i:s') , " Set header/footer" , EOL; $objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader('&L&G&C&HPlease treat this document as confidential!'); $objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N'); // Add a drawing to the header -echo date('H:i:s') , " Add a drawing to the header" , PHP_EOL; +echo date('H:i:s') , " Add a drawing to the header" , EOL; $objDrawing = new PHPExcel_Worksheet_HeaderFooterDrawing(); $objDrawing->setName('PHPExcel logo'); $objDrawing->setPath('./images/phpexcel_logo.gif'); @@ -70,12 +74,12 @@ $objDrawing->setHeight(36); $objPHPExcel->getActiveSheet()->getHeaderFooter()->addImage($objDrawing, PHPExcel_Worksheet_HeaderFooter::IMAGE_HEADER_LEFT); // Set page orientation and size -echo date('H:i:s') , " Set page orientation and size" , PHP_EOL; +echo date('H:i:s') , " Set page orientation and size" , EOL; $objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); $objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4); // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Printing'); @@ -84,14 +88,20 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +// Save Excel5 file +echo date('H:i:s') , " Write to Excel5 format" , EOL; +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); +$objWriter->save(str_replace('.php', '.xls', __FILE__)); +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Tests/05featuredemo.php b/Tests/05featuredemo.php index 99759c9d..69f16c97 100644 --- a/Tests/05featuredemo.php +++ b/Tests/05featuredemo.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -37,13 +41,19 @@ require_once '../Classes/PHPExcel/IOFactory.php'; // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +// Save Excel5 file +echo date('H:i:s') , " Write to Excel5 format" , EOL; +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); +$objWriter->save(str_replace('.php', '.xls', __FILE__)); +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Tests/06largescale-xls.php b/Tests/06largescale-xls.php index 366fbc73..551fab45 100644 --- a/Tests/06largescale-xls.php +++ b/Tests/06largescale-xls.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -49,11 +53,11 @@ for writing to Excel2007: */ // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set properties" , PHP_EOL; +echo date('H:i:s') , " Set properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -64,7 +68,7 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Create a first sheet -echo date('H:i:s') , " Add data" , PHP_EOL; +echo date('H:i:s') , " Add data" , EOL; $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname"); $objPHPExcel->getActiveSheet()->setCellValue('B1', "Lastname"); @@ -74,24 +78,24 @@ $objPHPExcel->getActiveSheet()->setCellValue('E1', "Is Client ?"); // Hide "Phone" and "fax" column -echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , PHP_EOL; +echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , EOL; $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false); $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false); // Set outline levels -echo date('H:i:s') , " Set outline levels" , PHP_EOL; +echo date('H:i:s') , " Set outline levels" , EOL; $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1) ->setVisible(false) ->setCollapsed(true); // Freeze panes -echo date('H:i:s') , " Freeze panes" , PHP_EOL; +echo date('H:i:s') , " Freeze panes" , EOL; $objPHPExcel->getActiveSheet()->freezePane('A2'); // Rows to repeat at top -echo date('H:i:s') , " Rows to repeat at top" , PHP_EOL; +echo date('H:i:s') , " Rows to repeat at top" , EOL; $objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1); @@ -110,14 +114,15 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 5 file -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/06largescale.php b/Tests/06largescale.php index 20eb409e..0a6377f5 100644 --- a/Tests/06largescale.php +++ b/Tests/06largescale.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -49,11 +53,11 @@ for writing to Excel2007: */ // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set properties" , PHP_EOL; +echo date('H:i:s') , " Set properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -64,7 +68,7 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Create a first sheet -echo date('H:i:s') , " Add data" , PHP_EOL; +echo date('H:i:s') , " Add data" , EOL; $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname"); $objPHPExcel->getActiveSheet()->setCellValue('B1', "Lastname"); @@ -74,24 +78,24 @@ $objPHPExcel->getActiveSheet()->setCellValue('E1', "Is Client ?"); // Hide "Phone" and "fax" column -echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , PHP_EOL; +echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , EOL; $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false); $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false); // Set outline levels -echo date('H:i:s') , " Set outline levels" , PHP_EOL; +echo date('H:i:s') , " Set outline levels" , EOL; $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1) ->setVisible(false) ->setCollapsed(true); // Freeze panes -echo date('H:i:s') , " Freeze panes" , PHP_EOL; +echo date('H:i:s') , " Freeze panes" , EOL; $objPHPExcel->getActiveSheet()->freezePane('A2'); // Rows to repeat at top -echo date('H:i:s') , " Rows to repeat at top" , PHP_EOL; +echo date('H:i:s') , " Rows to repeat at top" , EOL; $objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1); @@ -110,14 +114,15 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/07reader.php b/Tests/07reader.php index 5b14b944..649382f5 100644 --- a/Tests/07reader.php +++ b/Tests/07reader.php @@ -26,6 +26,10 @@ */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -34,20 +38,21 @@ require_once '../Classes/PHPExcel/IOFactory.php'; if (!file_exists("05featuredemo.xlsx")) { - exit("Please run 05featuredemo.php first." . PHP_EOL); + exit("Please run 05featuredemo.php first." . EOL); } -echo date('H:i:s') , " Load from Excel2007 file" , PHP_EOL; +echo date('H:i:s') , " Load from Excel2007 file" , EOL; $objPHPExcel = PHPExcel_IOFactory::load("05featuredemo.xlsx"); -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing files" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/08conditionalformatting.php b/Tests/08conditionalformatting.php index 274c53f6..36f4ec8f 100644 --- a/Tests/08conditionalformatting.php +++ b/Tests/08conditionalformatting.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,11 +39,11 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -50,59 +54,59 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Create a first sheet, representing sales data -echo date('H:i:s') , " Add some data" , PHP_EOL; +echo date('H:i:s') , " Add some data" , EOL; $objPHPExcel->setActiveSheetIndex(0); -$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Description'); -$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Amount'); +$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Description') + ->setCellValue('B1', 'Amount'); -$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Paycheck received'); -$objPHPExcel->getActiveSheet()->setCellValue('B2', 100); +$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Paycheck received') + ->setCellValue('B2', 100); -$objPHPExcel->getActiveSheet()->setCellValue('A3', 'Cup of coffee bought'); -$objPHPExcel->getActiveSheet()->setCellValue('B3', -1.5); +$objPHPExcel->getActiveSheet()->setCellValue('A3', 'Cup of coffee bought') + ->setCellValue('B3', -1.5); -$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Cup of coffee bought'); -$objPHPExcel->getActiveSheet()->setCellValue('B4', -1.5); +$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Cup of coffee bought') + ->setCellValue('B4', -1.5); -$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Cup of tea bought'); -$objPHPExcel->getActiveSheet()->setCellValue('B5', -1.2); +$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Cup of tea bought') + ->setCellValue('B5', -1.2); -$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Found some money'); -$objPHPExcel->getActiveSheet()->setCellValue('B6', 8); +$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Found some money') + ->setCellValue('B6', 8); -$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Total:'); -$objPHPExcel->getActiveSheet()->setCellValue('B7', '=SUM(B2:B6)'); +$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Total:') + ->setCellValue('B7', '=SUM(B2:B6)'); // Set column widths -echo date('H:i:s') , " Set column widths" , PHP_EOL; +echo date('H:i:s') , " Set column widths" , EOL; $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(30); $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12); // Add conditional formatting -echo date('H:i:s') , " Add conditional formatting" , PHP_EOL; +echo date('H:i:s') , " Add conditional formatting" , EOL; $objConditional1 = new PHPExcel_Style_Conditional(); -$objConditional1->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS); -$objConditional1->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_BETWEEN); -$objConditional1->addCondition('200'); -$objConditional1->addCondition('400'); +$objConditional1->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS) + ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_BETWEEN) + ->addCondition('200') + ->addCondition('400'); $objConditional1->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_YELLOW); $objConditional1->getStyle()->getFont()->setBold(true); $objConditional1->getStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE); $objConditional2 = new PHPExcel_Style_Conditional(); -$objConditional2->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS); -$objConditional2->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_LESSTHAN); -$objConditional2->addCondition('0'); +$objConditional2->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS) + ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_LESSTHAN) + ->addCondition('0'); $objConditional2->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED); $objConditional2->getStyle()->getFont()->setBold(true); $objConditional2->getStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE); $objConditional3 = new PHPExcel_Style_Conditional(); -$objConditional3->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS); -$objConditional3->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL); -$objConditional3->addCondition('0'); +$objConditional3->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS) + ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL) + ->addCondition('0'); $objConditional3->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN); $objConditional3->getStyle()->getFont()->setBold(true); $objConditional3->getStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE); @@ -115,15 +119,15 @@ $objPHPExcel->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditiona // duplicate the conditional styles across a range of cells -echo date('H:i:s') , " Duplicate the conditional formatting across a range of cells" , PHP_EOL; +echo date('H:i:s') , " Duplicate the conditional formatting across a range of cells" , EOL; $objPHPExcel->getActiveSheet()->duplicateConditionalStyle( $objPHPExcel->getActiveSheet()->getStyle('B2')->getConditionalStyles(), 'B3:B7' - ); + ); // Set fonts -echo date('H:i:s') , " Set fonts" , PHP_EOL; +echo date('H:i:s') , " Set fonts" , EOL; $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true); $objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setBold(true); $objPHPExcel->getActiveSheet()->getStyle('A7')->getFont()->setBold(true); @@ -131,19 +135,19 @@ $objPHPExcel->getActiveSheet()->getStyle('B7')->getFont()->setBold(true); // Set header and footer. When no different headers for odd/even are used, odd header is assumed. -echo date('H:i:s') , " Set header/footer" , PHP_EOL; +echo date('H:i:s') , " Set header/footer" , EOL; $objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader('&L&BPersonal cash register&RPrinted on &D'); $objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N'); // Set page orientation and size -echo date('H:i:s') , " Set page orientation and size" , PHP_EOL; +echo date('H:i:s') , " Set page orientation and size" , EOL; $objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); $objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4); // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Invoice'); @@ -152,14 +156,15 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/09pagebreaks.php b/Tests/09pagebreaks.php index 3fb7d7ba..1437ef58 100644 --- a/Tests/09pagebreaks.php +++ b/Tests/09pagebreaks.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,11 +39,11 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -50,7 +54,7 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Create a first sheet -echo date('H:i:s') , " Add data and page breaks" , PHP_EOL; +echo date('H:i:s') , " Add data and page breaks" , EOL; $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname") ->setCellValue('B1', "Lastname") @@ -80,14 +84,20 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +// Save Excel5 file +echo date('H:i:s') , " Write to Excel5 format" , EOL; +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); +$objWriter->save(str_replace('.php', '.xls', __FILE__)); +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Tests/10autofilter.php b/Tests/10autofilter.php index 68cf3bf2..4caf7a25 100644 --- a/Tests/10autofilter.php +++ b/Tests/10autofilter.php @@ -27,19 +27,16 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); /** Include PHPExcel */ require_once '../Classes/PHPExcel.php'; -if(php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR'])) { - define('EOL',PHP_EOL); -} -else { - define('EOL', '
'); -} - // Create new PHPExcel object echo date('H:i:s').' Create new PHPExcel object'.EOL; $objPHPExcel = new PHPExcel(); @@ -139,15 +136,16 @@ $objPHPExcel->setActiveSheetIndex(0); echo date('H:i:s').' Write to Excel2007 format'.EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s').' File written to '.str_replace('.php', '.xlsx', __FILE__).EOL; +echo date('H:i:s').' File written to '.str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)).EOL; // Save Excel5 file echo date('H:i:s').' Write to Excel5 format'.EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s').' File written to '.str_replace('.php', '.xls', __FILE__).EOL; +echo date('H:i:s').' File written to '.str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)).EOL; // Echo memory peak usage echo date('H:i:s').' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB'.EOL; // Echo done -echo date('H:i:s').' Done writing file'.EOL; +echo date('H:i:s').' Done writing files'.EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Tests/11documentsecurity-xls.php b/Tests/11documentsecurity-xls.php index 71a60f0e..26f36a86 100644 --- a/Tests/11documentsecurity-xls.php +++ b/Tests/11documentsecurity-xls.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,11 +39,11 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -50,7 +54,7 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Add some data -echo date('H:i:s') , " Add some data" , PHP_EOL; +echo date('H:i:s') , " Add some data" , EOL; $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getActiveSheet()->setCellValue('A1', 'Hello'); $objPHPExcel->getActiveSheet()->setCellValue('B2', 'world!'); @@ -58,19 +62,19 @@ $objPHPExcel->getActiveSheet()->setCellValue('C1', 'Hello'); $objPHPExcel->getActiveSheet()->setCellValue('D2', 'world!'); // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Simple'); // Set document security -echo date('H:i:s') , " Set document security" , PHP_EOL; +echo date('H:i:s') , " Set document security" , EOL; $objPHPExcel->getSecurity()->setLockWindows(true); $objPHPExcel->getSecurity()->setLockStructure(true); $objPHPExcel->getSecurity()->setWorkbookPassword("PHPExcel"); // Set sheet security -echo date('H:i:s') , " Set sheet security" , PHP_EOL; +echo date('H:i:s') , " Set sheet security" , EOL; $objPHPExcel->getActiveSheet()->getProtection()->setPassword('PHPExcel'); $objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); // This should be enabled in order to enable any of the following! $objPHPExcel->getActiveSheet()->getProtection()->setSort(true); @@ -83,14 +87,15 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/11documentsecurity.php b/Tests/11documentsecurity.php index 6646710c..c6a8ab2c 100644 --- a/Tests/11documentsecurity.php +++ b/Tests/11documentsecurity.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,11 +39,11 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -50,7 +54,7 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Add some data -echo date('H:i:s') , " Add some data" , PHP_EOL; +echo date('H:i:s') , " Add some data" , EOL; $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getActiveSheet()->setCellValue('A1', 'Hello'); $objPHPExcel->getActiveSheet()->setCellValue('B2', 'world!'); @@ -58,19 +62,19 @@ $objPHPExcel->getActiveSheet()->setCellValue('C1', 'Hello'); $objPHPExcel->getActiveSheet()->setCellValue('D2', 'world!'); // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Simple'); // Set document security -echo date('H:i:s') , " Set document security" , PHP_EOL; +echo date('H:i:s') , " Set document security" , EOL; $objPHPExcel->getSecurity()->setLockWindows(true); $objPHPExcel->getSecurity()->setLockStructure(true); $objPHPExcel->getSecurity()->setWorkbookPassword("PHPExcel"); // Set sheet security -echo date('H:i:s') , " Set sheet security" , PHP_EOL; +echo date('H:i:s') , " Set sheet security" , EOL; $objPHPExcel->getActiveSheet()->getProtection()->setPassword('PHPExcel'); $objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); // This should be enabled in order to enable any of the following! $objPHPExcel->getActiveSheet()->getProtection()->setSort(true); @@ -83,14 +87,15 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/18extendedcalculation.php b/Tests/18extendedcalculation.php index fd948607..954e589d 100644 --- a/Tests/18extendedcalculation.php +++ b/Tests/18extendedcalculation.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2011 PHPExcel + * Copyright (C) 2006 - 2012 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -46,28 +46,6 @@ $objPHPExcel = new PHPExcel(); // Add some data, we will use some formulas here echo date('H:i:s') . " Add some data\n"; $objPHPExcel->getActiveSheet()->setCellValue('A14', 'Count:'); -$objPHPExcel->getActiveSheet()->setCellValue('A15', 'Sum:'); -$objPHPExcel->getActiveSheet()->setCellValue('A16', 'Max:'); -$objPHPExcel->getActiveSheet()->setCellValue('A17', 'Min:'); -$objPHPExcel->getActiveSheet()->setCellValue('A18', 'Average:'); -$objPHPExcel->getActiveSheet()->setCellValue('A19', 'Median:'); -$objPHPExcel->getActiveSheet()->setCellValue('A20', 'Mode:'); - -$objPHPExcel->getActiveSheet()->setCellValue('A22', 'CountA:'); -$objPHPExcel->getActiveSheet()->setCellValue('A23', 'MaxA:'); -$objPHPExcel->getActiveSheet()->setCellValue('A24', 'MinA:'); - -$objPHPExcel->getActiveSheet()->setCellValue('A26', 'StDev:'); -$objPHPExcel->getActiveSheet()->setCellValue('A27', 'StDevA:'); -$objPHPExcel->getActiveSheet()->setCellValue('A28', 'StDevP:'); -$objPHPExcel->getActiveSheet()->setCellValue('A29', 'StDevPA:'); - -$objPHPExcel->getActiveSheet()->setCellValue('A31', 'DevSq:'); -$objPHPExcel->getActiveSheet()->setCellValue('A32', 'Var:'); -$objPHPExcel->getActiveSheet()->setCellValue('A33', 'VarA:'); -$objPHPExcel->getActiveSheet()->setCellValue('A34', 'VarP:'); -$objPHPExcel->getActiveSheet()->setCellValue('A35', 'VarPA:'); - $objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range 1'); $objPHPExcel->getActiveSheet()->setCellValue('B2', 2); @@ -82,27 +60,6 @@ $objPHPExcel->getActiveSheet()->setCellValue('B11', 6); $objPHPExcel->getActiveSheet()->setCellValue('B12', 12); $objPHPExcel->getActiveSheet()->setCellValue('B14', '=COUNT(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B15', '=SUM(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B16', '=MAX(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B17', '=MIN(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B18', '=AVERAGE(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B19', '=MEDIAN(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B20', '=MODE(B2:B12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('B22', '=COUNTA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B23', '=MAXA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B24', '=MINA(B2:B12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('B26', '=STDEV(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B27', '=STDEVA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B28', '=STDEVP(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B29', '=STDEVPA(B2:B12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('B31', '=DEVSQ(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B32', '=VAR(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B33', '=VARA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B34', '=VARP(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B35', '=VARPA(B2:B12)'); $objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range 2'); $objPHPExcel->getActiveSheet()->setCellValue('C2', 1); @@ -118,28 +75,6 @@ $objPHPExcel->getActiveSheet()->setCellValue('C11', 4); $objPHPExcel->getActiveSheet()->setCellValue('C12', 4); $objPHPExcel->getActiveSheet()->setCellValue('C14', '=COUNT(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C15', '=SUM(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C16', '=MAX(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C17', '=MIN(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C18', '=AVERAGE(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C19', '=MEDIAN(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C20', '=MODE(C2:C12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('C22', '=COUNTA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C23', '=MAXA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C24', '=MINA(C2:C12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('C26', '=STDEV(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C27', '=STDEVA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C28', '=STDEVP(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C29', '=STDEVPA(C2:C12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('C31', '=DEVSQ(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C32', '=VAR(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C33', '=VARA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C34', '=VARP(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C35', '=VARPA(C2:C12)'); - $objPHPExcel->getActiveSheet()->setCellValue('D1', 'Range 3'); $objPHPExcel->getActiveSheet()->setCellValue('D2', 2); @@ -156,72 +91,9 @@ $objPHPExcel->getActiveSheet()->setCellValue('E4', '=RANDBETWEEN(5, 10)'); $objPHPExcel->getActiveSheet()->setCellValue('E14', 'Count of both ranges:'); $objPHPExcel->getActiveSheet()->setCellValue('F14', '=COUNT(B2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('E15', 'Total of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F15', '=SUM(B2:C12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('E16', 'Maximum of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F16', '=MAX(B2:C12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('E17', 'Minimum of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F17', '=MIN(B2:C12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('E18', 'Average of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F18', '=AVERAGE(B2:C12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('E19', 'Median of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F19', '=MEDIAN(B2:C12)'); - -$objPHPExcel->getActiveSheet()->setCellValue('E20', 'Mode of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F20', '=MODE(B2:C12)'); - - // Calculated data echo date('H:i:s') . " Calculated data\n"; echo 'Value of B14 [=COUNT(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B14')->getCalculatedValue() . "\r\n"; -echo 'Value of B15 [=SUM(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B15')->getCalculatedValue() . "\r\n"; -echo 'Value of B16 [=MAX(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B16')->getCalculatedValue() . "\r\n"; -echo 'Value of B17 [=MIN(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B17')->getCalculatedValue() . "\r\n"; -echo 'Value of B18 [=AVERAGE(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B18')->getCalculatedValue() . "\r\n"; -echo 'Value of B19 [=MEDIAN(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B19')->getCalculatedValue() . "\r\n"; -echo 'Value of B20 [=MODE(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B20')->getCalculatedValue() . "\r\n"; - -echo 'Value of B22 [=COUNTA(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B22')->getCalculatedValue() . "\r\n"; -echo 'Value of B23 [=MAXA(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B23')->getCalculatedValue() . "\r\n"; -echo 'Value of B24 [=MINA(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B24')->getCalculatedValue() . "\r\n"; - -echo 'Value of B26 [=STDEV(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B26')->getCalculatedValue() . "\r\n"; -echo 'Value of B27 [=STDEVA(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B27')->getCalculatedValue() . "\r\n"; -echo 'Value of B28 [=STDEVP(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B28')->getCalculatedValue() . "\r\n"; -echo 'Value of B29 [=STDEVPA(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B29')->getCalculatedValue() . "\r\n"; - -echo 'Value of B31 [=DEVSQ(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B31')->getCalculatedValue() . "\r\n"; -echo 'Value of B32 [=VAR(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B32')->getCalculatedValue() . "\r\n"; -echo 'Value of B33 [=VARA(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B33')->getCalculatedValue() . "\r\n"; -echo 'Value of B34 [=VARP(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B34')->getCalculatedValue() . "\r\n"; -echo 'Value of B35 [=VARPA(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B35')->getCalculatedValue() . "\r\n"; - -echo 'Value of C14 [=COUNT(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C14')->getCalculatedValue() . "\r\n"; -echo 'Value of C15 [=SUM(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C15')->getCalculatedValue() . "\r\n"; -echo 'Value of C16 [=MAX(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C16')->getCalculatedValue() . "\r\n"; -echo 'Value of C17 [=MIN(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C17')->getCalculatedValue() . "\r\n"; -echo 'Value of C18 [=AVERAGE(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C18')->getCalculatedValue() . "\r\n"; -echo 'Value of C19 [=MEDIAN(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C19')->getCalculatedValue() . "\r\n"; -echo 'Value of C20 [=MODE(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C20')->getCalculatedValue() . "\r\n"; - -echo 'Value of C22 [=COUNTA(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C22')->getCalculatedValue() . "\r\n"; -echo 'Value of C23 [=MAXA(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C23')->getCalculatedValue() . "\r\n"; -echo 'Value of C24 [=MINA(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C24')->getCalculatedValue() . "\r\n"; - -echo 'Value of C26 [=STDEV(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C26')->getCalculatedValue() . "\r\n"; -echo 'Value of C27 [=STDEVA(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C27')->getCalculatedValue() . "\r\n"; -echo 'Value of C28 [=STDEVP(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C28')->getCalculatedValue() . "\r\n"; -echo 'Value of C29 [=STDEVPA(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C29')->getCalculatedValue() . "\r\n"; - -echo 'Value of C31 [=DEVSQ(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C31')->getCalculatedValue() . "\r\n"; -echo 'Value of C32 [=VAR(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C32')->getCalculatedValue() . "\r\n"; -echo 'Value of C33 [=VARA(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C33')->getCalculatedValue() . "\r\n"; -echo 'Value of C34 [=VARP(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C34')->getCalculatedValue() . "\r\n"; -echo 'Value of C35 [=VARPA(C2:C12)]: ' . $objPHPExcel->getActiveSheet()->getCell('C35')->getCalculatedValue() . "\r\n"; // Echo memory peak usage diff --git a/install.txt b/install.txt index c19f944b..79cd8152 100644 --- a/install.txt +++ b/install.txt @@ -17,7 +17,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * -* @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +* @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## ************************************************************************************** diff --git a/unitTests/bootstrap.php b/unitTests/bootstrap.php index 61ae205c..a502c17b 100644 --- a/unitTests/bootstrap.php +++ b/unitTests/bootstrap.php @@ -2,7 +2,7 @@ /** * $Id: bootstrap.php 2892 2011-08-14 15:11:50Z markbaker@phpexcel.net $ * - * @copyright Copyright (C) 2011 PHPExcel. All rights reserved. + * @copyright Copyright (C) 2011-2012 PHPExcel. All rights reserved. * @package PHPExcel * @subpackage PHPExcel Unit Tests * @author Mark Baker From 0588576fe2d7f5993d27ffa612f6d0d650631477 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 5 Aug 2012 22:06:51 +0100 Subject: [PATCH 27/30] Modify Test examples to echo nicely from both CLI and in a web browser --- Tests/13calculation.php | 238 +++++++++++++++++---------------- Tests/14excel5.php | 14 +- Tests/15datavalidation-xls.php | 32 +++-- Tests/15datavalidation.php | 32 +++-- Tests/16csv.php | 22 +-- Tests/17html.php | 14 +- 6 files changed, 194 insertions(+), 158 deletions(-) diff --git a/Tests/13calculation.php b/Tests/13calculation.php index 081a0071..3d1de90b 100644 --- a/Tests/13calculation.php +++ b/Tests/13calculation.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,177 +40,178 @@ require_once '../Classes/PHPExcel.php'; // List functions -echo date('H:i:s') , " List implemented functions" , PHP_EOL; +echo date('H:i:s') , " List implemented functions" , EOL; $objCalc = PHPExcel_Calculation::getInstance(); print_r($objCalc->listFunctionNames()); // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Add some data, we will use some formulas here -echo date('H:i:s') , " Add some data and formulas" , PHP_EOL; -$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Count:'); -$objPHPExcel->getActiveSheet()->setCellValue('A15', 'Sum:'); -$objPHPExcel->getActiveSheet()->setCellValue('A16', 'Max:'); -$objPHPExcel->getActiveSheet()->setCellValue('A17', 'Min:'); -$objPHPExcel->getActiveSheet()->setCellValue('A18', 'Average:'); -$objPHPExcel->getActiveSheet()->setCellValue('A19', 'Median:'); -$objPHPExcel->getActiveSheet()->setCellValue('A20', 'Mode:'); +echo date('H:i:s') , " Add some data and formulas" , EOL; +$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Count:') + ->setCellValue('A15', 'Sum:') + ->setCellValue('A16', 'Max:') + ->setCellValue('A17', 'Min:') + ->setCellValue('A18', 'Average:') + ->setCellValue('A19', 'Median:') + ->setCellValue('A20', 'Mode:'); -$objPHPExcel->getActiveSheet()->setCellValue('A22', 'CountA:'); -$objPHPExcel->getActiveSheet()->setCellValue('A23', 'MaxA:'); -$objPHPExcel->getActiveSheet()->setCellValue('A24', 'MinA:'); +$objPHPExcel->getActiveSheet()->setCellValue('A22', 'CountA:') + ->setCellValue('A23', 'MaxA:') + ->setCellValue('A24', 'MinA:'); -$objPHPExcel->getActiveSheet()->setCellValue('A26', 'StDev:'); -$objPHPExcel->getActiveSheet()->setCellValue('A27', 'StDevA:'); -$objPHPExcel->getActiveSheet()->setCellValue('A28', 'StDevP:'); -$objPHPExcel->getActiveSheet()->setCellValue('A29', 'StDevPA:'); +$objPHPExcel->getActiveSheet()->setCellValue('A26', 'StDev:') + ->setCellValue('A27', 'StDevA:') + ->setCellValue('A28', 'StDevP:') + ->setCellValue('A29', 'StDevPA:'); -$objPHPExcel->getActiveSheet()->setCellValue('A31', 'DevSq:'); -$objPHPExcel->getActiveSheet()->setCellValue('A32', 'Var:'); -$objPHPExcel->getActiveSheet()->setCellValue('A33', 'VarA:'); -$objPHPExcel->getActiveSheet()->setCellValue('A34', 'VarP:'); -$objPHPExcel->getActiveSheet()->setCellValue('A35', 'VarPA:'); +$objPHPExcel->getActiveSheet()->setCellValue('A31', 'DevSq:') + ->setCellValue('A32', 'Var:') + ->setCellValue('A33', 'VarA:') + ->setCellValue('A34', 'VarP:') + ->setCellValue('A35', 'VarPA:'); $objPHPExcel->getActiveSheet()->setCellValue('A37', 'Date:'); -$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range 1'); -$objPHPExcel->getActiveSheet()->setCellValue('B2', 2); -$objPHPExcel->getActiveSheet()->setCellValue('B3', 8); -$objPHPExcel->getActiveSheet()->setCellValue('B4', 10); -$objPHPExcel->getActiveSheet()->setCellValue('B5', True); -$objPHPExcel->getActiveSheet()->setCellValue('B6', False); -$objPHPExcel->getActiveSheet()->setCellValue('B7', 'Text String'); -$objPHPExcel->getActiveSheet()->setCellValue('B9', '22'); -$objPHPExcel->getActiveSheet()->setCellValue('B10', 4); -$objPHPExcel->getActiveSheet()->setCellValue('B11', 6); -$objPHPExcel->getActiveSheet()->setCellValue('B12', 12); +$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range 1') + ->setCellValue('B2', 2) + ->setCellValue('B3', 8) + ->setCellValue('B4', 10) + ->setCellValue('B5', True) + ->setCellValue('B6', False) + ->setCellValue('B7', 'Text String') + ->setCellValue('B9', '22') + ->setCellValue('B10', 4) + ->setCellValue('B11', 6) + ->setCellValue('B12', 12); -$objPHPExcel->getActiveSheet()->setCellValue('B14', '=COUNT(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B15', '=SUM(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B16', '=MAX(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B17', '=MIN(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B18', '=AVERAGE(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B19', '=MEDIAN(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B20', '=MODE(B2:B12)'); +$objPHPExcel->getActiveSheet()->setCellValue('B14', '=COUNT(B2:B12)') + ->setCellValue('B15', '=SUM(B2:B12)') + ->setCellValue('B16', '=MAX(B2:B12)') + ->setCellValue('B17', '=MIN(B2:B12)') + ->setCellValue('B18', '=AVERAGE(B2:B12)') + ->setCellValue('B19', '=MEDIAN(B2:B12)') + ->setCellValue('B20', '=MODE(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B22', '=COUNTA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B23', '=MAXA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B24', '=MINA(B2:B12)'); +$objPHPExcel->getActiveSheet()->setCellValue('B22', '=COUNTA(B2:B12)') + ->setCellValue('B23', '=MAXA(B2:B12)') + ->setCellValue('B24', '=MINA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B26', '=STDEV(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B27', '=STDEVA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B28', '=STDEVP(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B29', '=STDEVPA(B2:B12)'); +$objPHPExcel->getActiveSheet()->setCellValue('B26', '=STDEV(B2:B12)') + ->setCellValue('B27', '=STDEVA(B2:B12)') + ->setCellValue('B28', '=STDEVP(B2:B12)') + ->setCellValue('B29', '=STDEVPA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B31', '=DEVSQ(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B32', '=VAR(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B33', '=VARA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B34', '=VARP(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B35', '=VARPA(B2:B12)'); +$objPHPExcel->getActiveSheet()->setCellValue('B31', '=DEVSQ(B2:B12)') + ->setCellValue('B32', '=VAR(B2:B12)') + ->setCellValue('B33', '=VARA(B2:B12)') + ->setCellValue('B34', '=VARP(B2:B12)') + ->setCellValue('B35', '=VARPA(B2:B12)'); -$objPHPExcel->getActiveSheet()->setCellValue('B37', '=DATE(2007, 12, 21)'); -$objPHPExcel->getActiveSheet()->setCellValue('B38', '=DATEDIF( DATE(2007, 12, 21), DATE(2007, 12, 22), "D" )'); -$objPHPExcel->getActiveSheet()->setCellValue('B39', '=DATEVALUE("01-Feb-2006 10:06 AM")'); -$objPHPExcel->getActiveSheet()->setCellValue('B40', '=DAY( DATE(2006, 1, 2) )'); -$objPHPExcel->getActiveSheet()->setCellValue('B41', '=DAYS360( DATE(2002, 2, 3), DATE(2005, 5, 31) )'); +$objPHPExcel->getActiveSheet()->setCellValue('B37', '=DATE(2007, 12, 21)') + ->setCellValue('B38', '=DATEDIF( DATE(2007, 12, 21), DATE(2007, 12, 22), "D" )') + ->setCellValue('B39', '=DATEVALUE("01-Feb-2006 10:06 AM")') + ->setCellValue('B40', '=DAY( DATE(2006, 1, 2) )') + ->setCellValue('B41', '=DAYS360( DATE(2002, 2, 3), DATE(2005, 5, 31) )'); -$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range 2'); -$objPHPExcel->getActiveSheet()->setCellValue('C2', 1); -$objPHPExcel->getActiveSheet()->setCellValue('C3', 2); -$objPHPExcel->getActiveSheet()->setCellValue('C4', 2); -$objPHPExcel->getActiveSheet()->setCellValue('C5', 3); -$objPHPExcel->getActiveSheet()->setCellValue('C6', 3); -$objPHPExcel->getActiveSheet()->setCellValue('C7', 3); -$objPHPExcel->getActiveSheet()->setCellValue('C8', '0'); -$objPHPExcel->getActiveSheet()->setCellValue('C9', 4); -$objPHPExcel->getActiveSheet()->setCellValue('C10', 4); -$objPHPExcel->getActiveSheet()->setCellValue('C11', 4); -$objPHPExcel->getActiveSheet()->setCellValue('C12', 4); +$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range 2') + ->setCellValue('C2', 1) + ->setCellValue('C3', 2) + ->setCellValue('C4', 2) + ->setCellValue('C5', 3) + ->setCellValue('C6', 3) + ->setCellValue('C7', 3) + ->setCellValue('C8', '0') + ->setCellValue('C9', 4) + ->setCellValue('C10', 4) + ->setCellValue('C11', 4) + ->setCellValue('C12', 4); -$objPHPExcel->getActiveSheet()->setCellValue('C14', '=COUNT(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C15', '=SUM(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C16', '=MAX(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C17', '=MIN(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C18', '=AVERAGE(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C19', '=MEDIAN(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C20', '=MODE(C2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('C14', '=COUNT(C2:C12)') + ->setCellValue('C15', '=SUM(C2:C12)') + ->setCellValue('C16', '=MAX(C2:C12)') + ->setCellValue('C17', '=MIN(C2:C12)') + ->setCellValue('C18', '=AVERAGE(C2:C12)') + ->setCellValue('C19', '=MEDIAN(C2:C12)') + ->setCellValue('C20', '=MODE(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C22', '=COUNTA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C23', '=MAXA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C24', '=MINA(C2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('C22', '=COUNTA(C2:C12)') + ->setCellValue('C23', '=MAXA(C2:C12)') + ->setCellValue('C24', '=MINA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C26', '=STDEV(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C27', '=STDEVA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C28', '=STDEVP(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C29', '=STDEVPA(C2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('C26', '=STDEV(C2:C12)') + ->setCellValue('C27', '=STDEVA(C2:C12)') + ->setCellValue('C28', '=STDEVP(C2:C12)') + ->setCellValue('C29', '=STDEVPA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C31', '=DEVSQ(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C32', '=VAR(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C33', '=VARA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C34', '=VARP(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('C35', '=VARPA(C2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('C31', '=DEVSQ(C2:C12)') + ->setCellValue('C32', '=VAR(C2:C12)') + ->setCellValue('C33', '=VARA(C2:C12)') + ->setCellValue('C34', '=VARP(C2:C12)') + ->setCellValue('C35', '=VARPA(C2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('D1', 'Range 3'); -$objPHPExcel->getActiveSheet()->setCellValue('D2', 2); -$objPHPExcel->getActiveSheet()->setCellValue('D3', 3); -$objPHPExcel->getActiveSheet()->setCellValue('D4', 4); +$objPHPExcel->getActiveSheet()->setCellValue('D1', 'Range 3') + ->setCellValue('D2', 2) + ->setCellValue('D3', 3) + ->setCellValue('D4', 4); $objPHPExcel->getActiveSheet()->setCellValue('D14', '=((D2 * D3) + D4) & " should be 10"'); -$objPHPExcel->getActiveSheet()->setCellValue('E12', 'Other functions'); -$objPHPExcel->getActiveSheet()->setCellValue('E14', '=PI()'); -$objPHPExcel->getActiveSheet()->setCellValue('E15', '=RAND()'); -$objPHPExcel->getActiveSheet()->setCellValue('E16', '=RANDBETWEEN(5, 10)'); +$objPHPExcel->getActiveSheet()->setCellValue('E12', 'Other functions') + ->setCellValue('E14', '=PI()') + ->setCellValue('E15', '=RAND()') + ->setCellValue('E16', '=RANDBETWEEN(5, 10)'); -$objPHPExcel->getActiveSheet()->setCellValue('E17', 'Count of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F17', '=COUNT(B2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('E17', 'Count of both ranges:') + ->setCellValue('F17', '=COUNT(B2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('E18', 'Total of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F18', '=SUM(B2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('E18', 'Total of both ranges:') + ->setCellValue('F18', '=SUM(B2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('E19', 'Maximum of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F19', '=MAX(B2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('E19', 'Maximum of both ranges:') + ->setCellValue('F19', '=MAX(B2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('E20', 'Minimum of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F20', '=MIN(B2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('E20', 'Minimum of both ranges:') + ->setCellValue('F20', '=MIN(B2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('E21', 'Average of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F21', '=AVERAGE(B2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('E21', 'Average of both ranges:') + ->setCellValue('F21', '=AVERAGE(B2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('E22', 'Median of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F22', '=MEDIAN(B2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('E22', 'Median of both ranges:') + ->setCellValue('F22', '=MEDIAN(B2:C12)'); -$objPHPExcel->getActiveSheet()->setCellValue('E23', 'Mode of both ranges:'); -$objPHPExcel->getActiveSheet()->setCellValue('F23', '=MODE(B2:C12)'); +$objPHPExcel->getActiveSheet()->setCellValue('E23', 'Mode of both ranges:') + ->setCellValue('F23', '=MODE(B2:C12)'); // Calculated data -echo date('H:i:s') , " Calculated data" , PHP_EOL; +echo date('H:i:s') , " Calculated data" , EOL; for ($col = 'B'; $col != 'G'; ++$col) { for($row = 14; $row <= 41; ++$row) { if ((!is_null($formula = $objPHPExcel->getActiveSheet()->getCell($col.$row)->getValue())) && ($formula[0] == '=')) { echo 'Value of ' , $col , $row , ' [' , $formula , ']: ' , - $objPHPExcel->getActiveSheet()->getCell($col.$row)->getCalculatedValue() . PHP_EOL; + $objPHPExcel->getActiveSheet()->getCell($col.$row)->getCalculatedValue() . EOL; } } } // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/14excel5.php b/Tests/14excel5.php index 82e61dee..bded748f 100644 --- a/Tests/14excel5.php +++ b/Tests/14excel5.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -36,14 +41,15 @@ include "05featuredemo.inc.php"; require_once '../Classes/PHPExcel/IOFactory.php'; -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing files" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/15datavalidation-xls.php b/Tests/15datavalidation-xls.php index 87ad54da..2f795ca4 100644 --- a/Tests/15datavalidation-xls.php +++ b/Tests/15datavalidation-xls.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,12 +40,12 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -51,17 +56,17 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Create a first sheet -echo date('H:i:s') , " Add data" , PHP_EOL; +echo date('H:i:s') , " Add data" , EOL; $objPHPExcel->setActiveSheetIndex(0); -$objPHPExcel->getActiveSheet()->setCellValue('A1', "Cell B3 and B5 contain data validation..."); -$objPHPExcel->getActiveSheet()->setCellValue('A3', "Number:"); -$objPHPExcel->getActiveSheet()->setCellValue('B3', "10"); -$objPHPExcel->getActiveSheet()->setCellValue('A5', "List:"); -$objPHPExcel->getActiveSheet()->setCellValue('B5', "Item A"); +$objPHPExcel->getActiveSheet()->setCellValue('A1', "Cell B3 and B5 contain data validation...") + ->setCellValue('A3', "Number:") + ->setCellValue('B3', "10") + ->setCellValue('A5', "List:") + ->setCellValue('B5', "Item A"); // Set data validation -echo date('H:i:s') , " Set data validation" , PHP_EOL; +echo date('H:i:s') , " Set data validation" , EOL; $objValidation = $objPHPExcel->getActiveSheet()->getCell('B3')->getDataValidation(); $objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_WHOLE ); $objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP ); @@ -94,14 +99,15 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/15datavalidation.php b/Tests/15datavalidation.php index 6f8809bd..c5221d63 100644 --- a/Tests/15datavalidation.php +++ b/Tests/15datavalidation.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,12 +40,12 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -51,17 +56,17 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Create a first sheet -echo date('H:i:s') , " Add data" , PHP_EOL; +echo date('H:i:s') , " Add data" , EOL; $objPHPExcel->setActiveSheetIndex(0); -$objPHPExcel->getActiveSheet()->setCellValue('A1', "Cell B3 and B5 contain data validation..."); -$objPHPExcel->getActiveSheet()->setCellValue('A3', "Number:"); -$objPHPExcel->getActiveSheet()->setCellValue('B3', "10"); -$objPHPExcel->getActiveSheet()->setCellValue('A5', "List:"); -$objPHPExcel->getActiveSheet()->setCellValue('B5', "Item A"); +$objPHPExcel->getActiveSheet()->setCellValue('A1', "Cell B3 and B5 contain data validation...") + ->setCellValue('A3', "Number:") + ->setCellValue('B3', "10") + ->setCellValue('A5', "List:") + ->setCellValue('B5', "Item A"); // Set data validation -echo date('H:i:s') , " Set data validation" , PHP_EOL; +echo date('H:i:s') , " Set data validation" , EOL; $objValidation = $objPHPExcel->getActiveSheet()->getCell('B3')->getDataValidation(); $objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_WHOLE ); $objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP ); @@ -94,14 +99,15 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/16csv.php b/Tests/16csv.php index f2057088..db377c6a 100644 --- a/Tests/16csv.php +++ b/Tests/16csv.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -36,31 +41,32 @@ include "05featuredemo.inc.php"; require_once '../Classes/PHPExcel/IOFactory.php'; -echo date('H:i:s') , " Write to CSV format" , PHP_EOL; +echo date('H:i:s') , " Write to CSV format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV')->setDelimiter(',') ->setEnclosure('"') ->setLineEnding("\r\n") ->setSheetIndex(0) ->save(str_replace('.php', '.csv', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.csv', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; -echo date('H:i:s') , " Read from CSV format" , PHP_EOL; +echo date('H:i:s') , " Read from CSV format" , EOL; $objReader = PHPExcel_IOFactory::createReader('CSV')->setDelimiter(',') ->setEnclosure('"') ->setLineEnding("\r\n") ->setSheetIndex(0); $objPHPExcelFromCSV = $objReader->load(str_replace('.php', '.csv', __FILE__)); -echo date('H:i:s') , " File read from " , str_replace('.php', '.csv', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File read from " , str_replace('.php', '.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter2007 = PHPExcel_IOFactory::createWriter($objPHPExcelFromCSV, 'Excel2007'); $objWriter2007->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing files" , PHP_EOL; +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Tests/17html.php b/Tests/17html.php index 281b86ac..5bfcab34 100644 --- a/Tests/17html.php +++ b/Tests/17html.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -36,16 +41,17 @@ include "05featuredemo.inc.php"; require_once '../Classes/PHPExcel/IOFactory.php'; -echo date('H:i:s') , " Write to HTML format" , PHP_EOL; +echo date('H:i:s') , " Write to HTML format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML'); $objWriter->setSheetIndex(0); //$objWriter->setImagesRoot('http://www.example.com'); $objWriter->save(str_replace('.php', '.htm', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.htm', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.htm', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing files" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; From cf78af261c5cd640eebd8aef30c44ee4e4c6da04 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 5 Aug 2012 23:03:45 +0100 Subject: [PATCH 28/30] Modify Test examples to echo nicely from both CLI and in a web browser --- Tests/14excel5.php | 1 - Tests/18extendedcalculation.php | 7 +- Tests/19namedrange.php | 40 ++++++---- Tests/20readexcel5.php | 16 ++-- Tests/21pdf.php | 20 +++-- Tests/22heavilyformatted.php | 20 +++-- Tests/23sharedstyles.php | 20 +++-- Tests/24readfilter.php | 17 ++-- Tests/25inmemoryimage.php | 21 +++-- Tests/26utf8.php | 44 ++++++----- Tests/27imagesexcel5.php | 19 +++-- Tests/28iterator.php | 18 +++-- Tests/29advancedvaluebinder.php | 117 ++++++++++++++-------------- Tests/30template.php | 27 ++++--- Tests/31docproperties_write-xls.php | 60 +++++++------- Tests/31docproperties_write.php | 60 +++++++------- Tests/32chartreadwrite.php | 34 ++++---- Tests/33chartcreate.php | 14 +++- Tests/34chartupdate.php | 20 +++-- 19 files changed, 334 insertions(+), 241 deletions(-) diff --git a/Tests/14excel5.php b/Tests/14excel5.php index bded748f..27865b19 100644 --- a/Tests/14excel5.php +++ b/Tests/14excel5.php @@ -29,7 +29,6 @@ error_reporting(E_ALL); ini_set('display_errors', TRUE); ini_set('display_startup_errors', TRUE); -date_default_timezone_set('Europe/London'); define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); diff --git a/Tests/18extendedcalculation.php b/Tests/18extendedcalculation.php index 954e589d..2cc8137b 100644 --- a/Tests/18extendedcalculation.php +++ b/Tests/18extendedcalculation.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -100,4 +105,4 @@ echo 'Value of B14 [=COUNT(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell echo date('H:i:s') . " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB\r\n"; // Echo done -echo date('H:i:s') . " Done.\r\n"; +echo date('H:i:s') . " Done" , EOL; diff --git a/Tests/19namedrange.php b/Tests/19namedrange.php index 20098c89..ef03c5e2 100644 --- a/Tests/19namedrange.php +++ b/Tests/19namedrange.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,11 +40,11 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -50,7 +55,7 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Add some data -echo date('H:i:s') , " Add some data" , PHP_EOL; +echo date('H:i:s') , " Add some data" , EOL; $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:') ->setCellValue('A2', 'Lastname:') @@ -60,25 +65,25 @@ $objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:') ->setCellValue('B3', '=B1 & " " & B2'); // Define named ranges -echo date('H:i:s') , " Define named ranges" , PHP_EOL; +echo date('H:i:s') , " Define named ranges" , EOL; $objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonName', $objPHPExcel->getActiveSheet(), 'B1') ); $objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonLN', $objPHPExcel->getActiveSheet(), 'B2') ); // Rename named ranges -echo date('H:i:s') , " Rename named ranges" , PHP_EOL; +echo date('H:i:s') , " Rename named ranges" , EOL; $objPHPExcel->getNamedRange('PersonName')->setName('PersonFN'); // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Person'); // Create a new worksheet, after the default sheet -echo date('H:i:s') , " Create new Worksheet object" , PHP_EOL; +echo date('H:i:s') , " Create new Worksheet object" , EOL; $objPHPExcel->createSheet(); // Add some data to the second sheet, resembling some different data types -echo date('H:i:s') , " Add some data" , PHP_EOL; +echo date('H:i:s') , " Add some data" , EOL; $objPHPExcel->setActiveSheetIndex(1); $objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:') ->setCellValue('A2', 'Lastname:') @@ -88,13 +93,13 @@ $objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:') ->setCellValue('B3', '=PersonFN & " " & PersonLN'); // Resolve range -echo date('H:i:s') , " Resolve range" , PHP_EOL; -echo 'Cell B1 {=PersonFN}: ' , $objPHPExcel->getActiveSheet()->getCell('B1')->getCalculatedValue() , PHP_EOL; -echo 'Cell B3 {=PersonFN & " " & PersonLN}: ' , $objPHPExcel->getActiveSheet()->getCell('B3')->getCalculatedValue() , PHP_EOL; -echo 'Cell Person!B1: ' , $objPHPExcel->getActiveSheet()->getCell('Person!B1')->getCalculatedValue() , PHP_EOL; +echo date('H:i:s') , " Resolve range" , EOL; +echo 'Cell B1 {=PersonFN}: ' , $objPHPExcel->getActiveSheet()->getCell('B1')->getCalculatedValue() , EOL; +echo 'Cell B3 {=PersonFN & " " & PersonLN}: ' , $objPHPExcel->getActiveSheet()->getCell('B3')->getCalculatedValue() , EOL; +echo 'Cell Person!B1: ' , $objPHPExcel->getActiveSheet()->getCell('Person!B1')->getCalculatedValue() , EOL; // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Person (cloned)'); // Set active sheet index to the first sheet, so Excel opens this as the first sheet @@ -102,14 +107,15 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/20readexcel5.php b/Tests/20readexcel5.php index f763257f..dd77cb65 100644 --- a/Tests/20readexcel5.php +++ b/Tests/20readexcel5.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -38,17 +43,18 @@ if (!file_exists("14excel5.xls")) { exit("Please run 14excel5.php first.\n"); } -echo date('H:i:s') , " Load workbook from Excel5 file" , PHP_EOL; +echo date('H:i:s') , " Load workbook from Excel5 file" , EOL; $objPHPExcel = PHPExcel_IOFactory::load("14excel5.xls"); -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done reading file" , PHP_EOL; +echo date('H:i:s') , " Done reading file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/21pdf.php b/Tests/21pdf.php index ddfd99fa..9c13b70a 100644 --- a/Tests/21pdf.php +++ b/Tests/21pdf.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -46,14 +51,14 @@ $rendererLibrary = 'domPDF0.6.0beta3'; $rendererLibraryPath = dirname(__FILE__).'/../../../libraries/PDF/' . $rendererLibrary; -echo date('H:i:s') , " Hide grid lines" , PHP_EOL; +echo date('H:i:s') , " Hide grid lines" , EOL; $objPHPExcel->getActiveSheet()->setShowGridLines(false); -echo date('H:i:s') , " Set orientation to landscape" , PHP_EOL; +echo date('H:i:s') , " Set orientation to landscape" , EOL; $objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); -echo date('H:i:s') , " Write to PDF format using {$rendererName}" , PHP_EOL; +echo date('H:i:s') , " Write to PDF format using {$rendererName}" , EOL; if (!PHPExcel_Settings::setPdfRenderer( $rendererName, @@ -61,7 +66,7 @@ if (!PHPExcel_Settings::setPdfRenderer( )) { die( 'NOTICE: Please set the $rendererName and $rendererLibraryPath values' . - PHP_EOL . + EOL . 'at the top of this script as appropriate for your directory structure' ); } @@ -70,11 +75,12 @@ if (!PHPExcel_Settings::setPdfRenderer( $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF'); $objWriter->setSheetIndex(0); $objWriter->save(str_replace('.php', '_'.$rendererName.'.pdf', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '_'.$rendererName.'.pdf', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '_'.$rendererName.'.pdf', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing files" , PHP_EOL; +echo date('H:i:s') , " Done writing files" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/22heavilyformatted.php b/Tests/22heavilyformatted.php index 5ddd978a..59eb2442 100644 --- a/Tests/22heavilyformatted.php +++ b/Tests/22heavilyformatted.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,11 +40,11 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -50,7 +55,7 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Add some data -echo date('H:i:s') , " Add some data" , PHP_EOL; +echo date('H:i:s') , " Add some data" , EOL; $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getActiveSheet()->getStyle('A1:T100')->applyFromArray( @@ -74,14 +79,15 @@ $objPHPExcel->getActiveSheet()->getStyle('C5:R95')->applyFromArray( ); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/23sharedstyles.php b/Tests/23sharedstyles.php index 95e4fb5d..759bae9e 100644 --- a/Tests/23sharedstyles.php +++ b/Tests/23sharedstyles.php @@ -27,6 +27,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,11 +40,11 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -50,7 +55,7 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") // Add some data -echo date('H:i:s') , " Add some data" , PHP_EOL; +echo date('H:i:s') , " Add some data" , EOL; $objPHPExcel->setActiveSheetIndex(0); $sharedStyle1 = new PHPExcel_Style(); @@ -82,14 +87,15 @@ $objPHPExcel->getActiveSheet()->setSharedStyle($sharedStyle1, "A1:T100"); $objPHPExcel->getActiveSheet()->setSharedStyle($sharedStyle2, "C5:R95"); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/24readfilter.php b/Tests/24readfilter.php index d695e0f1..386f40d7 100644 --- a/Tests/24readfilter.php +++ b/Tests/24readfilter.php @@ -26,6 +26,10 @@ */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -51,22 +55,23 @@ class MyReadFilter implements PHPExcel_Reader_IReadFilter } -echo date('H:i:s') , " Load from Excel2007 file" , PHP_EOL; +echo date('H:i:s') , " Load from Excel2007 file" , EOL; $objReader = PHPExcel_IOFactory::createReader('Excel2007'); $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.xlsx"); -echo date('H:i:s') , " Remove unnecessary rows" , PHP_EOL; +echo date('H:i:s') , " Remove unnecessary rows" , EOL; $objPHPExcel->getActiveSheet()->removeRow(2, 18); -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing files" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/25inmemoryimage.php b/Tests/25inmemoryimage.php index 1b99cfc4..0ed15085 100644 --- a/Tests/25inmemoryimage.php +++ b/Tests/25inmemoryimage.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,11 +39,11 @@ require_once '../Classes/PHPExcel.php'; // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -49,13 +53,13 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setCategory("Test result file"); // Generate an image -echo date('H:i:s') , " Generate an image" , PHP_EOL; +echo date('H:i:s') , " Generate an image" , EOL; $gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream'); $textColor = imagecolorallocate($gdImage, 255, 255, 255); imagestring($gdImage, 1, 5, 5, 'Created with PHPExcel', $textColor); // Add a drawing to the worksheet -echo date('H:i:s') , " Add a drawing to the worksheet" , PHP_EOL; +echo date('H:i:s') , " Add a drawing to the worksheet" , EOL; $objDrawing = new PHPExcel_Worksheet_MemoryDrawing(); $objDrawing->setName('Sample image'); $objDrawing->setDescription('Sample image'); @@ -65,14 +69,15 @@ $objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT); $objDrawing->setHeight(36); $objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing files" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/26utf8.php b/Tests/26utf8.php index b2e69ec0..b46c933b 100644 --- a/Tests/26utf8.php +++ b/Tests/26utf8.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -46,32 +50,32 @@ $rendererLibraryPath = dirname(__FILE__).'/../../../libraries/PDF/' . $rendererL // Read from Excel2007 (.xlsx) template -echo date('H:i:s') , " Load Excel2007 template file" , PHP_EOL; +echo date('H:i:s') , " Load Excel2007 template file" , EOL; $objReader = PHPExcel_IOFactory::createReader('Excel2007'); $objPHPExcel = $objReader->load("templates/26template.xlsx"); /** at this point, we could do some manipulations with the template, but we skip this step */ // Export to Excel2007 (.xlsx) -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Export to Excel5 (.xls) -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Export to HTML (.html) -echo date('H:i:s') , " Write to HTML format" , PHP_EOL; +echo date('H:i:s') , " Write to HTML format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML'); $objWriter->save(str_replace('.php', '.htm', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.htm', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.htm', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Export to PDF (.pdf) -echo date('H:i:s') , " Write to PDF format" , PHP_EOL; +echo date('H:i:s') , " Write to PDF format" , EOL; try { if (!PHPExcel_Settings::setPdfRenderer( $rendererName, @@ -79,38 +83,40 @@ try { )) { echo ( 'NOTICE: Please set the $rendererName and $rendererLibraryPath values' . - PHP_EOL . - 'at the top of this script as appropriate for your directory structure' + EOL . + 'at the top of this script as appropriate for your directory structure' . + EOL ); } else { $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF'); $objWriter->save(str_replace('.php', '.pdf', __FILE__)); - echo date('H:i:s') , " File written to " , str_replace('.php', '.pdf', __FILE__) , PHP_EOL; + echo date('H:i:s') , " File written to " , str_replace('.php', '.pdf', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; } } catch (Exception $e) { - echo date('H:i:s') , ' EXCEPTION: ', $e->getMessage() , PHP_EOL; + echo date('H:i:s') , ' EXCEPTION: ', $e->getMessage() , EOL; } // Remove first two rows with field headers before exporting to CSV -echo date('H:i:s') , " Removing first two heading rows for CSV export" , PHP_EOL; +echo date('H:i:s') , " Removing first two heading rows for CSV export" , EOL; $objWorksheet = $objPHPExcel->getActiveSheet(); $objWorksheet->removeRow(1, 2); // Export to CSV (.csv) -echo date('H:i:s') , " Write to CSV format" , PHP_EOL; +echo date('H:i:s') , " Write to CSV format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV'); $objWriter->save(str_replace('.php', '.csv', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.csv', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Export to CSV with BOM (.csv) -echo date('H:i:s') , " Write to CSV format (with BOM)" , PHP_EOL; +echo date('H:i:s') , " Write to CSV format (with BOM)" , EOL; $objWriter->setUseBOM(true); $objWriter->save(str_replace('.php', '-bom.csv', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '-bom.csv', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '-bom.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing files" , PHP_EOL; +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Tests/27imagesexcel5.php b/Tests/27imagesexcel5.php index 7f95c90f..462ec6e7 100644 --- a/Tests/27imagesexcel5.php +++ b/Tests/27imagesexcel5.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,25 +39,26 @@ require_once '../Classes/PHPExcel.php'; // Read from Excel5 (.xls) template -echo date('H:i:s') , " Load Excel2007 template file" , PHP_EOL; +echo date('H:i:s') , " Load Excel2007 template file" , EOL; $objReader = PHPExcel_IOFactory::createReader('Excel5'); $objPHPExcel = $objReader->load("templates/27template.xls"); // Export to Excel2007 (.xlsx) -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Export to Excel5 (.xls) -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing files" , PHP_EOL; +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Tests/28iterator.php b/Tests/28iterator.php index 52fbfce0..1c6e6d85 100644 --- a/Tests/28iterator.php +++ b/Tests/28iterator.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,25 +39,25 @@ require_once '../Classes/PHPExcel/IOFactory.php'; if (!file_exists("05featuredemo.xlsx")) { - exit("Please run 05featuredemo.php first." . PHP_EOL); + exit("Please run 05featuredemo.php first." . EOL); } -echo date('H:i:s') , " Load from Excel2007 file" , PHP_EOL; +echo date('H:i:s') , " Load from Excel2007 file" , EOL; $objReader = PHPExcel_IOFactory::createReader('Excel2007'); $objPHPExcel = $objReader->load("05featuredemo.xlsx"); -echo date('H:i:s') , " Iterate worksheets" , PHP_EOL; +echo date('H:i:s') , " Iterate worksheets" , EOL; foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) { - echo 'Worksheet - ' , $worksheet->getTitle() , PHP_EOL; + echo 'Worksheet - ' , $worksheet->getTitle() , EOL; foreach ($worksheet->getRowIterator() as $row) { - echo ' Row number - ' , $row->getRowIndex() , PHP_EOL; + echo ' Row number - ' , $row->getRowIndex() , EOL; $cellIterator = $row->getCellIterator(); $cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set foreach ($cellIterator as $cell) { if (!is_null($cell)) { - echo ' Cell - ' , $cell->getCoordinate() , ' - ' , $cell->getCalculatedValue() , PHP_EOL; + echo ' Cell - ' , $cell->getCoordinate() , ' - ' , $cell->getCalculatedValue() , EOL; } } } @@ -61,4 +65,4 @@ foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) { // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; diff --git a/Tests/29advancedvaluebinder.php b/Tests/29advancedvaluebinder.php index e2e7d127..3e34264b 100644 --- a/Tests/29advancedvaluebinder.php +++ b/Tests/29advancedvaluebinder.php @@ -27,27 +27,29 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); -date_default_timezone_set('Europe/London'); +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** PHPExcel */ require_once '../Classes/PHPExcel.php'; // Set timezone -echo date('H:i:s') , " Set timezone" , PHP_EOL; +echo date('H:i:s') , " Set timezone" , EOL; date_default_timezone_set('UTC'); // Set value binder -echo date('H:i:s') , " Set value binder" , PHP_EOL; +echo date('H:i:s') , " Set value binder" , EOL; PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); // Create new PHPExcel object -echo date('H:i:s') , " Create new PHPExcel object" , PHP_EOL; +echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); // Set document properties -echo date('H:i:s') , " Set document properties" , PHP_EOL; +echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") @@ -57,85 +59,85 @@ $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") ->setCategory("Test result file"); // Set default font -echo date('H:i:s') , " Set default font" , PHP_EOL; +echo date('H:i:s') , " Set default font" , EOL; $objPHPExcel->getActiveSheet()->getDefaultStyle()->getFont()->setName('Arial'); $objPHPExcel->getActiveSheet()->getDefaultStyle()->getFont()->setSize(10); // Set column widths -echo date('H:i:s') , " Set column widths" , PHP_EOL; +echo date('H:i:s') , " Set column widths" , EOL; $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setAutoSize(true); $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(14); // Add some data, resembling some different data types -echo date('H:i:s') , " Add some data" , PHP_EOL; -$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String value:'); -$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Mark Baker'); +echo date('H:i:s') , " Add some data" , EOL; +$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String value:') + ->setCellValue('B1', 'Mark Baker'); -$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Numeric value #1:'); -$objPHPExcel->getActiveSheet()->setCellValue('B2', 12345); +$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Numeric value #1:') + ->setCellValue('B2', 12345); -$objPHPExcel->getActiveSheet()->setCellValue('A3', 'Numeric value #2:'); -$objPHPExcel->getActiveSheet()->setCellValue('B3', -12.345); +$objPHPExcel->getActiveSheet()->setCellValue('A3', 'Numeric value #2:') + ->setCellValue('B3', -12.345); -$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Numeric value #3:'); -$objPHPExcel->getActiveSheet()->setCellValue('B4', .12345); +$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Numeric value #3:') + ->setCellValue('B4', .12345); -$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Numeric value #4:'); -$objPHPExcel->getActiveSheet()->setCellValue('B5', '12345'); +$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Numeric value #4:') + ->setCellValue('B5', '12345'); -$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Numeric value #5:'); -$objPHPExcel->getActiveSheet()->setCellValue('B6', '1.2345'); +$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Numeric value #5:') + ->setCellValue('B6', '1.2345'); -$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Numeric value #6:'); -$objPHPExcel->getActiveSheet()->setCellValue('B7', '.12345'); +$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Numeric value #6:') + ->setCellValue('B7', '.12345'); -$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Numeric value #7:'); -$objPHPExcel->getActiveSheet()->setCellValue('B8', '1.234e-5'); +$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Numeric value #7:') + ->setCellValue('B8', '1.234e-5'); -$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Numeric value #8:'); -$objPHPExcel->getActiveSheet()->setCellValue('B9', '-1.234e+5'); +$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Numeric value #8:') + ->setCellValue('B9', '-1.234e+5'); -$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Boolean value:'); -$objPHPExcel->getActiveSheet()->setCellValue('B10', true); +$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Boolean value:') + ->setCellValue('B10', true); -$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Percentage value #1:'); -$objPHPExcel->getActiveSheet()->setCellValue('B11', '10%'); +$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Percentage value #1:') + ->setCellValue('B11', '10%'); -$objPHPExcel->getActiveSheet()->setCellValue('A12', 'Percentage value #2:'); -$objPHPExcel->getActiveSheet()->setCellValue('B12', '12.5%'); +$objPHPExcel->getActiveSheet()->setCellValue('A12', 'Percentage value #2:') + ->setCellValue('B12', '12.5%'); -$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Currency value:'); -$objPHPExcel->getActiveSheet()->setCellValue('B13', '$12345'); +$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Currency value:') + ->setCellValue('B13', '$12345'); -$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Date value #1:'); -$objPHPExcel->getActiveSheet()->setCellValue('B14', '21 December 1983'); +$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Date value #1:') + ->setCellValue('B14', '21 December 1983'); -$objPHPExcel->getActiveSheet()->setCellValue('A15', 'Date value #2:'); -$objPHPExcel->getActiveSheet()->setCellValue('B15', '19-Dec-1960'); +$objPHPExcel->getActiveSheet()->setCellValue('A15', 'Date value #2:') + ->setCellValue('B15', '19-Dec-1960'); -$objPHPExcel->getActiveSheet()->setCellValue('A16', 'Date value #3:'); -$objPHPExcel->getActiveSheet()->setCellValue('B16', '19/12/1960'); +$objPHPExcel->getActiveSheet()->setCellValue('A16', 'Date value #3:') + ->setCellValue('B16', '19/12/1960'); -$objPHPExcel->getActiveSheet()->setCellValue('A17', 'Date value #4:'); -$objPHPExcel->getActiveSheet()->setCellValue('B17', '19-12-1960'); +$objPHPExcel->getActiveSheet()->setCellValue('A17', 'Date value #4:') + ->setCellValue('B17', '19-12-1960'); -$objPHPExcel->getActiveSheet()->setCellValue('A18', 'Date value #5:'); -$objPHPExcel->getActiveSheet()->setCellValue('B18', '1-Jan'); +$objPHPExcel->getActiveSheet()->setCellValue('A18', 'Date value #5:') + ->setCellValue('B18', '1-Jan'); -$objPHPExcel->getActiveSheet()->setCellValue('A19', 'Time value #1:'); -$objPHPExcel->getActiveSheet()->setCellValue('B19', '01:30'); +$objPHPExcel->getActiveSheet()->setCellValue('A19', 'Time value #1:') + ->setCellValue('B19', '01:30'); -$objPHPExcel->getActiveSheet()->setCellValue('A20', 'Time value #2:'); -$objPHPExcel->getActiveSheet()->setCellValue('B20', '01:30:15'); +$objPHPExcel->getActiveSheet()->setCellValue('A20', 'Time value #2:') + ->setCellValue('B20', '01:30:15'); -$objPHPExcel->getActiveSheet()->setCellValue('A21', 'Date/Time value:'); -$objPHPExcel->getActiveSheet()->setCellValue('B21', '19-Dec-1960 01:30'); +$objPHPExcel->getActiveSheet()->setCellValue('A21', 'Date/Time value:') + ->setCellValue('B21', '19-Dec-1960 01:30'); -$objPHPExcel->getActiveSheet()->setCellValue('A22', 'Formula:'); -$objPHPExcel->getActiveSheet()->setCellValue('B22', '=SUM(B2:B9)'); +$objPHPExcel->getActiveSheet()->setCellValue('A22', 'Formula:') + ->setCellValue('B22', '=SUM(B2:B9)'); // Rename worksheet -echo date('H:i:s') , " Rename worksheet" , PHP_EOL; +echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Advanced value binder'); @@ -144,14 +146,15 @@ $objPHPExcel->setActiveSheetIndex(0); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/30template.php b/Tests/30template.php index d601bea0..6367de07 100644 --- a/Tests/30template.php +++ b/Tests/30template.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -35,14 +39,14 @@ require_once '../Classes/PHPExcel/IOFactory.php'; -echo date('H:i:s') , " Load from Excel5 template" , PHP_EOL; +echo date('H:i:s') , " Load from Excel5 template" , EOL; $objReader = PHPExcel_IOFactory::createReader('Excel5'); $objPHPExcel = $objReader->load("templates/30template.xls"); -echo date('H:i:s') , " Add new data to the template" , PHP_EOL; +echo date('H:i:s') , " Add new data to the template" , EOL; $data = array(array('title' => 'Excel for dummies', 'price' => 17.99, 'quantity' => 2 @@ -64,23 +68,24 @@ foreach($data as $r => $dataRow) { $row = $baseRow + $r; $objPHPExcel->getActiveSheet()->insertNewRowBefore($row,1); - $objPHPExcel->getActiveSheet()->setCellValue('A'.$row, $r+1); - $objPHPExcel->getActiveSheet()->setCellValue('B'.$row, $dataRow['title']); - $objPHPExcel->getActiveSheet()->setCellValue('C'.$row, $dataRow['price']); - $objPHPExcel->getActiveSheet()->setCellValue('D'.$row, $dataRow['quantity']); - $objPHPExcel->getActiveSheet()->setCellValue('E'.$row, '=C'.$row.'*D'.$row); + $objPHPExcel->getActiveSheet()->setCellValue('A'.$row, $r+1) + ->setCellValue('B'.$row, $dataRow['title']) + ->setCellValue('C'.$row, $dataRow['price']) + ->setCellValue('D'.$row, $dataRow['quantity']) + ->setCellValue('E'.$row, '=C'.$row.'*D'.$row); } $objPHPExcel->getActiveSheet()->removeRow($baseRow-1,1); -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/31docproperties_write-xls.php b/Tests/31docproperties_write-xls.php index 58e2269a..6c136817 100644 --- a/Tests/31docproperties_write-xls.php +++ b/Tests/31docproperties_write-xls.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -38,7 +42,7 @@ $inputFileType = 'Excel5'; $inputFileName = 'templates/31docproperties.xls'; -echo date('H:i:s') , " Load Tests from $inputFileType file" , PHP_EOL; +echo date('H:i:s') , " Load Tests from $inputFileType file" , EOL; $callStartTime = microtime(true); $objPHPExcelReader = PHPExcel_IOFactory::createReader($inputFileType); @@ -46,12 +50,12 @@ $objPHPExcel = $objPHPExcelReader->load($inputFileName); $callEndTime = microtime(true); $callTime = $callEndTime - $callStartTime; -echo 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , PHP_EOL; +echo 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; // Echo memory usage -echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; -echo date('H:i:s') , " Adjust properties" , PHP_EOL; +echo date('H:i:s') , " Adjust properties" , EOL; $objPHPExcel->getProperties()->setTitle("Office 95 XLS Test Document") ->setSubject("Office 95 XLS Test Document") ->setDescription("Test XLS document, generated using PHPExcel") @@ -59,57 +63,57 @@ $objPHPExcel->getProperties()->setTitle("Office 95 XLS Test Document") // Save Excel 95 file -echo date('H:i:s') , " Write to Excel5 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel5 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , EOL; -echo PHP_EOL; +echo EOL; // Reread File -echo date('H:i:s') , " Reread Excel5 file" , PHP_EOL; +echo date('H:i:s') , " Reread Excel5 file" , EOL; $objPHPExcelRead = PHPExcel_IOFactory::load(str_replace('.php', '.xls', __FILE__)); // Set properties -echo date('H:i:s') , " Get properties" , PHP_EOL; +echo date('H:i:s') , " Get properties" , EOL; -echo 'Core Properties:' , PHP_EOL; -echo ' Created by - ' , $objPHPExcel->getProperties()->getCreator() , PHP_EOL; +echo 'Core Properties:' , EOL; +echo ' Created by - ' , $objPHPExcel->getProperties()->getCreator() , EOL; echo ' Created on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getCreated()) , ' at ' , - date('H:i:s',$objPHPExcel->getProperties()->getCreated()) , PHP_EOL; -echo ' Last Modified by - ' , $objPHPExcel->getProperties()->getLastModifiedBy() , PHP_EOL; + date('H:i:s',$objPHPExcel->getProperties()->getCreated()) , EOL; +echo ' Last Modified by - ' , $objPHPExcel->getProperties()->getLastModifiedBy() , EOL; echo ' Last Modified on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getModified()) , ' at ' , - date('H:i:s',$objPHPExcel->getProperties()->getModified()) , PHP_EOL; -echo ' Title - ' , $objPHPExcel->getProperties()->getTitle() , PHP_EOL; -echo ' Subject - ' , $objPHPExcel->getProperties()->getSubject() , PHP_EOL; -echo ' Description - ' , $objPHPExcel->getProperties()->getDescription() , PHP_EOL; -echo ' Keywords: - ' , $objPHPExcel->getProperties()->getKeywords() , PHP_EOL; + date('H:i:s',$objPHPExcel->getProperties()->getModified()) , EOL; +echo ' Title - ' , $objPHPExcel->getProperties()->getTitle() , EOL; +echo ' Subject - ' , $objPHPExcel->getProperties()->getSubject() , EOL; +echo ' Description - ' , $objPHPExcel->getProperties()->getDescription() , EOL; +echo ' Keywords: - ' , $objPHPExcel->getProperties()->getKeywords() , EOL; -echo 'Extended (Application) Properties:' , PHP_EOL; -echo ' Category - ' , $objPHPExcel->getProperties()->getCategory() , PHP_EOL; -echo ' Company - ' , $objPHPExcel->getProperties()->getCompany() , PHP_EOL; -echo ' Manager - ' , $objPHPExcel->getProperties()->getManager() , PHP_EOL; +echo 'Extended (Application) Properties:' , EOL; +echo ' Category - ' , $objPHPExcel->getProperties()->getCategory() , EOL; +echo ' Company - ' , $objPHPExcel->getProperties()->getCompany() , EOL; +echo ' Manager - ' , $objPHPExcel->getProperties()->getManager() , EOL; -echo 'Custom Properties:' , PHP_EOL; +echo 'Custom Properties:' , EOL; $customProperties = $objPHPExcel->getProperties()->getCustomProperties(); foreach($customProperties as $customProperty) { $propertyValue = $objPHPExcel->getProperties()->getCustomPropertyValue($customProperty); $propertyType = $objPHPExcel->getProperties()->getCustomPropertyType($customProperty); echo ' ' , $customProperty , ' - (' , $propertyType , ') - '; if ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE) { - echo date('d-M-Y H:i:s',$propertyValue) , PHP_EOL; + echo date('d-M-Y H:i:s',$propertyValue) , EOL; } elseif ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN) { - echo (($propertyValue) ? 'TRUE' : 'FALSE') , PHP_EOL; + echo (($propertyValue) ? 'TRUE' : 'FALSE') , EOL; } else { - echo $propertyValue , PHP_EOL; + echo $propertyValue , EOL; } } // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , EOL; diff --git a/Tests/31docproperties_write.php b/Tests/31docproperties_write.php index c3ef6a8a..7e474979 100644 --- a/Tests/31docproperties_write.php +++ b/Tests/31docproperties_write.php @@ -27,6 +27,10 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -38,7 +42,7 @@ $inputFileType = 'Excel2007'; $inputFileName = 'templates/31docproperties.xlsx'; -echo date('H:i:s') , " Load Tests from $inputFileType file" , PHP_EOL; +echo date('H:i:s') , " Load Tests from $inputFileType file" , EOL; $callStartTime = microtime(true); $objPHPExcelReader = PHPExcel_IOFactory::createReader($inputFileType); @@ -46,12 +50,12 @@ $objPHPExcel = $objPHPExcelReader->load($inputFileName); $callEndTime = microtime(true); $callTime = $callEndTime - $callStartTime; -echo 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , PHP_EOL; +echo 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; // Echo memory usage -echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; -echo date('H:i:s') , " Adjust properties" , PHP_EOL; +echo date('H:i:s') , " Adjust properties" , EOL; $objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document") ->setSubject("Office 2007 XLSX Test Document") ->setDescription("Test XLSX document, generated using PHPExcel") @@ -59,57 +63,57 @@ $objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document") // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , EOL; -echo PHP_EOL; +echo EOL; // Reread File -echo date('H:i:s') , " Reread Excel2007 file" , PHP_EOL; +echo date('H:i:s') , " Reread Excel2007 file" , EOL; $objPHPExcelRead = PHPExcel_IOFactory::load(str_replace('.php', '.xlsx', __FILE__)); // Set properties -echo date('H:i:s') , " Get properties" , PHP_EOL; +echo date('H:i:s') , " Get properties" , EOL; -echo 'Core Properties:' , PHP_EOL; -echo ' Created by - ' , $objPHPExcel->getProperties()->getCreator() , PHP_EOL; +echo 'Core Properties:' , EOL; +echo ' Created by - ' , $objPHPExcel->getProperties()->getCreator() , EOL; echo ' Created on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getCreated()) , ' at ' , - date('H:i:s',$objPHPExcel->getProperties()->getCreated()) , PHP_EOL; -echo ' Last Modified by - ' , $objPHPExcel->getProperties()->getLastModifiedBy() , PHP_EOL; + date('H:i:s',$objPHPExcel->getProperties()->getCreated()) , EOL; +echo ' Last Modified by - ' , $objPHPExcel->getProperties()->getLastModifiedBy() , EOL; echo ' Last Modified on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getModified()) , ' at ' , - date('H:i:s',$objPHPExcel->getProperties()->getModified()) , PHP_EOL; -echo ' Title - ' , $objPHPExcel->getProperties()->getTitle() , PHP_EOL; -echo ' Subject - ' , $objPHPExcel->getProperties()->getSubject() , PHP_EOL; -echo ' Description - ' , $objPHPExcel->getProperties()->getDescription() , PHP_EOL; -echo ' Keywords: - ' , $objPHPExcel->getProperties()->getKeywords() , PHP_EOL; + date('H:i:s',$objPHPExcel->getProperties()->getModified()) , EOL; +echo ' Title - ' , $objPHPExcel->getProperties()->getTitle() , EOL; +echo ' Subject - ' , $objPHPExcel->getProperties()->getSubject() , EOL; +echo ' Description - ' , $objPHPExcel->getProperties()->getDescription() , EOL; +echo ' Keywords: - ' , $objPHPExcel->getProperties()->getKeywords() , EOL; -echo 'Extended (Application) Properties:' , PHP_EOL; -echo ' Category - ' , $objPHPExcel->getProperties()->getCategory() , PHP_EOL; -echo ' Company - ' , $objPHPExcel->getProperties()->getCompany() , PHP_EOL; -echo ' Manager - ' , $objPHPExcel->getProperties()->getManager() , PHP_EOL; +echo 'Extended (Application) Properties:' , EOL; +echo ' Category - ' , $objPHPExcel->getProperties()->getCategory() , EOL; +echo ' Company - ' , $objPHPExcel->getProperties()->getCompany() , EOL; +echo ' Manager - ' , $objPHPExcel->getProperties()->getManager() , EOL; -echo 'Custom Properties:' , PHP_EOL; +echo 'Custom Properties:' , EOL; $customProperties = $objPHPExcel->getProperties()->getCustomProperties(); foreach($customProperties as $customProperty) { $propertyValue = $objPHPExcel->getProperties()->getCustomPropertyValue($customProperty); $propertyType = $objPHPExcel->getProperties()->getCustomPropertyType($customProperty); echo ' ' , $customProperty , ' - (' , $propertyType , ') - '; if ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE) { - echo date('d-M-Y H:i:s',$propertyValue) , PHP_EOL; + echo date('d-M-Y H:i:s',$propertyValue) , EOL; } elseif ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN) { - echo (($propertyValue) ? 'TRUE' : 'FALSE') , PHP_EOL; + echo (($propertyValue) ? 'TRUE' : 'FALSE') , EOL; } else { - echo $propertyValue , PHP_EOL; + echo $propertyValue , EOL; } } // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) . " MB" , EOL; diff --git a/Tests/32chartreadwrite.php b/Tests/32chartreadwrite.php index 7b084f3f..614dc6e0 100644 --- a/Tests/32chartreadwrite.php +++ b/Tests/32chartreadwrite.php @@ -2,6 +2,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -52,25 +57,25 @@ foreach($inputFileNames as $inputFileName) { $inputFileNameShort = basename($inputFileName); if (!file_exists($inputFileName)) { - echo date('H:i:s') , " File " , $inputFileNameShort , ' does not exist' , PHP_EOL; + echo date('H:i:s') , " File " , $inputFileNameShort , ' does not exist' , EOL; continue; } - echo date('H:i:s') , " Load Test from $inputFileType file " , $inputFileNameShort , PHP_EOL; + echo date('H:i:s') , " Load Test from $inputFileType file " , $inputFileNameShort , EOL; $objReader = PHPExcel_IOFactory::createReader($inputFileType); $objReader->setIncludeCharts(TRUE); $objPHPExcel = $objReader->load($inputFileName); - echo date('H:i:s') , " Iterate worksheets looking at the charts" , PHP_EOL; + echo date('H:i:s') , " Iterate worksheets looking at the charts" , EOL; foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) { $sheetName = $worksheet->getTitle(); - echo 'Worksheet: ' , $sheetName , PHP_EOL; + echo 'Worksheet: ' , $sheetName , EOL; $chartNames = $worksheet->getChartNames(); if(empty($chartNames)) { - echo ' There are no charts in this worksheet' , PHP_EOL; + echo ' There are no charts in this worksheet' , EOL; } else { natsort($chartNames); foreach($chartNames as $i => $chartName) { @@ -80,12 +85,12 @@ foreach($inputFileNames as $inputFileName) { } else { $caption = 'Untitled'; } - echo ' ' , $chartName , ' - ' , $caption , PHP_EOL; + echo ' ' , $chartName , ' - ' , $caption , EOL; echo str_repeat(' ',strlen($chartName)+3); $groupCount = $chart->getPlotArea()->getPlotGroupCount(); if ($groupCount == 1) { $chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); - echo ' ' , $chartType , PHP_EOL; + echo ' ' , $chartType , EOL; } else { $chartTypes = array(); for($i = 0; $i < $groupCount; ++$i) { @@ -94,11 +99,11 @@ foreach($inputFileNames as $inputFileName) { $chartTypes = array_unique($chartTypes); if (count($chartTypes) == 1) { $chartType = 'Multiple Plot ' . array_pop($chartTypes); - echo ' ' , $chartType , PHP_EOL; + echo ' ' , $chartType , EOL; } elseif (count($chartTypes) == 0) { - echo ' *** Type not yet implemented' , PHP_EOL; + echo ' *** Type not yet implemented' , EOL; } else { - echo ' Combination Chart' , PHP_EOL; + echo ' Combination Chart' , EOL; } } } @@ -108,18 +113,19 @@ foreach($inputFileNames as $inputFileName) { $outputFileName = basename($inputFileName); - echo date('H:i:s') , " Write Tests to Excel2007 file " , PHP_EOL; + echo date('H:i:s') , " Write Tests to Excel2007 file " , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->setIncludeCharts(TRUE); $objWriter->save($outputFileName); - echo date('H:i:s') , " File written to " , $outputFileName , PHP_EOL; + echo date('H:i:s') , " File written to " , $outputFileName , EOL; $objPHPExcel->disconnectWorksheets(); unset($objPHPExcel); } // Echo memory peak usage -echo date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing files" , PHP_EOL; +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Tests/33chartcreate.php b/Tests/33chartcreate.php index 6da43d73..bc364d8c 100644 --- a/Tests/33chartcreate.php +++ b/Tests/33chartcreate.php @@ -2,6 +2,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -127,15 +132,16 @@ $objWorksheet->addChart($chart); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->setIncludeCharts(TRUE); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Tests/34chartupdate.php b/Tests/34chartupdate.php index 79b509fb..1cf7e2d4 100644 --- a/Tests/34chartupdate.php +++ b/Tests/34chartupdate.php @@ -2,6 +2,11 @@ /** Error reporting */ error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); +date_default_timezone_set('Europe/London'); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); @@ -38,16 +43,16 @@ set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); include 'PHPExcel.php'; if (!file_exists("33chartcreate.xlsx")) { - exit("Please run 33chartcreate.php first." . PHP_EOL); + exit("Please run 33chartcreate.php first." . EOL); } -echo date('H:i:s') , " Load from Excel2007 file" , PHP_EOL; +echo date('H:i:s') , " Load from Excel2007 file" , EOL; $objReader = PHPExcel_IOFactory::createReader("Excel2007"); $objReader->setIncludeCharts(TRUE); $objPHPExcel = $objReader->load("33chartcreate.xlsx"); -echo date('H:i:s') , " Update cell data values that are displayed in the chart" , PHP_EOL; +echo date('H:i:s') , " Update cell data values that are displayed in the chart" , EOL; $objWorksheet = $objPHPExcel->getActiveSheet(); $objWorksheet->fromArray( array( @@ -61,15 +66,16 @@ $objWorksheet->fromArray( ); // Save Excel 2007 file -echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +echo date('H:i:s') , " Write to Excel2007 format" , EOL; $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->setIncludeCharts(TRUE); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); -echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; // Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done -echo date('H:i:s') , " Done writing file" , PHP_EOL; +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; From 6c9a907027e9da9748d0dda74528959e02f9330c Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 6 Aug 2012 11:41:05 +0100 Subject: [PATCH 29/30] Bugfix: Work item 18145 - Autoshape being identified in twoCellAnchor when includeCharts is TRUE triggering load error --- Classes/PHPExcel/Reader/Excel2007.php | 45 ++++++++++++++------------- changelog.txt | 2 ++ 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 803b8bd1..a98a1061 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -51,7 +51,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader * * @var boolean */ - private $_readDataOnly = false; + private $_readDataOnly = FALSE; /** * Read charts that are defined in the workbook? @@ -59,7 +59,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader * * @var boolean */ - private $_includeCharts = false; + private $_includeCharts = FALSE; /** * Restrict which sheets should be loaded? @@ -67,28 +67,28 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader * * @var array of string */ - private $_loadSheetsOnly = null; + private $_loadSheetsOnly = NULL; /** * PHPExcel_Reader_IReadFilter instance * * @var PHPExcel_Reader_IReadFilter */ - private $_readFilter = null; + private $_readFilter = NULL; /** * PHPExcel_ReferenceHelper instance * * @var PHPExcel_ReferenceHelper */ - private $_referenceHelper = null; + private $_referenceHelper = NULL; /** * PHPExcel_Reader_Excel2007_Theme instance * * @var PHPExcel_Reader_Excel2007_Theme */ - private static $_theme = null; + private static $_theme = NULL; /** @@ -121,7 +121,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader * * @return PHPExcel_Reader_Excel2007 */ - public function setReadDataOnly($pValue = false) { + public function setReadDataOnly($pValue = FALSE) { $this->_readDataOnly = $pValue; return $this; } @@ -150,7 +150,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader * * @return PHPExcel_Reader_Excel2007 */ - public function setIncludeCharts($pValue = false) { + public function setIncludeCharts($pValue = FALSE) { $this->_includeCharts = (boolean) $pValue; return $this; } @@ -178,7 +178,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader * * @return PHPExcel_Reader_Excel2007 */ - public function setLoadSheetsOnly($value = null) + public function setLoadSheetsOnly($value = NULL) { $this->_loadSheetsOnly = is_array($value) ? $value : array($value); @@ -194,7 +194,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader */ public function setLoadAllSheets() { - $this->_loadSheetsOnly = null; + $this->_loadSheetsOnly = NULL; return $this; } @@ -342,11 +342,11 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader private static function _castToBool($c) { // echo 'Initial Cast to Boolean
'; - $value = isset($c->v) ? (string) $c->v : null; + $value = isset($c->v) ? (string) $c->v : NULL; if ($value == '0') { - return false; + return FALSE; } elseif ($value == '1') { - return true; + return TRUE; } else { return (bool)$c->v; } @@ -356,18 +356,18 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader private static function _castToError($c) { // echo 'Initial Cast to Error
'; - return isset($c->v) ? (string) $c->v : null;; + return isset($c->v) ? (string) $c->v : NULL; } // function _castToError() private static function _castToString($c) { // echo 'Initial Cast to String
'; - return isset($c->v) ? (string) $c->v : null;; + return isset($c->v) ? (string) $c->v : NULL; } // function _castToString() private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) { -// echo 'Formula
'; +// echo 'Formula
'; // echo '$c->f is '.$c->f.'
'; $cellDataType = 'f'; $value = "={$c->f}"; @@ -375,7 +375,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader // Shared formula? if (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') { -// echo 'SHARED FORMULA
'; +// echo 'SHARED FORMULA
'; $instance = (string)$c->f['si']; // echo 'Instance ID = '.$instance.'
'; @@ -384,7 +384,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader // print_r($sharedFormulas); // echo ''; if (!isset($sharedFormulas[(string)$c->f['si']])) { -// echo 'SETTING NEW SHARED FORMULA
'; +// echo 'SETTING NEW SHARED FORMULA
'; // echo 'Master is '.$r.'
'; // echo 'Formula is '.$value.'
'; $sharedFormulas[$instance] = array( 'master' => $r, @@ -394,7 +394,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader // print_r($sharedFormulas); // echo ''; } else { -// echo 'GETTING SHARED FORMULA
'; +// echo 'GETTING SHARED FORMULA
'; // echo 'Master is '.$sharedFormulas[$instance]['master'].'
'; // echo 'Formula is '.$sharedFormulas[$instance]['formula'].'
'; $master = PHPExcel_Cell::coordinateFromString($sharedFormulas[$instance]['master']); @@ -1408,7 +1408,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader } - // TODO: Make sure drawings and graph are loaded differently! +// TODO: Autoshapes from twoCellAnchors! if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $drawings = array(); @@ -1469,6 +1469,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader } $objDrawing->setWorksheet($docSheet); } else { + // ? Can charts be positioned with a oneCellAnchor ? $coordinates = PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1); $offsetX = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff); $offsetY = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff); @@ -1509,7 +1510,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); } $objDrawing->setWorksheet($docSheet); - } elseif($this->_includeCharts) { + } elseif(($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { $fromCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1); $fromOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff); $fromOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff); @@ -1733,7 +1734,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader } - private static function _readColor($color, $background=false) { + private static function _readColor($color, $background=FALSE) { if (isset($color["rgb"])) { return (string)$color["rgb"]; } else if (isset($color["indexed"])) { diff --git a/changelog.txt b/changelog.txt index 23b9a111..c0558021 100644 --- a/changelog.txt +++ b/changelog.txt @@ -99,6 +99,8 @@ Fixed in develop branch: - Bugfix: (MBaker) Fix to Excel5 Reader when cell annotations are defined before their referenced text objects - Bugfix: (MBaker) OOCalc Reader modified to process number-rows-repeated - Bugfix: (MBaker) Work item 18377 - Chart Title compatibility on Excel 2007 +- Bugfix: (MBaker) Work item 18146 - Chart Refresh returning cell reference rather than values +- Bugfix: (MBaker) Work item 18145 - Autoshape being identified in twoCellAnchor when includeCharts is TRUE triggering load error 2012-05-19 (v1.7.7): From 938ce8d51f0208410b6037be8d3cab4d5468ac6e Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 6 Aug 2012 22:40:24 +0100 Subject: [PATCH 30/30] Bugfix: Work item 18325 - v-type texts for series labels now recognised and parsed correctly --- Classes/PHPExcel/Chart/DataSeries.php | 10 +++++--- Classes/PHPExcel/Reader/Excel2007/Chart.php | 7 +++++ .../Functionality Cross-Reference.xls | Bin 37376 -> 37376 bytes changelog.txt | 1 + .../Classes/PHPExcel/Cell/DataTypeTest.php | 24 ++++++++++++++++++ 5 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/Cell/DataTypeTest.php diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index b58b4025..50e3a0f1 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -146,6 +146,7 @@ class PHPExcel_Chart_DataSeries if ((count($plotLabel) == 0) || (is_null($plotLabel[$keys[0]]))) { $plotLabel[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); } + $this->_plotLabel = $plotLabel; if ((count($plotCategory) == 0) || (is_null($plotCategory[$keys[0]]))) { $plotCategory[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); @@ -337,13 +338,16 @@ class PHPExcel_Chart_DataSeries public function refresh(PHPExcel_Worksheet $worksheet) { foreach($this->_plotValues as $plotValues) { - $plotValues->refresh($worksheet); + if ($plotValues !== NULL) + $plotValues->refresh($worksheet); } foreach($this->_plotLabel as $plotValues) { - $plotValues->refresh($worksheet); + if ($plotValues !== NULL) + $plotValues->refresh($worksheet); } foreach($this->_plotCategory as $plotValues) { - $plotValues->refresh($worksheet); + if ($plotValues !== NULL) + $plotValues->refresh($worksheet); } } diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index 865fb3d7..4a6981ca 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Chart.php +++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php @@ -305,6 +305,13 @@ class PHPExcel_Reader_Excel2007_Chart $seriesData['pointCount'] = count($seriesData['dataValues']); return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } elseif (isset($seriesDetail->v)) { + $seriesData = array( 'formatCode' => '@', + 'pointCount' => 1, + 'dataValues' => array((string) $seriesDetail->v) + ); + + return new PHPExcel_Chart_DataSeriesValues('String',NULL,'@',1,$seriesData['dataValues'],$marker,$smoothLine); } return null; } // function _chartDataSeriesValueSet() diff --git a/Documentation/Functionality Cross-Reference.xls b/Documentation/Functionality Cross-Reference.xls index 995ceeaa9d780cdd8e94e9384a0ac77f75e910e2..8df18cd5c3ae4463fd4b04050ff9e05d52984704 100644 GIT binary patch delta 2558 zcma)7&2Jk;6o0ecII(H%P=%o2P$i^snxt)F2WZlkrj7Hp_HJ!x%SRiE?bL~#qz;5! zs8Agtf#8CoOfN`9;*dWeV5#MR_&9(#1XNDF6p1SbIB-A#QHl3`^<<=}|jQ_k6OM zrJw*SP=O+>;X47H@Cg7s51R}>0LdV`fEHy~g=_c~JVX8qtucQP?jzA6{525D_jE`3 z6HU%&GpO@3O{9s|hO=-;1a+J?9McFzeAJ7$(?lynuZYeVjH+G~c3;p5I}mizneM3S zjy9c9q^t(|I_PAe)L}PuU2lGDFn;|MEj$q0`Gs(jp?EtCO>eb46WwlyZ>6%_$yH;3VuT&TL2hZ&t$YF^0&H@x)0XUTh`2H#n zE#0aQjqmC#SN|vV@#D39&?R<-MWID&g>H2DFZNUetfv8Xr~%g70E>HA4L~OD^FS9n z+yLuufDJUj1{+{U9>RuN;pjtPD;#Tp4G~uVZtgEu3&Ir8^a1YUAqc??47;;OB*(NM z(Bcgcqb9T>ds_T7ydmx5zXH6>*ng9;}R-Ys-JJ%J5CBszk)S0^gEfh|CA zM-`5WZ@`k|jv*(iO?jy5M$Inikei5#KY>Of*f8QLcS927fCU#^0?X~KHsO|=upqe%o=or5X7FVC zX8~oV<1FeN)Qkwq=St786yGZK*67gYP=pXmHqd?qvh~{w z5r*Kmi}t47N0S0i$8<6nRwe8rJD8c#Zha_2&EoxJg8-h}R*M@0yt@UTfxglhZ#|5Ym2&xwp-YJ2*QEfG;mGUDY%;Uc@?P{C+Q$p^zcMV! zE|2ea%#-8#alkqae0&c0!Kq)LsD!ln`u>^s@2y60Q0%)FN2}hBB)R_=d#DNaa1-p2 zCRlG1tgnGp0a^Ib2IymlnqZGL!TOtE15L2QcVMY@9JvE*$6ymI#j*OWGq<%+1UaPH z?XwS7v#qb=)02s22_74OD^?XQ9y@5(}6a)2XF*szhG*v8WocAIoqqDC z>S9#|Z_}b_5#&IS1aH^EisTLxHw)ecPtUs+g^suacp=_(mV896LBglKLT;ReImxBm zm^An0fn1G+6Ov3zQgB0r+BCl2D!3CFmwT3dxzKG`D6n4^x{q1lCzfY@Ldi2ssD-B` zH>_|^x?GW^O5KKyGb~@~896CEk1C!cgxYvsaw7^i>T)lz4@y1SDfSuVcux9_DSqRw z-;0tPSGWn6JI&&YJx{$PJtlpR8}vmx!oZrIplgr+=FllE|IIEe?qjt@Gw{F0#+**g zW}gsKbUN9aPCMInq9ZTM3R8XszHc<_v{SE0?zqBb3AJ&S-E#O&on!wv-PL(4NZ%R7 zmmdU+u3+&sW{LC9oqG^$y21rFr*Jtp&XHVB$;qcBj`NbE1BmIWf5t56ffHxJP*$e0 z3LYbiu10aPdHWVxl$ATIe!-}c< z$wzD#gfY*$miK!27J~FdfkJ6>^assertInternalType('array', $result); + $this->assertGreaterThan(0, count($result)); + $this->assertArrayHasKey('#NULL!', $result); + } + +}