Spreadsheet-XLSX-0.18/0000755000000000000000000000000014573141343013210 5ustar rootrootSpreadsheet-XLSX-0.18/t/0000755000000000000000000000000014573141340013450 5ustar rootrootSpreadsheet-XLSX-0.18/t/formats.xlsx0000644000000000000000000002646212612455202016052 0ustar rootrootPK![Content_Types].xml (Tn0W?DV@8t9H0@, PPH4zIog'mYDhM l洱T^z"BRVYHPGWl#^m19J`…R?*[%a'3g , j]P{%scEJ0"*7V d].:F@i,b 3)1r`4DU $v fD`7H3թ=聹!gk1gО]{&.έ.JՆTt7+4 ΣuU5gHdY7^e}vpZ#~[ :noy`)Iv6c73p>GPK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK! (xl/_rels/workbook.xml.rels (j0 }qne:A[&Q6'o?C@.$}?ЧjU%)Z(8>< ֶҝ`@CqNsD$%襤`)qm.cuy :itFQL w}_?(qkѐ#8̯ch}3"WTPs72 h<)"XUViTsIanaR`O"hUq4_RMk}P(DF'ؚ~ lܷR4Q~^%o_z:&M3DйBK[2<Ʀ[)|:wIggti.ݯMB]{v.ؕH/6`#>ٟ=hBMJPK!%Sxl/theme/theme1.xmlYOo6w tom'uرMniXS@I}úa0l+t&[HJKՇD"|#uڃC"$q۫]z>8h{wK cxLޜH]ś*$A>J%aACMʈJ&M;4Be tY>c~4$ &^ L1bma]ut(gZ[Wvr2u{`M,EF,2nQ%[NJeD >֗f}{7vtd%|JYw2Oڡ~J=L8-o|(<4 ժX}.@'d}.Fbo\C\ҼMT0 zSώt--g.—~?~xY'y92h!ы/ɋ>%mGEFD[t3q%'#qSgv 9feqwW@(^wdbh a8g.J pC*Xx8rbV`|XƻcǵYU3 Jݐ8b3+(QuK>QELKM2#'vi~ vlwu8+zHHJ:) ~L\E\O*t@G1lm~C*uG.R(:-ys^Di7QR8,b?SQ*q7C;+}ݧ;4pDZ K(NhwŘQ6㶷 [SYJ(p»g>X_xwu{\>k]Xy}钣M26PsFnJ'K,}䇦$Ǵ;@` >*8i"LI%\ xӕ=6u= r2f 3c (:jZ3sLs*UܚЅ ]M8kp6x"]$C<&>'eb. vJ|yXɾ8Ȯ]7R /=,.&'Qk5q&p(Kaݐ Sd›L17 jpSaS! 35'+ZzQ H )7 5)kdB|UtvaDξp|Fl&0_*3n'LE/pm&]8fIrS4d 7y` nίI R3U~cnrF:_*P}-p Tpl rۜ4LZéO !PLB]$K *++65vꦚeNƟf(MN1ߜ6&3(adE,Uz<{EUϲV)9Z[4^kd5!J?Q3qBoC~M m<.vpIYӦZY_p=al-Y}Nc͙ŋ4vjavl'S&A8|*~x1%M0g%<ҭPK!;m2KB#xl/worksheets/_rels/sheet1.xml.rels0ECx{օ CS7"Ubۗ{ep6<f,Ժch{-A8 -Iy0Ьjm_/N,}W:=RY}H9EbAwk}m PK!JK-xl/worksheets/sheet2.xmlPJ0 CMWY",m'm$YW޴eyyo^jĘ E }K} o۫{%5|cusyQ)Ӏ";TVRv@RA}f4E8"nZrV^txV?iqC$UO 3Ȧ0xLf1G⩫v;xC_8W2\&$J:YH:瞫"}mr2z%!~P4Jֈ2?g!_T *t*UQC˔'zlƭMq졼&Ntk巫 VEm,LнmFmL1Vť| Ti6ؗf &LH & 2 /-a`oaYEfdgQ-u5#r|T!jv4iQ;F3(|C%~xB$-"LvYd J\$xCegbP0[%^A>~9˿PK!n 'xl/printerSettings/printerSettings1.binW{82d$ %54aHÔ02cƥ E\(\(KP%6_ I:t"mmc"_r*ۥ?4*́T%$q*YyvHFqE&OURh~L~$ȡiF Ł;0צ3&Tczr_ zщ,.YV9ᶤfՓx daJbjg~1FAiR܆1=%Øן􄊳Ms7.8 :9TzuKLVbC+,'m?GWк._iF_ߺwzؙp(z}Fz#!8xEdCYLdz"o^[zm|:R/H^PA/7]~>;WFl{{)}d7is}v|E>&I0, AGϓ!bZXjCԫ2W"Τik sVeV7&} y3$6QΖïfdKkRCR j5U<~ 8op/ɇFGMȷ1CƼ1;CMga#vRRgT;:Nq@+۪.OJ;cBN}7u KPOj\DWva!%OYmg{B3f1*$XxQ;]K'2ohg?])=$UwQ9~B[oyMp_?:gD'x󙛻LSFM‚ny[(:ؖ/|roW CmRtN 8ֺH5GumY9 AJgPґes}=4ے({=/;I,6\zo#;PvSPv nQJ2Γ^6Yb_DEJ$跸?cKrJD܃%ٹ.NVCFx̚uF)j4#6*QŎ8.ƘxJѬ{"I.41WєhWA쩘j%{-&Rz*Z$ݳWc>qm;$).N^ ~E=%U1,l{ԸqtF4k^T\8l5Y_7 t/:4ܢb31cuXtB ns'y:.%s;i *۽ 3ޅKJ^Qc1h1oEKSU~HD;G \K7D%{M{x ;嗫 $\[]\|oE|\[wS3짵&&Mg9U| 4YƧu>0'mPЗobIZg,g _| 3g>| 0oPK!zGidocProps/core.xml (QO0MP nq D=LƷۈP>ܯ4YmZ!@Zr|"X&+k )jev}pEyQ -x$ *EkT!uŬ;=V=(  w@_DtB >"Շ.{J@ZI@ׂ̟2qVmt;e >h4M} S_/d+(K\ζ[oUK e m'BĒq _KqѡYyWeQHf> dAotu)qN4i<%Y/>GPK!oSdocProps/app.xml (Mo0  9iQ bHVAvgMc$Oe:|HIܝxW"g8K{>_}brA:@v'?~D2YpX(9G]CpdFQJ2^5ÉP^wC6:[__]HR|(R~3:ze_NsQ$=hT쵲IƲRAsA<ꇶS&-[cgۊe?BSVE%mL(5a,wy=4ಱ7Apx0d908o9{'տt~aP7or|zʶ9:j+>*i!EU2pvmo;B9)e#rZ f ~ PK-![Content_Types].xmlPK-!U0#L _rels/.relsPK-! (~xl/_rels/workbook.xml.relsPK-!9E]nxl/workbook.xmlPK-!%SJ xl/theme/theme1.xmlPK-!;m2KB#xl/worksheets/_rels/sheet1.xml.relsPK-!JK-xl/worksheets/sheet2.xmlPK-!JK-Hxl/worksheets/sheet3.xmlPK-!#Ixl/worksheets/sheet1.xmlPK-!Ŋwxl/sharedStrings.xmlPK-!K xl/styles.xmlPK-!n '<xl/printerSettings/printerSettings1.binPK-!zGi$docProps/core.xmlPK-!oS&docProps/app.xmlPKj)Spreadsheet-XLSX-0.18/t/missing_styles.xlsx0000644000000000000000000001462212612027633017451 0ustar rootrootPK> _rels/.relsJ1}{wDdЛH}a70u}{ZI~7CfGFoZ+{kW#VJ$cʪl n0\QX^:`dd{m]_dhVFw^F9W-(F/3ODSUNl/w{N([qTudocProps/core.xmlOO0~-C%6TNxkh\ ۀ*=mm1ݩ&قь0,%>p]h(5UPUL8CS/JS2NGK-RóqCp̜iu\â;z?GƱ:'VתþqS}PKJ@PK>docProps/app.xml=k0ཿB: k:8]Ή.UShڵ Β l攀WAa|((6x2 5 dR{zBkƲ:./Xtda]PgY#kU鷸QW6^c1v4>QþvWu8x3RUݲ[lky+oMOPKgPK>xl/_rels/workbook.xml.relsN0 {w ]x(ujm_:i8L;Ya)(:u v/w}`n+1')X5g>KӨcjAPy i4 h vǀm|}D/XH9)j0*}yMOO{wJ11L91r)y"? tGOPKr)X,?PK>xl/worksheets/sheet1.xmlVQo8 ~_aaO8q ]z 蚠nʒ'_8=H$E#OI}/dcVp4Ts0)ΤV0 f${mmt4̝+Ȧ9t 56s5Ȗ yT0Õ:D 7: Pvb@2\6%>'1I +>^ u4K,#PU4]d ujG> €C*6I> 2w\̾[NpY9S^1,0 F6k:H$aCyֺXLbAG;KIWk3A־o╌&hNmt3TM=TS.8#Ă} . OoH.'<8 \o|:z%F.wOhV+1Ҍ^M]-@ hAݴ^ (v`c"~i1?- {N-z7nOZZLzΈF(,=9GF٨/A:=pIx19Gvө>1NOlˋIC-tDMhu&txti>j߃ 6׊ɅcOm溠)*RP!fp:\ c]Ul9annJ@" j-q GlxCjU%E f-fWNfE sS?VSmBX _,*}ZvǙ%abEv_}{ Sa/n$:!u2ʻm|%Q'n?9PK6r( PK>xl/worksheets/sheet3.xmlUMo8 xinZ..Fn"BqXR=DΈzG#8|rsD̶_ߞs0Rh4P'݃^d/kh?B <Fںm!ӡFgDܶ&n~?Cam+ .LNtR*D-maR?$ws_Ya3tz~]ӾVr"஺DU_!ycRUqhB ޟK)?=*PnoDc?,Ç{< a-]4s&eC+E^Xl'm?PKiDPK>xl/worksheets/sheet2.xmlUMo8 xinZ..Fn"BqXR=DΈzG#8|rsD̶_ߞs0Rh4P'݃^d/kh?B <Fںm!ӡFgDܶ&n~?Cam+ .LNtR*D-maR?$ws_Ya3tz~]ӾVr"஺DU_!ycRUqhB ޟK)?=*PnoDc?,Ç{< a-]4s&eC+E^Xl'm?PKiDPK> xl/styles.xmlXQO0~߯>$iҴ8cG ~8Iӊj/<|9/s^L |e|gϧiCDBtKy)Ԧ! `z3c/Dɂ Iʉ{P$: 8 "FX.-L ܏,CEWDa*Ŋgl$ 3; )/ "v$^566(,1T) Pݟ얀zq4sE`08T }*ֆP\ ¿WݔpMq > g5,12NaC;c-j>.SDEN-nTeM͝Ʀ:yvQma9oZwk? IeR70;8*eu^IO)&grL-C^D| -F30k| ME+e,-3M؄.w3UUmQnbj1^>Ӌbz1rx|PjR3<(5CRsֈww"wyGty>=-7Lⅆ{Z975W-4ǻid%mA~[VT ˖d+~LkNvQCMDgգh0XPK;r8PK>xl/workbook.xmlRn0+k=la9͡4ir^+1E n]V>Dqwg83ŏΊhd1ɥ@6n]7RDz|(/V{6x+,5[DlVYցq(jۡI@ ck(WX|8cW`V/Qld6"mKX+<#QxI~C>=ԕd" GO JRI"[#' )TPH7N37uO͋r=M-/l:q􏩘<~Qx MڊABڙhjˢp#r` ]7'Yr3Z[9|).ɱch 8IvPK=FHPK>xl/sharedStrings.xmle 0 OQrwD'[ k:Lԧw"(l SwYX%(*ՁΧr SDh {0̢4X؀(EuYntΈF3_LBl9oPKތվ PK>[Content_Types].xml͔AK1KgɴXd[EDzI7CH9ݴM$]%FPd7-+0/t2(qJ1+)I**|7 |ĥ Jx8ڻ.1yIy8xZ|DhHiNP!4VڙO|OJʮj dıTx/FaD> =[as {Gq*138!$m) (әqG8'93=`oOvڋVY]B0w}9>+PKgiA9gPK>f; _rels/.relsPK>J@docProps/core.xmlPK>gdocProps/app.xmlPK>r)X,?xl/_rels/workbook.xml.relsPK>6r( xl/worksheets/sheet1.xmlPK>iDxl/worksheets/sheet3.xmlPK>iD xl/worksheets/sheet2.xmlPK>;r8 |xl/styles.xmlPK>=FHdxl/workbook.xmlPK>ތվ Qxl/sharedStrings.xmlPK>giA9g7[Content_Types].xmlPK Spreadsheet-XLSX-0.18/t/missing_styles.t0000644000000000000000000000027312612030570016705 0ustar rootrootuse Test::More tests => 1; use Test::NoWarnings; BEGIN { use Spreadsheet::XLSX; use warnings; my $fn = __FILE__; $fn =~ s{t$}{xlsx}; my $excel = Spreadsheet::XLSX->new($fn); }; Spreadsheet-XLSX-0.18/t/empty_v_tag.t0000644000000000000000000000027312612204553016153 0ustar rootrootuse Test::More tests => 1; use Test::NoWarnings; BEGIN { use Spreadsheet::XLSX; use warnings; my $fn = __FILE__; $fn =~ s{t$}{xlsx}; my $excel = Spreadsheet::XLSX->new($fn); }; Spreadsheet-XLSX-0.18/t/1_____loreyna126.t0000644000000000000000000000057512516012041016550 0ustar rootrootuse Test::More tests => 3; BEGIN { use Spreadsheet::XLSX; use warnings; my $fn = __FILE__; $fn =~ s{t$}{xlsx}; my $excel = Spreadsheet::XLSX -> new ($fn); ok (@{$excel -> {Worksheet}} == 3); ok ($excel -> {Worksheet} -> [0] -> {Name} eq 'POST_DSENDS'); ok ($excel -> {Worksheet} -> [0] -> {Cells} [112] [0] -> {Val} eq 'RCS Thrust Vector Uncertainties '); }; Spreadsheet-XLSX-0.18/t/0____________use.t0000644000000000000000000000100112516012041016653 0ustar rootroot# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl Spreadsheet-XLSC.t' ######################### # change 'tests => 1' to 'tests => last_test_to_print'; use Test::More tests => 2; BEGIN { use_ok ('Archive::Zip'); use_ok ('Spreadsheet::XLSX'); }; ######################### # Insert your test code below, the Test::More module is use()ed here so read # its man page ( perldoc Test::More ) for help writing this test script. Spreadsheet-XLSX-0.18/t/1_____loreyna126.xlsx0000644000000000000000000007400211105501576017310 0ustar rootrootPK!q9+p[Content_Types].xml (̔MN0H!%nj?Kؓƪc[g PTDQ4f|[d9g#NiCz*a|v~6}y-欌pJ`t6i5lDV,D"5<qFz,m k "RrkBKPN+Zjqg[ 2Y+wBMLDq}̨iKǡ]?wVoέNMUB}%-iփ@\J=IB̺iޛ1"o^AAGc,ER'?_rM?;67PK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK! (xl/_rels/workbook.xml.rels (j0 }qne:A[&Q6'o?C@.$}?ЧjU%)Z(8>< ֶҝ`@CqNsD$%襤`)qm.cuy Wo(A5ڻc^ C 9ZrJ-L=]IӎR2,{/ wOh:6@]nݽfyX3|]$ر.EDݠٟ +QKrr+,dg/3PK!%Sxl/theme/theme1.xmlYOo6w tom'uرMniXS@I}úa0l+t&[HJKՇD"|#uڃC"$q۫]z>8h{wK cxLޜH]ś*$A>J%aACMʈJ&M;4Be tY>c~4$ &^ L1bma]ut(gZ[Wvr2u{`M,EF,2nQ%[NJeD >֗f}{7vtd%|JYw2Oڡ~J=L8-o|(<4 ժX}.@'d}.Fbo\C\ҼMT0 zSώt--g.—~?~xY'y92h!ы/ɋ>%mGEFD[t3q%'#qSgv 9feqwW@(^wdbh a8g.J pC*Xx8rbV`|XƻcǵYU3 Jݐ8b3+(QuK>QELKM2#'vi~ vlwu8+zHHJ:) ~L\E\O*t@G1lm~C*uG.R(:-ys^Di7QR8,b?SQ*q7C;+}ݧ;4pDZ K(NhwŘQ6㶷 [SYJ(p»g>X_xwu{\>k]Xy}钣M26PsFnJ'K,}䇦$Ǵ;@` >*8i"LI%\ xӕ=6u= r2f 3c (:jZ3sLs*UܚЅ ]M8kp6x"]$C<&>'eb. vJ|yXɾ8Ȯ]7R /=,.&'Qk5q&p(Kaݐ Sd›L17 jpSaS! 35'+ZzQ H )7 5)kdB|UtvaDξp|Fl&0_*3n'LE/pm&]8fIrS4d 7y` nίI R3U~cnrF:_*P}-p Tpl rۜ4LZéO !PLB]$K *++65vꦚeNƟf(MN1ߜ6&3(adE,Uz<{EUϲV)9Z[4^kd5!J?Q3qBoC~M m<.vpIYӦZY_p=al-Y}Nc͙ŋ4vjavl'S&A8|*~x1%M0g%<ҭPK!JK-xl/worksheets/sheet2.xmlPJ0 CMWY",m'm$YW޴eyyo^jĘ E }K} o۫{%5|cusyQ)Ӏ";TVRv@RA}f4E8"nZrV^txV?iqC$UO 3Ȧ0xLf1G⩫v;xC_8Wp*+RV(|TV(PJSYB)#B)eRNeR :J)+RV#6!ƤB?;QjQcRV(PJYIJYB)e5&)eR ՘J)+RVcRV(PJYIJYB)e5&)eR ESF4_k,.(,AxضGq[TϾ+gJ +gJG+gJ+gJ+gJ+gJ+gʞįqTfxP$mn',t²I'v²I',tbn',t²I'v²I',tbn',t²I'v²I',tbn',t²y\ܦQaZ&qA\\$?ż=y z#1f:~"^,L3F'>}BTZ& #ω$CRPO|gzfto`F|cqg/+\%N,"c)@+v! nNk8aNipR_I} '5aQJ.SYņa6ruCiE:6-&F@4:)I:!AB3hIHݶ:Lm)tB')LȡiK:LqԖB')tJquKO4Je ѢcH‘G-[8ҿnѷpoHÙM[H`1qo#k3[8ҷp/Ǘ˄Wlg6,C܄ #q9&M˲;M05w07a$. 7a$nH췁 v#ī5cKܥ/qyoX]O7q;L4,nEp[IͰ8L27y<ze qZ)r8{Z<?!Y!Y$4k3Px^1jG #ع3u+r)鮞B51]eF>)-<ɭ\Zz K.Xdf/(tlӇZ[4;Bt؇(c` {7`wVnI(eҀ21\̒9.阎|L$(r=߷`Dc#DUS~'=LKFHe}y 4w|EY*68mNxZ[6 xi/z`d2In9-깣a)bC8oaĩ ˍ"emT4NdYGC;,NKTn vVaFe3F[z^JWܓanSYy SXө&_F6\Fʽޕ^?'45>U (fJh}F볼-1p.H0Z_`q$>NII UTHJEa6Ɨ}.6[O0oyAwNW1P#*j͢\ Z@'a0,eY"=zug9T6k^SqQǢٲڵQߍ4[B%O~ kŗ%ǞG^ ^9ϊ\'{7%Sziay>fp" A",ayz+Xhd+5 VZܟ| (_C+z ec%c5+@ $Ic5+vIAMd1V2noIAMd1V2IAMd1V2yė@j,&YҜ%i:t:+ Ekp ! mc1NRQZېjn`5BuUJF(i1xC17t1!7o(f741xCsRA@ !7o B5xcPCHAPjc 7ooYo ji1xcJ#A@ !7o B'|X"K^!F揃Wh,lfUs;zyAç<`>yK#LǾ!&dy-~?}9<+ܽg'R#am^~]V~%c1 ~|t< <'OOa>Q9<%Q\J1v` ;m^lHHzu(_{[|2i\޼YjiX"7ْxe7OWzP~itpy0~^.?.k3ݿn+%Y;OA47p s}PJկA_O>dfaaG֑6l4R^-:W覧ofwk(GTg0ex4nGz /zG !{t8_zm`WtR.1<:䱾&zok<;" ~o OgoB?66gÉo5c[\I#S̘ T=2Qznu!k,ۆV.Nݩq0m}d#/Nvk hUݎFnmຶ1p$p|'cUǒ 1ǔF1}ZxQ>prx +f}CP~Ħ`#fؤͫͩq|ͅ{MlfLe t}jj&MgՀil6Z6cj`sj6asgSb*S>55ILRĦj4j8l#5 >S̘8Ib$6_M=kxl^L 6R㰹p)1͌7>55ILRĦϚ"WoScRTl`؃;^P,\UglF"y-"YMZħH|:nb.s9[uv5Y|F|R絈|j*|ZħH|:\>+1`ޚpMdjI-""򩵪i5R#p'\΃ye7Y\^g'|^ȧ֪§H|Jħub.s9- dqyMѪ"y-"Z V#)5ׁϊ|r+1`pMdjI-""򩵪i5R#p'\>daoQ.Cpbtwz4̃kZ\R?=E XV 6}/txݱH{rta#V [wwf-Dѯ>t7Kq6ey9?|BHiTo>{x0~dQ5i=D꘮/^ .ڏ[o )xہlx%w+=:>{Bt~Աm{. K%t:owwm,Ht9vL{J_PK!~J<* xl/styles.xmlZ_o8?CN- RvCս 1`cG~)IIAP3f<363xHI1tKuɀa|wD.G2HԆɒR ݥRѻN'-iHKQeD1%ABz^&@qg&WB ~6o> \u ;,ޥ۱Ko(=EZCxE_ 5DzڷU^ͻFs)hp }Ts& !5wi̐lNB7f%R `Ǭ`Oʮ䜿8 Tr.1(2ncFK>~}e^R蚢s.)_b4ge:X$ls_Ɓ "JXI6Xc vP/boOH$gJyLBA-HDڅڮ(2 \H5h\1[,SJFR;~LчZ{R 0]E҈D77U* (TyඞrBaGnh02/]ݤ>0MU(/pJNZ.=:)-g RLpKEgJxPmH0+6УKF;F :9MIkkuc^hLI (ӫ b0co?fVK}Л4vc=е^ 7Vxư)-̶]ھK]BN~O[@{ȀmdP\ em>n җӱ-tNs ֥7)GD6ڊz;cL Ir9mʈtێ*ހRxP]$ܶi,T_Qm8&O%V=|{PSEU*LڹS={- ڢp=[?s:KYU:{UdsΘ\IOP{WD|c5W:ۼuͦ'N|;r }pVm!fZ%{#@%CD}:#mZMvA}qTM;ʙȥ">Z8<㨠 (vVZ}HxASuR+:G: ƎM.'4Ŝv 7V+&hc9_ Ov ߼ۏ'΄΅arq3';*@`%B%vd WٗC7L !cTQ*bamMI9PK!2Cxvxl/worksheets/sheet1.xml}]FPԻnhݷ|nt-ٞ{HY.O `_~~߾|뇗vy_>ϗw_~Ǐ?~y/?~}+O_w|凟^__>~_^?闟_>~\w]?~yko?_|폟oɡwx/|m?^?_~˻ڟ>dWw\K6HO/?;2 o*BgFۻ_o?__?姯үg)M˻_>{ӧe[oM>oi^gLɴ뗯)]/D-п/SsuMg~>_1eQ!,@`ƪ7|w%xcp ^kWC<.Q@sdfT,h!a-Һ.%b$x{|Oe-9#ZT> Ep C ]–)NI@8'n!lgh$(Z菜9ߖ8ǽH9,yq7EO6S~,m{c{O];\FLOȆq[:M^  Qj&N,;i|}܏}iH> S(lK&ȩ{K Qjbz$k(ɈfD[ 1*YN;[D6W=wXIgx%&!0s◧S- e)ԾmMWhVjk5sFrY0B)iF6U>ɕ{.-5}O˲rH_ zHf'Y娇l6{6)\娇6{R-D/!e 3ȆCfYB:utF6zǗղF6}ƗղF6ףRʮKKgdhltF65e ,[h[:#UFYB:p/օKf`[6c3:/Li;ynHIKHg€[:c>c?yɢPkg [>cvf )9CZ[ְ]h5apq?7"kkB{Z^c7=dlVrev⎍й2<鸇z[-MzN0!ŭVErlk $0[kՒ4_b5la24˶ۘGL4-|ʬMo!e Ycv"o!e nym"o!e niml#B۰Win46 ~᷐岅ܲ0;\0F/\0؆=sf9mb!la<6~){HqB؆/R\0S8dpxCJR4!e f)lص摶v-Sn)l ExC3KQdq\݁v-W^$8_q' !@{-M#dla|,C6Q Ukn)Ȇ9\GH# Y!pe!d fyl8}4- 6#dhcB&5$dhӐ%JTB6K!d fll3dlNu&!8gH%Y*!0!€Y&!kXTHϐILB65CBaim$#Y<ɒBslZ= 64pze8*po RV1[ҪV!OŴDU(,5=M.ʊ吽/ D9NJ;U吤/pq"Yuk{ {Hӓw/Va#W͔Ou~5# E:ID7x1]M]Usiρ*d/>gpF۸'@ t811D^uβsnשm/f! QWU_@$ %LPՏ-H4lE…\(''- BެX@]+:nGgy#/\ua>f,,:i°D^ 0)VsXdhǴ_djG>f6V+XW}5F_^uY1P՚NHjE5H(`h X<OYs%Ц``WȪ_>f w?9ǨjȡFē= 96' Y 5S$"b = H!d-ǎ }"P[ U-(TGnWSZfs*HUrqlБ"uR9VTd~ #@簌`8莧q[~轅yBpr5è+FGc+`tX{ʘ^Fd,u޼N`rs);p[ gGZ=:?Pg?Ȋam>QeDYu\P [eY+kr j R7f2$+PUub<h֗ '/^I֔A9fR*FIiV0#6:(f1km5B]9WP6MþR â' ˕|L/yN%YfiO(t&,(gtW\3zB'NȪ 2.7RPbOh)m~-lƸɨwS8̧ʣS\w9<:. 1 M hige蓥Qj tyP,1B2A^f1ǣwHiԂiUpLUsAH ]H]W$l{adt.ެDeX8K5/E\%|kx8Uͯd#\<ڷ}˷y=/2+e@1NUbت}W@GSkA)rUJ*;?ۉ?"uf[3(] rמT3Y[ *"@R Р4a2Unm?F.bbIuV2ۃP|ncB8SXŪr*k`E)J!@+&3k@ґ:%v!P<1^K_p 긅(1p K_*AIhӟ Z7@p*8urFub$)rVI6DlфHq s!jT#tjTb\" Fm/>,o1z;1sҧCQsZϸV\¶S0;2tŐ{j[h HGv q @ (ېv-ۢZӒJ;'V!8Uy{SSPyd' OELGm (AsYA+k P0}]4{oƬbj48 OGA*>0lcH5!]@" (0`"@,-8@١ ,VIL$PN:R!.ס.sBh&[蘆b@4]@*@Z@]HK7ӣ pNm +q3eYUGSE PR  *yk0+rcgVuaGDdDĚ\(3VD$"jA;Լ`d45!%']HKdxdZ7mÀa)wBZpHyYǫfXEnlԿ=Yێ A\CZ wЩDx!p ;WKiHWAQYw#3Ԍ5OqkXw)aB^> 1߱X; #S,څE mȊa::d ^P!áPh3mxd%θ kMV$+%wy yu|_Y 8:#bnIޑåf}3*oV  =^6څ9.hw-1+<{ ƕ˘Ȫ97 Te計9 )iZșA30f!V,+ sGsmwat9&%鉗͆C;dE┒S?ϕ,!:;B'a^H\0= +[ny!fRMH2>TĪd5WIUrcnba&=&''+DDJk՘\Śe5UdUp9暼c9*+TXlEY,=~ps$CFaUC,bWV (:b<3%Cyd*QѲ`,f!u&=\߿6ʘiH`Ӑ'DC*c6:!+1цPK]@(M {A%y[)sCzA<ʼn~=;ۇZk\YQ YU|nɦpwrȓ{Tƴ7㨆"GceopTc}}0㈸Qáq8u=?)G #\BNV5zcy-=Y,x4'9Wt`gVlX ~V$l{Ї&I$z 3HG苬j0\idap`Ek|GldUOY˺Ώ+usbpwNcb$}Ǔ^4{J)G _Wr?:[klW06Q3y };:#Ml-똰ɪtNNpZiE-77)PMUtԉP#g2w%kD0@]q YUKכ`^kOX3;7ݎu= xO@Wg ~tG= j\JVu.ޱēv rKCf!AŖtwܕW?f?j3؏ 3JE\'BiU D-*Qr<:@(1 YU6!@8 ԝY-}e 79UK|> R7' .BOcA(q}p٠8жI\]q H qm.nB<4'p|m8϶I\LUbU][U/>w7<_6OiOYמZ%{{v&OhW=jUbfp6έs>+&HX JgsqFM H:;AGfo<ֺȴ50R`zaMΘ:<ש\a g9fVJܲGD72q_ހki hpIt"p: h8KB8:#“q;:Ҙ{[)`ŕQ-)yl;qGφfq/ŗ[J";gn'6nAب Jjx@D|Ww#ltT|SfxƖ; : -nL 8н< z^¢ib.!d{8w@ }h iD!$FTׂUerZf`b;mXGŕLi+Ԟd\u0vY#i =n#*ɨtL4n=[WFqAi5O1lbfu !籅&ձYnn.5994k6fN 6n3D&>m)Ͳ8 D{wj21;\&/tƏ6nh10TL$a0t#J"(;T"lb# b5]B~⼪bGPvJ7f h8I7x1_㹊(cv"v1='4=AF͘#Rqp(H hlڽ(qyLۀu(Fueq4mj )t rD!c4ω96*R-77DZ%jvN2:=%>5qH`o@_иU8 Q[T,{s 3nkPI{0a>r>YנfX~TSM"A}r$Vf%O5tA PL-f@;cV>C_{*ɠ}.vȂ2:"E%YBFԱ $R,(wXU4Vc7[XN4f$>H_y܈)XCdgkPHdv%zZU Hisb+vɂ1X!HHNsr] o,hc$O-Mn3GIKNbFN2wTҳ_'G_ }e ӃJ Ku1 9!I2^"ֺ㔵Pz ULh4i$b"Cs|0R@dEu)dt/y(OCÄZ߿81d&y JwIbekd"yTY㫊R;,f6i \! ոq~itx|^ 31eY<ЃPiLq1Jї.cuj, )dbV/ \$Q7j.2{3Rv|ΧCo,[ kCrm)L/Od7΃@7|Eu䝊jqn>FD #/c| TQ.s]^E#y߿5cf Ȭm˕#fXδӉi 72?4{>p>N>߿z2cf rA|z;Y~0f2< ųR 9>֩#p=qFf5ci'7kZj_eX~NO%PY1MOHyn|vFf DxPV̕ηX)f ȬE&Vo?7#ӞyIiɍґgZd]%C4$fȌm⩤/C~ϊdKs3GtdNFt騍u_c 5elUdPO,}#Y@P_g!֦#sg x5+v33#ṉd ]YqNOn5$=7#pGf4 M|\R86VO>\c>q:7R RA8#Kq?/7#p'3۟tk::@:#Z$$Xsqe1݌A1~)$xJȠK)|g^䛣LG@jPC3 < -8O bb]-ڛ d<^ k{_6fd<E7Ҏ'8߫|jL<{(f! Aχ/,<3#&J#'bdrOCzqh7 jg|}lV#5d?w:=&3v+%vlie1p/ɬRf0G~wy~3 5h c~K咼yːŌBTwQ{c $Ha=1ܞ;\y㈹iZpֆO]4Q)҄@Ǽ~]w:ߌ@GPĄFHGhdVy]z zhxX Q5+J=,5qg8]>K bLo$>oஙV(eFϗ\=Gfwh۟G#]5'~%L\GB|:2qkxkt 5 Qoڟz5So  KjpV621=hxz2/eDv$7~*fK' o:SMl57idMOxgx4 'ڌS={+)M6q_$9qoH'i <{dHUA6Cw$i{f1QKaPʺCGGtr%[]݀̋q:60N;j#3J *x<1玀 {\8wd|ElQgRH, h92Yn>=).(>WM+ws O(YM8 =[|GxCCz5O o: _fwL㪎;0*k> AAY bLutqUuq[?j3*h#92/7h &Y|gqzLY4g4 qG fV;mE=nsGt ;w4˒01q?tlFfZX3;,1Kޠ H׭2˨iA渌{,(/f22Uqo`ܭ[QCsov\Ƈ51qN5ed0zVwFfY.2z WȼRYY;*\glzcp\Gf5CFϭ ϗX7ct6م 4PbtFf5=>5@``mI 4^ǥүŵ;NNMZ>tJ62?f7o3xQX>?HuwFWFoOl4P -v=! {òa ͱz ,uE@_Ziyݟ-[1NƤtItaz  BY2f^Ghli\n\ ql19Z2йM'godf3auY2pUdP6 x9iDŽ\b56}Py*m {x6dKȰ0IZ|zA*#K,nB73@ڡfyVeFWp^0(!dh|4ARV"%9ۊQbaozȌcg8qde<{0׺r>Tīt' ay@xN^{*ߵ찎!^#v}|10,muH dLm.t_8؍}>%餴$12c׶'=n k qS+tg,M=U>= GGð>8#i>x0~s^kksc ~q&1Z0zA{9 Ue h gˉf πq¹na8l] TcAy'gRL^O];qGA & Ȍe8S]pNSDŽ,z8~ҷDŽvUĭzI>21eIG513m}= mE]8=#H͙S(&SGO*NI>kC-i&#>` Vi㎥X.YY>X-3A}+Ơ#5 (, 00`EAC ELzy]URGuyQ~?|a0Bv}o&1z_y|5}ԭH|iљ䉜)jBt3EN̸Pv "uZH&9oqt.qTD_-[K,CmBaL&mAg$Hާn5],gό$edP6y?P^oiHwCN/q BTͼuql'hP !}RdSƗM3nfUv&y  -~Bys0y8Q xG$dcD;.:GP7s6+^ 5!,()Ͳ`5 >ą Xes|06)ZqB4˲>ymLIqr.}օUN3B焙*͠_JoT pD>ɠD~?p Of{0C00Cc] 8VL kgTˋ8rK.<*3/ Uem&L ̰ X&OAbk|=p!5駣ff-91ty(\帏SC&Sv!'U0) ؎H$,w6y$YJKUi| %Ĥ! )q9npfgPus>7<7nIi~t}7*Bj JQؙ 8nLJ"qcu<N_|Uwuؐ.a*WC8 ͸p!x`0&RP3gkPzy1AU"_hCX0ϝmE|c1GO(:,7b)dA]} Xb]y٧Յ c C3!]P-,?fB)]q"iW7ʍ)eG>x !\9ڀ oEfC~F9</ʐ_tIDla=~z]4 r:ߠls!xh,n&*1@B}dH$UeЬ7%5x*^.)|p)FߤX]?^۷~z9?]_~>?cc _o/{WtvO?7妿?=\E;OPK! 2BkdocProps/core.xml (_O0M¢XfO[bޚiiNƷ|=zMAV'[*CqDPעTE7pdE5嵁GSk0x cw Cyq[ɜ?k?X8!KpL0p HDG#RMP,{i蕉Sվ1- -Gc4Q3c1~]a]q@y*8MZł7ث"bŬ[oKwo"DѡIy?l(aLBrI%?滨Å<*O IZY`@v+߿D2YpX(8GBpdNQJ16^v/#= 'C69zziO!$`)>`Vn)=+\ d.<VX6"~.{PжDU|Jc[Bp ֫h5Mۀ_ <5L1cAތ )l &$\"V,CUA|3'& gPVϛCpˁi_mVk! q/*QM\E٪uZQ?}ZBɺUnoax7OE\5@PK-!q9+p[Content_Types].xmlPK-!U0#L |_rels/.relsPK-! (hxl/_rels/workbook.xml.relsPK-!M#kvxl/workbook.xmlPK-!%SB xl/theme/theme1.xmlPK-!JK-xl/worksheets/sheet2.xmlPK-!JK->xl/worksheets/sheet3.xmlPK-!gjJ?zxl/sharedStrings.xmlPK-!~J<* &xl/styles.xmlPK-!2Cxv_,xl/worksheets/sheet1.xmlPK-! 2BkodocProps/core.xmlPK-!6LrdocProps/app.xmlPK tSpreadsheet-XLSX-0.18/t/2_____with_chart.xlsx0000644000000000000000000002433111162235662017546 0ustar rootrootPK!싫[Content_Types].xml (UN0#(q[$Px4V򺯿ghF*%%;3;;LQ[q2bi6/_{aFHgWFTm0eys9ГR+\htǥ5LCf7ൂh!|x%}As'ǢǦNpRRηF`mi MI\I vS`*t EҀ "D{r1C֚Pe>aCw_X+;I)9>S&ק)P^(4! nq+P#HAC7}WB^&5|e-a^tC^\, g?oshښvEHz8? /WU.2PK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK!A^xl/_rels/workbook.xml.rels (J0nvut/"U)&%3v]Y^!fֵ5)Ȓ: W +u*`[\^lmzQőIIb)=ة|42Բkyeʼnؕ ®\}t[WUcޛ>"rաFV0];yAɗ1VAsp%q ~ff$ MQeq=ţXzIc<;PK!cXnxl/workbook.xmlRn0W?X˗ SS;Rبɀ)NVC<D3v0t6K?,2cGIRȠJ}U_PK!S!xl/chartsheets/sheet1.xmlMO0 Hwƾn4i$$uhM\9$rz;Oo;rt e9( %U.4673P1P֫ei hDֱؔM̨ ؛$!7:vVD{ AuJ|cH5IuV'giEKn\Zjl ]c/:QΦ|t?χ3b yv&J@Ze+Nzm547PK!,xl/worksheets/sheet2.xmlQMK0 0wKE\="~ fJ27mqD0y/o^Gk;`0IRJkrxy^,AVRYv$ETp!ܭ V:tɷc:.V^\8V?Tצ "M*ސXp3YdWѾҞ*qG/v*-7SqŴ*4tvڷQ`|P1.uC bNfx vLb .M@D6N_T|PK!֎ihxl/charts/chart1.xmlUQo0~Y؊*JjRM+ǎlC˪N}}}ﻋsyU2٣B ,Au.:c?gYbV-w'|=1!e'HTj5]ެ7{+C:*4 ;%NX0[$dO>U'Z=qMWG܄iʩ!ke TV`^DݭeE9ѧhq==.>aU%=DAF>YU3JG@k!XpIdz(pj9=&1 _-tq5u[!lӿg]{FTm\Sԑ#qDFΈ6<okR6-5O CsEx>IoJֱiv~?PK!܌xxl/drawings/drawing1.xmlSMo0 OrhhѤ 4i8l?KSI*'@s&8L\Ďsڔkgc>9SVL]??O6Y|- ѧzAט!T",?rt]! ڔt<^DB/ i=܀f@[w>+ ]r1'uQU&)83$e4i:!Tk.}#{؜%}+~"Y̧Yy`a]ւ8ogm"kQJ]>JI \_1p'I֭&-PO=` ٤hOf_{GT{lU h׬ScR޻pnTIԄ48uOPK!h Kf xl/styles.xmlSj0 macIv N[R}$Mӳd/GgAh<|Xr@t{Kq{EFFsGl^;@'N"mC#bT1%9+p/FV\LDvEVyC'#1UZSjGz HJNK$cl` QdD6a-(3ٯ b(Xdy*2k$4o[zD(# u*m6M軾> :qrNNM8AGq/F˲c}OLYwη{ "EגCHUMX,uJײs~Z=QqY9)~PK!&y Xxl/theme/theme1.xmlYMoE#F{oc'Gu&%ݢԳ;qRP{DBBTj%.H 3މ$i#P3׌x1tD[[Tkb=,JHvFǀG^hciUC\v@G<`5C@yaE˫}} oZo>txnx`3kkݜ0z^5gAU+KfYmg4 uvR\|ƒv]oXd֖FmgחNpd%|ZQs2Oڡ~J=L8-o|(<4 `}.H'd}Fbo\xc|! ~!+^=''<ѣ?XZ]ō/>B?r B_<ٓ_~۷K;!D1:f JNFb;!=:spmﮀQ9:Lηs\UpŬ;wǎk{f;!q<`8V8 1QHSBJGc} .D{1-5ɐ@Zlڥe^3ڱ]L.9r?$1M ˍm}[w|]筶 Wv06crzJPjȞ4n1âhN$?6%!|M 6{CA&Ȕt Q%r)mA]ٳa]lAX] 'czN` M6DAaVB[Ոfj-W,ք1Vn9] fdn;pt >z/jŊ)>a&" vKY/T:,F-Y_{I˛F x].|%l؟&lfIP k%:X64̫4X9Y`RFkH Ivt]K&⫢ +v1-|c4b3q:TA1p=a*~4mm-i ήc8-:ELpǹ V*Q⪘$Ua?SE/kp+0P!* Lh Yx A G9Kä5! ЏT(9d bմwY,%d" L#rDP !M5Iˀ?9͠Qb95$6&3(a3dE,vٞޢ"b̪eY kpVk+֒L8ưD >#&uCC~m l iG08EL5m::ie'ݜ)ck ;\vN.^S ;k+M =4N21槭oO|t݅;S$0ٺ'PK!죐xl/worksheets/sheet1.xmlRKo0#,Y'c*InU $x=¿gQB§g{ъ|0*o2)5W )ij* ߿+@\@4 I~[߫0ymz4ZUdٹqra3 `<ă` 5| ]%u!U]&,HBCrR`ħx3C3t!2 {4xd*_nS_8{%:l1z:ѤQpCl0L: vD*iR,ܼ/hŠIVho9$s} iɻt_ BV I3ЋimO?.\Á? pls"EH PK!DmdocProps/core.xml (IO0HYQ+I%@=QD+e"%Yʁ=><9D|J hZ(JNk%@Gh^^^L < lI sN-ہ6ō2:4[)[i`r(nh@r6"3 5$JׁρN8EwNٜ>j46M5YOVTf:ew7ڂ Ov5n7|8W9)jJoY^Ҙ\$M?۰b8#Y2!e>H PK!l xdocProps/app.xml (S0#[ePxjA{QٽOIkؑ=|ԛ6"@43oi,:A;[$gZ*m{,?|`Y g` N}#V޵Ic" s΃aaa(~]]kKgyVXݴ'B/iT/<6 t \s"h_.{F1(5gsSV`p5 7s):w,[m `/`x ܾ-%ش6"ǮqocC ؘ&Ni&kO+$Ac0I 8˿7/x/fRpM ;E-p؆ˢXchdjy >&y<ǕjPK-!싫[Content_Types].xmlPK-!U0#L _rels/.relsPK-!A^xl/_rels/workbook.xml.relsPK-!cXnxl/workbook.xmlPK-!,g xl/worksheets/sheet3.xmlPK-!D߼%# xl/drawings/_rels/drawing1.xml.relsPK-!<+$ xl/chartsheets/_rels/sheet1.xml.relsPK-!S! xl/chartsheets/sheet1.xmlPK-!,xl/worksheets/sheet2.xmlPK-!֎ihxl/charts/chart1.xmlPK-!܌xxl/drawings/drawing1.xmlPK-!h Kf xl/styles.xmlPK-!&y Xxl/theme/theme1.xmlPK-!죐Txl/worksheets/sheet1.xmlPK-!DmdocProps/core.xmlPK-!l x!docProps/app.xmlPK<$Spreadsheet-XLSX-0.18/t/3_____invalid_formular.t0000644000000000000000000000134414140565341020213 0ustar rootrootuse strict; use warnings; use Test::More; use Spreadsheet::XLSX; BEGIN { if( !$ENV{RELEASE_TESTING} ) { plan skip_all => 'these tests are for release candidate testing'; }else{ eval{ require Test::Warnings; Test::Warnings->import(('warning', ':no_end_test')); 1; } or do { plan skip_all => 'Skipping this test because Test::Warnings is not installed'; }; } } plan tests => 1; my $fn = __FILE__; $fn =~ s{t$}{xlsx}; my $warning = warning { my $excel = Spreadsheet::XLSX->new($fn); }; unlike( $warning, qr/isn't numeric/, 'got a "isn\'t numeric" warning when parsing the Excel file', ) or diag 'got warning(s): ', explain($warning); Spreadsheet-XLSX-0.18/t/3_____invalid_formular.xlsx0000644000000000000000000002167714140570234020756 0ustar rootrootPK!DJ[i [Content_Types].xml (N1&æW[`azS9,[A6lt4]1rfj Ie5{?VvkEbhHEʶT6F9 P<ڴҸ` ߰o;.hc; 6=b+MޑĊ.xH.ޡJ9Z&a0~ԡ[`&( B|0FO-"G(](҉I'PZhtʀ's0< / / pt|,cHq.}Y` _=:.p=JvԼݝ]vПcHGy~_PK!U0#L _rels/.rels (MO0 HݐBKwAH!T~I$ݿ'TG~PK!dqɸcxl/worksheets/sheet1.xmln0G;X VUz]3+P۹w MŤfW[4bJ[I(?%>pSqe t^/6-}/hB3Eȶ`S[yO`u~V, \'k)֊74wU;V(aC)"XxmqAA(i)>lʸHI2`-<ҿ\6`v|%~?I7Y%񄻪I~=l>MgP FBIמ.M1}r 73F Av7#%pcջBTP G4Jx^'h.@kĤY|@9>7nox)IO^6h7Vx;zDA5lKv1cUk zIJ!$"ARGx&Pdc(Jf ?_]=4k &ᓌ,Dǽ ^] p0IѫrbXt[~^=."~?_Z_3n:|D̝ܹ?gog11,P -8x{ fd/6$ΖXz'1c5d_ZGtn<[{Pj$x\(ͻq#S-{Hc2g3<$NkHFdlRitHFRmc6>>3Z j!?Z \PB!Hpcʜsnxm rjyӑ}v(YX94ֱ_S(Qe?f"!(ݙ\O%V*oyBKZ|jnw>:͈m:޻pAezk=g}O%{׻|B]j3v>Wdb}F(=+ZsChT l1\[7ϐq2&$">5; a&_v M=j&xp$v/شBY6NvkmHh$u#du$ȮE¢%ݯS&@mX29긁a(<\iwunK;'Gd IB+MqQaU]Ԡ'C~Jևȵ @S])hwܰy-: p,v\":]eqG<D'W9$WS 4U -6Fn&fx"k-2-(|֧Ғ-!'evA͚ p8ќ8YY&BvCDUCy;3.9\膎@+ x.'u/e4,LCUi7kI`K6RkB̺o0!h j K.ZMjW "fF]g~XrX+U᫏6~ч%\6d}q.<eF:/Q=*^+TUZAQA6j^W Zh][T'd}vm’*STR'a}n{a+~תWQ?GA=|:g wZE?$V~iQ«x PK! g6T xl/styles.xmlUk0~zweeij(l0H{Ul9Տ ə}';:ѾD;)]'3cV9nBt&_`uTThr|`e[ms ֹݜ[mF/6:ؚ ;hm!)H)+< e? vTZk.;XjQе]4Ĩ3$E+n 4b/ȌjD!E ;J 1lϽ|En1oYs*2OIUZhH=J6DS׆J.;^c{$qp qf{(21JؠtAz6qzZ&{Ud5s~՜n—2 (bBkV=9{p29 6`u5> ^о"}N9^w0;Gnp\2؄ksYC[s<ڟY[v=DG*J}ֹO VCp1 &, fb$rY8u_"5 s,XjA7@R}}$ 6IJ4M2e:Y<$er=yC(O>;.IK/ۿANJ PK! xl/metadata.xmldQKO1W?Xo!B(D%T(ձljUd{iVU{g8=5b޵t>)'nOjIIInMwpÊ$`y;G3qRedky]_2˵ 'Eɫ<2 g~8@7nOCD]FmwX| @5Z"|Fxʰ6Myc*{Ioyk5ɚ2_nSһ1q9D1 0?aЮQ}#%Ol8I[g+ۥR|%T|ZZԢ>h"z5|=15Z o  dKBw"f6`9wQbQsd2X NPK!ֱxl/calcChain.xmllK @ wS+HEO)̣LŅ@=xuSU MGi>E2 [.ZNQCdy5[GJ3E\SXdͣ9Jb]kU6p؀(XE6vPK!Ǟ)docProps/core.xml (QK0C{uCC=({R(4$nެۺt7{[#Sv]voQJt Es}UIe|dKWMy"l W7"_'X)(Q( TrR/ߍ% t`@XșM`L.HΥ^< zaȇr#˸*vWPS)9҃$v䭼h)(a:tֲ[xyQu? M:Jc,f Ӳ-(/|vi< :bPK!} docProps/app.xml (N0H) **BVRi2iul"ϳo‹1IT{>:xW, R>^މ,wX&?.: -\*Ğ(,L[H3+-q'}Ә |֢#y ]e2㢣5}XҴs%Ob VoСWT`q6PSA=!+ZIVco^ҕȶ^G ѷې(ECik?aTFe󡁃`aᜳ4d1=7k{`Gh-Sy7o _O~P [,y'5%OXPK-!DJ[i [Content_Types].xmlPK-!U0#L _rels/.relsPK-!W_xl/workbook.xmlPK-!2x:K xl/_rels/workbook.xml.relsPK-!dqɸc xl/worksheets/sheet1.xmlPK-!M?,~xl/theme/theme1.xmlPK-! g6T 3xl/styles.xmlPK-! xl/metadata.xmlPK-!ֱxl/calcChain.xmlPK-!Ǟ)docProps/core.xmlPK-!} docProps/app.xmlPK  Spreadsheet-XLSX-0.18/t/empty_v_tag.xlsx0000644000000000000000000003065212612204421016704 0ustar rootrootPK!t6Z[Content_Types].xml (Mn0zۊ zc±-@UI8ekHh/D/ E!g!)o  ]W{,DI_D]B0vOROC_aV 9Y/UZkoN 0[ &U9` @cLL `(YfArlai#>p?ߩu;5UUqvq;,e~Yڭi(([F|p\oi"mDȥJ`&ݻ->rzTrx|)D䩑z#ZWw" A" CzُD9O3̀9Ö PK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK!?xl/_rels/workbook.xml.rels (j0 EѾq2}PqfRm~p8Lb}kR:n1\ {$w$ύ $AV%ΒZ g],+0![)YדC=#$7i 3Oq(Cy Fӳp!Br8($2Y3>ĵД>J9C&×G6Da8XE5a4`c'Sii#wkBAO[1/ȳPK!p<xl/workbook.xmln0EB£HP_TJaLIy0Ьjm_/N,}W:=RY}H9EbAwk}m PK!tG|xl/theme/theme1.xmlYOoE#F{oc'vGuرhR-qN=' G$$DA\q@@VR>MԯNvM6!ٝ޼~Aկ 4aEc `BXsf/KCj{'aA^=^=rO=:y,qP\O#ӯ_>/_>B -$zœ_=y'}-҈HtCn0d$.bb!Ю S=Ǭ ! UP|+>Eni^ gqP\̊Cxwq츶7KnfAؾGcR=JS_p' ݣiItb./*ՎmgUZ# YC33*C ̅_Oq~ Ct>G.R(:9/"w(h)(F\U!K 8"-DDo`&*5ݩl3 urx[6lbUɳ{X/ Ko+ +\(PuCbmzG; elI|K؁} ͑G$G5Hp!U 4uO dJ:(NfCyO"tH1RX1ZlZJt{fu-ԹՍh*:rL5AЯYÁ32v>bp.!GZﲏIYz`Ч3Vd߀yTdX.ޛx)tdq19Y^72gT=̀(3p g&1Z'=Oz^,5AqM'E-\^_{4.&%Pa,o g@ʻ6rB~ ]?Ɛ9yHֱ3|>usԘ&Ͻ 9e`6'Co¿4A>:l[!dUUid"2nUUKVVY*B`ɪ%ݠUaX*B`ɪj"{֭X*BVEX]M8'W]yमG&vdln915NgNKTAT\ҨLjK4TǓk'jNCgT1]iMrb5Nccrj'jT&]gTzQNl%&b0iҐ L|Feb򞫖id>ɚLci(Pv N.Ysg`NFSy-K҅8,% G ]G&A> dKN]C>~3*rO8l UuqԠO<4{P<f^<,#Ȯzb%r׊КmۺtrjBjkCNFz>g+0ߑlSRMW>u}>]eUA@:(m_w qMsn =28K܍ǖ B`0X*$ B`B`ܷu=߃?X*ܷ,{([` cqc5nb `kl<1|=3'a( x des/?7`Dζl!;%ωn4l s-%(SOЩYaX;]!?YJ6 .XР0@VQ㐻s\>~Q  w0H@>{Sؗ_uF nGgb@ Fv2v&1u݉A H4 d.ntF} bȾ11!5M؍imM!dmM' 7*WsU3=/lC쮣NWwA& iq5Ȳ BvL+GɅĸ)D 31n,zG#{dzĄ4 /rSښrC;'ښr5OZmM٫ښrMtզS?ˉ]G1$xK䂀31Fp#vL+^:#9rH:"lEaKv 'Loz^4妚*3t rCL7jժ6\3ea\E3zMjА=TE͌7O4 w"ޥl)a{!g6F̔7c-Hg"fĘq;A1S=cƽ1@:91SF>O fDd b V>/g$BS#8Ε!|d< ^aFaX>u@ܭ(JX!GQd3E Q M6EJzG (G20+z6H^Be Sy;p@_7a, Hd^ "(_+MzaV&ir R )Եd 0Wb7ci Η)/C(/9WǷBɫ,"œG x(2>pG 9q!E: *{]27HYwF|fDOY/ݮ"(+"+Y\]Ar?^%*"H+A4 5U\5}Ee((:&[j67,3{Fs;!%aUP!~ٍGF*v,|Ň팿+yygя4mHfuLIH");-!ԐZM9ےߙ3z8sǗfi!vZ+2Yf4od3CO &JuPRĐ_5zBMso~+FWBLp ֞2cPy!v ƒ ;9:Z[ثZ?\)'{:(yc Bhk5i.Z,/Qr wij}YN惫;&'Ľi FfQ= E!wg>}nUd&?]*&\l:{|G[eJ)Ҭ+[Ї"B2l_*D?#w&PK!fHxl/worksheets/sheet1.xmlM0,@B X&JUӏc`-`j;ɦc>+mnᙙw^> 96Ru9 <*ew鷯cyWFu+z[]~45%HLNkk1#jhTTJ>2kR۰W岣#!oaJZpZf-S#T# iVNi~h`^[)2Xl͐TdDCӻ ٠w X~CBcP>D38"VaM-FCmDebϩ^iw>kr6!K[cntH ?5b|^.AkG.-[0gzK/Ty%OcsS (V!R9؝t|JXΥMԑ_/\Qo,&^'"(ZGZ^"Bn6=w'H1M Us;.qbڻp8cҌU 0$>!E1w6؀Q-07LcA\ި@6Pd=?'3jDLm{xoU'xNieqجRv~n]=SOzރ_5%JKiUj.-%5Rl{h|2N*{PK!YondocProps/core.xml (|QK0C{=9ZQ| LӒD{nEK8~=$b_S#Tf;G2FHkstE.&j k[7`qL4sa;$8L7G | 8%d+\r7R   0M(zsSFJCv:8{`l6i.FO[5VؕTR0a+nE= &rlQsWy{(> <Z[߮~pm PIISa7L]` ;U+/}Dg$&W%,|MnXOb2iIf,#b(?VPK!hؚxl/calcChain.xmldA 0Ewfo HӂOIۛq߇?b'e5vM@lyx]w')g7 v[gXGHVAVPK![$'xl/printerSettings/printerSettings1.bin얽JADB$"@ hڐDA|m} ;A|8,!FAc죁-"e,`N"-dL%g&(B~ $vMy7):٦@TiT0\U&K{|hեe[ךVv6 "Asy~^6YXԞ O#D^-/t:fǵ%03>N%ɄJi ִfˡ '`M͈2ED)dUC9u'fGjͰzXߋ;#g>֟]:|)BC7ϲr y[gՈ1qYrʆ+<4GŎ'n#Ĭ /1X9[J@ (%PJ@ (%PJ@ (%%oPK!ždocProps/app.xml (n0 (@VQzhqzWd:&KIgo+m#ɟ7> Y.26V.l .^| 1@!F)fl;v!%4g,VCu,G@ y0㢣5< U5s%Om[!~r6E5e?SQ1 Krt=ZYx%O_ҸZuRLW^6,Dg3o!-RҷipARFe󡁃`aᜳtK)0B8OtD8ܜgo\ejgT~*^΄-TǞBoY-緜Ԕ 6; BEGIN { use Spreadsheet::XLSX; use warnings; my $fn = __FILE__; $fn =~ s{t$}{xlsx}; my $excel = Spreadsheet::XLSX -> new ($fn); ok (@{$excel -> {Worksheet}} == 4); ok ($excel -> {Worksheet} -> [0] -> {Name} eq 'Tabelle1'); ok ($excel -> {Worksheet} -> [0] -> {Cells} [0] [0] -> {Val} == 1); ok ($excel -> {Worksheet} -> [0] -> {Cells} [0] [1] -> {Val} == 10); ok ($excel -> {Worksheet} -> [0] -> {Cells} [1] [0] -> {Val} == 2); ok ($excel -> {Worksheet} -> [0] -> {Cells} [1] [1] -> {Val} == 20); }; Spreadsheet-XLSX-0.18/t/formats.t0000644000000000000000000000177212615023727015322 0ustar rootrootuse Test::More tests => 10; BEGIN { use Spreadsheet::XLSX; use warnings; my $fn = __FILE__; $fn =~ s{t$}{xlsx}; my $excel = Spreadsheet::XLSX->new($fn); my $cells = $excel->{Worksheet}[0]{Cells}; ok ($cells->[0][0]->value() eq '2015-12-31', 'formatted date'); ok ($cells->[0][1]->value() eq '23:59', 'formatted time'); ok ($cells->[0][2]->value() eq '1.12', 'formatted default numeric'); ok ($cells->[0][2]->unformatted() eq '1.125', 'unformatted default numeric'); ok ($cells->[0][3]->value() eq '1.12', 'formatted 2-digit numeric'); ok ($cells->[0][3]->unformatted() eq '1.125', 'unformatted 2-digit numeric'); ok ($cells->[0][4]->value() eq 'Test', 'formatted default text'); ok ($cells->[0][4]->unformatted() eq 'Test', 'unformatted default text'); ok ($cells->[0][5]->value() eq '1.2345', 'formatted number in text field'); ok ($cells->[0][5]->unformatted() eq '1.2345', 'unformatted number in text field'); }; Spreadsheet-XLSX-0.18/t/kwalitee.t0000644000000000000000000000046514134573047015455 0ustar rootrootuse Test::More; BEGIN { plan skip_all => 'these tests are for release candidate testing' unless $ENV{RELEASE_TESTING}; } eval { require Test::Kwalitee; Test::Kwalitee->import('kwalitee_ok'); }; plan( skip_all => "Test::Kwalitee not installed: $@; skipping") if $@; kwalitee_ok(); done_testing; Spreadsheet-XLSX-0.18/Changes0000644000000000000000000000546214573140707014515 0ustar rootrootRevision history for Perl extension Spreadsheet::XLSX. 0.18 - fix RT #117166: unformatted date values can no longer be retrieved, thx to lherschi 0.17 - fix RT #139898: missing file from MANIFEST - fix RT #127829, #80565, #79016: [Warning] Argument "#N/A" isn't numeric in int 0.16 - added GitHub repository - fix RT #125112: Update module name in comments and POD - improve POD - improve kwalitee test 0.15 - revert a numeric formatting change which caused isssues with Spreadsheet::Read. 0.14 - change default date format to yyyy-mm-dd. This matches Spreadsheet::ParseExcel. - handle xml tag attributes in varying order (RT #86667, et.al.) 0.13 Sun May 16 13:08:12 MSD 2010 - ability to read xlsx from filehandle (RT #57483, thanks Sergey Pushkin) 0.12 Tue Oct 6 10:04:37 MSD 2009 - sheets are now detected by relations (xl/_rels/workbook.xml.rels), not numbers (RT #50236, thanks Pat Mariani) 0.11 Mon Oct 5 19:03:46 MSD 2009 - sheets numbering fixed (RT #50211, thanks endacoe) 0.1 Wed Mar 25 18:19:46 MSK 2009 - bypassing empty sheets (thanks Lukasz Wilun for an example with diagrams); - rich text within a cell (by Rob Polocz); 0.09 Mon Jan 26 09:57:04 MSK 2009 - fixed using of $1 after unsuccessful m// (thanks HMBRAND); 0.08 Mon Jan 5 18:07:57 MSK 2009 - Perl version requirement lowered (thanks HMBRAND) 0.07 Thu Dec 18 09:46:18 MSK 2008 - "Use of uninitialized value ..." warnings suppressed (thanks Gregor Herrmann) 0.04 Fri Nov 14 09:25:47 MSK 2008 - RE fixed for the case of opening with attributes (thanks Loreyna Yeung) 0.06 Tue Dec 16 18:06:17 MSK 2008 - files missed from MANIFEST and, therefore, from .tar.gz :-( Sorry, everybody! 0.05 Fri Dec 12 17:28:23 MSK 2008 - a lot of fixes by Rob Polocz (dependency on Spreadsheet::ParseExcel introduced): -- Added support for styles and formatted strings; -- create and use ParseExcel Workbook, Spreadsheet, and Cell objects; -- 1904 date convention support; -- empty tag support; -- received permission from the Spreadsheet::ParseExcel guys to leverage the formatting classes and check them in to this project. 0.03 Tue May 20 05:18:41 UTC 2008 - fixed the incorrect mapping for columns > AA (thanks JMELTZER http://rt.cpan.org/Public/Bug/Display.html?id=36013) - added support for r:id attribute (Ibid) 0.02 Mon May 12 07:02:31 UTC 2008 - fixed a bug with 1st dictionnary string (thanks SSIMMS: http://rt.cpan.org/Public/Bug/Display.html?id=35489) - prereq relaxed (thanx SSIMMS: http://rt.cpan.org/Public/Bug/Display.html?id=35490) 0.01 Thu Mar 13 09:41:52 2008 - original version; created by h2xs 1.23 with options -A -X -n Spreadsheet::XLSC --skip-exporter --skip-autoloader Spreadsheet-XLSX-0.18/META.json0000644000000000000000000000247114573141343014635 0ustar rootroot{ "abstract" : "Perl extension for reading MS Excel 2007 files.", "author" : [ "Dmitry Ovsyanko ", "Mike Blackwell 'Spreadsheet::XLSX', VERSION_FROM => 'lib/Spreadsheet/XLSX.pm', # finds $VERSION ABSTRACT_FROM => 'lib/Spreadsheet/XLSX.pm', # retrieve abstract from module AUTHOR => ['Dmitry Ovsyanko ', 'Mike Blackwell 'perl_5', PREREQ_PM => { 'Archive::Zip' => 1.18, 'Spreadsheet::ParseExcel' => 0, }, TEST_REQUIRES => { 'Test::More' => 0, 'Test::Warnings' => 0, 'Test::NoWarnings' => 0, }, META_MERGE => { resources => { repository => 'https://github.com/asb-capfan/Spreadsheet-XLSX', }, }, ); Spreadsheet-XLSX-0.18/lib/0000755000000000000000000000000014573141633013760 5ustar rootrootSpreadsheet-XLSX-0.18/lib/Spreadsheet/0000755000000000000000000000000014573141340016222 5ustar rootrootSpreadsheet-XLSX-0.18/lib/Spreadsheet/XLSX.pm0000644000000000000000000002621614573141221017363 0ustar rootrootpackage Spreadsheet::XLSX; use 5.006000; use strict; use warnings; use base 'Spreadsheet::ParseExcel::Workbook'; our $VERSION = '0.18'; use Archive::Zip; use Spreadsheet::ParseExcel; use Spreadsheet::XLSX::Fmt2007; ################################################################################ sub new { my ($class, $filename, $converter) = @_; my %shared_info; # shared_strings, styles, style_info, rels, converter $shared_info{converter} = $converter; my $self = bless Spreadsheet::ParseExcel::Workbook->new(), $class; my $zip = __load_zip($filename); $shared_info{shared_strings}= __load_shared_strings($zip, $shared_info{converter}); my ($styles, $style_info) = __load_styles($zip); $shared_info{styles} = $styles; $shared_info{style_info} = $style_info; $shared_info{rels} = __load_rels($zip); $self->_load_workbook($zip, \%shared_info); return $self; } sub _load_workbook { my ($self, $zip, $shared_info) = @_; my $member_workbook = $zip->memberNamed('xl/workbook.xml') or die("xl/workbook.xml not found in this zip\n"); $self->{SheetCount} = 0; $self->{FmtClass} = Spreadsheet::XLSX::Fmt2007->new; $self->{Flg1904} = 0; if ($member_workbook->contents =~ /date1904="1"/) { $self->{Flg1904} = 1; } foreach ($member_workbook->contents =~ /\<(.*?)\/?\>/g) { /^(\w+)\s+/; my ($tag, $other) = ($1, $'); my @pairs = split /\" /, $other; $tag eq 'sheet' or next; my $sheet = { MaxRow => 0, MaxCol => 0, MinRow => 1000000, MinCol => 1000000, }; foreach ($other =~ /(\S+=".*?")/gsm) { my ($k, $v) = split /=?"/; #" if ($k eq 'name') { $sheet->{Name} = $v; $sheet->{Name} = $shared_info->{converter}->convert($sheet->{Name}) if defined $shared_info->{converter}; } elsif ($k eq 'r:id') { $sheet->{path} = $shared_info->{rels}->{$v}; } } my $wsheet = Spreadsheet::ParseExcel::Worksheet->new(%$sheet); $self->{Worksheet}[$self->{SheetCount}] = $wsheet; $self->{SheetCount} += 1; } foreach my $sheet (@{$self->{Worksheet}}) { my $member_sheet = $zip->memberNamed("xl/$sheet->{path}") or next; my ($row, $col); my $parsing_v_tag = 0; my $s = 0; my $s2 = 0; my $sty = 0; foreach ($member_sheet->contents =~ /(\<.*?\/?\>|.*?(?=\<))/g) { if (/^\/) { $parsing_v_tag = 1; } elsif (/^<\/v>/) { $parsing_v_tag = 0; } elsif (length($_) && $parsing_v_tag) { my $v = $s ? $shared_info->{shared_strings}->[$_] : $_; if ($v eq "") { $v = ""; } my $type = "Text"; my $thisstyle = ""; if (not($s) && not($s2)) { $type = "Numeric"; if (defined $sty && defined $shared_info->{styles}->[$sty]) { $thisstyle = $shared_info->{style_info}->{$shared_info->{styles}->[$sty]}; if ($thisstyle =~ /\b(mmm|m|d|yy|h|hh|mm|ss)\b/) { $type = "Date"; } } } $sheet->{MaxRow} = $row if $sheet->{MaxRow} < $row; $sheet->{MaxCol} = $col if $sheet->{MaxCol} < $col; $sheet->{MinRow} = $row if $sheet->{MinRow} > $row; $sheet->{MinCol} = $col if $sheet->{MinCol} > $col; if ($v =~ /(.*)E\-(.*)/gsm && $type eq "Numeric") { $v = $1 / (10**$2); # this handles scientific notation for very small numbers } my $cell = Spreadsheet::ParseExcel::Cell->new( Val => $v, Format => $thisstyle, Type => $type ); $cell->{_Value} = $self->{FmtClass}->ValFmt($cell, $self); if ($type eq "Date") { if ($v < 1) { #then this is Excel time field $cell->{Type} = "Text"; $cell->{Val} = $cell->{_Value}; } } $sheet->{Cells}[$row][$col] = $cell; } } $sheet->{MinRow} = 0 if $sheet->{MinRow} > $sheet->{MaxRow}; $sheet->{MinCol} = 0 if $sheet->{MinCol} > $sheet->{MaxCol}; } return $self; } # Convert cell name in the format AA1 to a row and column number. sub __decode_cell_name { my ($letter1, $letter2, $digits) = @_; my $col = ord($letter1) - 65; if ($letter2) { $col++; $col *= 26; $col += (ord($letter2) - 65); } my $row = $digits - 1; return ($row, $col); } sub __load_shared_strings { my ($zip, $converter) = @_; my $member_shared_strings = $zip->memberNamed('xl/sharedStrings.xml'); my @shared_strings = (); if ($member_shared_strings) { my $mstr = $member_shared_strings->contents; $mstr =~ s//<\/t>/gsm; # this handles an empty t tag in the xml foreach my $si ($mstr =~ /(.*?)<\/si/gsm) { my $str; foreach my $t ($si =~ /(.*?)<\/t/gsm) { $t = $converter->convert($t) if defined $converter; $str .= $t; } push @shared_strings, $str; } } return \@shared_strings; } sub __load_styles { my ($zip) = @_; my $member_styles = $zip->memberNamed('xl/styles.xml'); my @styles = (); my %style_info = (); if ($member_styles) { my $formatter = Spreadsheet::XLSX::Fmt2007->new(); foreach my $t ($member_styles->contents =~ /xf\ numFmtId="([^"]*)"(?!.*\/cellStyleXfs)/gsm) { #" push @styles, $t; } my $default = $1 || ''; foreach my $t1 (@styles) { $member_styles->contents =~ /numFmtId="$t1" formatCode="([^"]*)/; my $formatCode = $1 || ''; if ($formatCode eq $default || not($formatCode)) { if ($t1 == 9 || $t1 == 10) { $formatCode = '0.00000%'; } elsif ($t1 == 14) { $formatCode = 'yyyy-mm-dd'; } else { $formatCode = ''; } # $formatCode = $formatter->FmtStringDef($t1); } $style_info{$t1} = $formatCode; $default = $1 || ''; } } return (\@styles, \%style_info); } sub __load_rels { my ($zip) = @_; my $member_rels = $zip->memberNamed('xl/_rels/workbook.xml.rels') or die("xl/_rels/workbook.xml.rels not found in this zip\n"); my %rels = (); foreach ($member_rels->contents =~ /\/g) { my ($id, $target); ($id) = /Id="(.*?)"/; ($target) = /Target="(.*?)"/; if (defined $id and defined $target) { $rels{$id} = $target; } } return \%rels; } sub __load_zip { my ($filename) = @_; my $zip = Archive::Zip->new(); if (ref $filename) { $zip->readFromFileHandle($filename) == Archive::Zip::AZ_OK or die("Cannot open data as Zip archive"); } else { $zip->read($filename) == Archive::Zip::AZ_OK or die("Cannot open $filename as Zip archive"); } return $zip; } 1; __END__ =head1 NAME Spreadsheet::XLSX - Perl extension for reading MS Excel 2007 files. =head1 SYNOPSIS use Text::Iconv; my $converter = Text::Iconv->new("utf-8", "windows-1251"); # Text::Iconv is not really required. # This can be any object with the convert method. Or nothing. use Spreadsheet::XLSX; my $excel = Spreadsheet::XLSX->new('test.xlsx', $converter); foreach my $sheet (@{$excel->{Worksheet}}) { printf("Sheet: %s\n", $sheet->{Name}); $sheet->{MaxRow} ||= $sheet->{MinRow}; foreach my $row ($sheet->{MinRow} .. $sheet->{MaxRow}) { $sheet->{MaxCol} ||= $sheet->{MinCol}; foreach my $col ($sheet->{MinCol} .. $sheet->{MaxCol}) { my $cell = $sheet->{Cells}[$row][$col]; if ($cell) { printf("( %s , %s ) => %s\n", $row, $col, $cell->{Val}); } } } } =head1 DESCRIPTION This module is a (quick and dirty) emulation of L for Excel 2007 (.xlsx) file format. It supports styles and many of Excel's quirks, but not all. It populates the classes from L for interoperability; including Workbook, Worksheet, and Cell. =head1 SEE ALSO =over 2 =item L This module (Spradsheet::XLSX) has some serious issues with the way it uses regexs for parsing the XML. I would strongly encourage switching to L which takes a more reliable approach. =item L, L =item L =item L =item L for xlscat likewise functionality (Excel only) =item Spreadsheet::ConvertAA for an alternative set of C / C pair =item L offers a Pure Perl implementation of a spreadsheet engine. Users that want this format to be supported in L are hereby motivated to offer patches. It's not high on my todo-list. =item xls2csv L offers an alternative for my C, in the xls2csv tool, but this tool focusses on character encoding transparency, and requires some other modules. =item L read the data from a spreadsheet (interface module) =back =head1 AUTHOR Dmitry Ovsyanko, Edo@eludia.ruE, http://eludia.ru/wiki/ Patches by: Steve Simms Joerg Meltzer Loreyna Yeung Rob Polocz Gregor Herrmann H.Merijn Brand endacoe Pat Mariani Sergey Pushkin =head1 ACKNOWLEDGEMENTS Thanks to TrackVia Inc. (http://www.trackvia.com) for paying for Rob Polocz working time. =head1 COPYRIGHT AND LICENSE Copyright (C) 2008 by Dmitry Ovsyanko This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available. =cut Spreadsheet-XLSX-0.18/lib/Spreadsheet/XLSX/0000755000000000000000000000000014573141633017025 5ustar rootrootSpreadsheet-XLSX-0.18/lib/Spreadsheet/XLSX/Utility2007.pm0000644000000000000000000010756214573141246021352 0ustar rootroot# This code is adapted for Excel 2007 from: # Spreadsheet::XLSX::Utility # by Kawai, Takanori (Hippo2000) 2001.2.2 # This Program is ALPHA version. #============================================================================== # Spreadsheet::XLSX::Utility2007; #============================================================================== package Spreadsheet::XLSX::Utility2007; use strict; use warnings; require Exporter; use vars qw(@ISA @EXPORT_OK); @ISA = qw(Exporter); @EXPORT_OK = qw(ExcelFmt LocaltimeExcel ExcelLocaltime col2int int2col sheetRef xls2csv); our $VERSION = '0.18'; my $sNUMEXP = '(^[+-]?\d+(\.\d+)?$)|(^[+-]?\d+\.?(\d*)[eE][+-](\d+))$'; #------------------------------------------------------------------------------ # ExcelFmt (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ sub ExcelFmt { my ($sFmt, $iData, $i1904, $sType) = @_; my $sCond; my $sWkF = ''; my $sRes = ''; $sFmt = unescape_HTML($sFmt); #1. Get Condition if ($sFmt =~ /^\[([<>=][^\]]+)\](.*)$/) { $sCond = $1; $sFmt = $2; } $sFmt =~ s/_/ /g; my @sFmtWk; my $sFmtObj; my $iFmtPos = 0; my $iDblQ = 0; my $iQ = 0; foreach my $sWk (split //, $sFmt) { if ($iDblQ or $iQ) { $sFmtWk[$iFmtPos] .= $sWk; $iDblQ = 0 if ($sWk eq '"'); $iQ = 0; next; } if ($sWk eq ';') { $iFmtPos++; next; } elsif ($sWk eq '"') { $iDblQ = 1; } elsif ($sWk eq '!') { $iQ = 1; } elsif ($sWk eq '\\') { $iQ = 1; # next; } elsif ($sWk eq '(') { #Skip? next; } elsif ($sWk eq ')') { #Skip? next; } $sFmtWk[$iFmtPos] .= $sWk; } #Get FmtString if (scalar(@sFmtWk) > 1) { if ($sCond) { $sFmtObj = $sFmtWk[((eval(qq/"$iData" $sCond/)) ? 0 : 1)]; } else { my $iWk = ($iData =~ /$sNUMEXP/) ? $iData : 0; # $iData = abs($iData) if($iWk !=0); if (scalar(@sFmtWk) == 2) { $sFmtObj = $sFmtWk[(($iWk >= 0) ? 0 : 1)]; } elsif (scalar(@sFmtWk) == 3) { $sFmtObj = $sFmtWk[(($iWk > 0) ? 0 : (($iWk < 0) ? 1 : 2))]; } else { if ($iData =~ /$sNUMEXP/) { $sFmtObj = $sFmtWk[(($iWk > 0) ? 0 : (($iWk < 0) ? 1 : 2))]; } else { $sFmtObj = $sFmtWk[3]; } } } } else { $sFmtObj = $sFmtWk[0]; } my $sColor; if ($sFmtObj =~ /^(\[[^hm\[\]]*\])/) { $sColor = $1; $sFmtObj = substr($sFmtObj, length($sColor)); chop($sColor); $sColor = substr($sColor, 1); } #print "FMT:$sFmtObj Co:$sColor\n"; #3.Build Data my $iFmtMode = 0; #1:Number, 2:Date my $i = 0; my $ir = 0; my $sFmtWk; my @aRep = (); my $sFmtRes = ''; my $iFflg = -1; my $iRpos = -1; my $iCmmCnt = 0; my $iBunFlg = 0; my $iFugouFlg = 0; my $iPer = 0; my $iAm = 0; my $iSt; while ($i < length($sFmtObj)) { $iSt = $i; my $sWk = substr($sFmtObj, $i, 1); if ($sWk !~ /[#0\+\-\.\?eE\,\%]/) { if ($iFflg != -1) { push @aRep, [substr($sFmtObj, $iFflg, $i - $iFflg), $iRpos, $i - $iFflg]; $iFflg = -1; } } if ($sWk eq '"') { $iDblQ = $iDblQ ? 0 : 1; $i++; next; } elsif ($sWk eq '!') { $iQ = 1; $i++; next; } elsif ($sWk eq '\\') { if ($iQ == 1) { } else { $iQ = 1; $i++; next; } } #print "WK:", ord($sWk), " $iFmtMode \n"; #print "DEF1: $iDblQ DEF2: $iQ\n"; if ((defined($iDblQ) and ($iDblQ)) or (defined($iQ) and ($iQ))) { $iQ = 0; if ( ($iFmtMode != 2) and ( (substr($sFmtObj, $i, 2) eq "\x81\xA2") || (substr($sFmtObj, $i, 2) eq "\x81\xA3") || (substr($sFmtObj, $i, 2) eq "\xA2\xA4") || (substr($sFmtObj, $i, 2) eq "\xA2\xA5")) ) { #print "PUSH:", unpack("H*", substr($sFmtObj, $i, 2)), "\n"; push @aRep, [substr($sFmtObj, $i, 2), length($sFmtRes), 2]; $iFugouFlg = 1; $i += 2; } else { $i++; } } elsif ( ($sWk =~ /[#0\+\.\?eE\,\%]/) || ( ($iFmtMode != 2) and (($sWk eq '-') || ($sWk eq '(') || ($sWk eq ')'))) ) { $iFmtMode = 1 unless ($iFmtMode); if (substr($sFmtObj, $i, 1) =~ /[#0]/) { if (substr($sFmtObj, $i) =~ /^([#0]+)([\.]?)([0#]*)([eE])([\+\-])([0#]+)/) { push @aRep, [substr($sFmtObj, $i, length($&)), $i, length($&)]; $i += length($&); } else { if ($iFflg == -1) { $iFflg = $i; $iRpos = length($sFmtRes); } } } elsif (substr($sFmtObj, $i, 1) eq '?') { if ($iFflg != -1) { push @aRep, [substr($sFmtObj, $iFflg, $i - $iFflg + 1), $iRpos, $i - $iFflg + 1]; } $iFflg = $i; while ($i < length($sFmtObj)) { if (substr($sFmtObj, $i, 1) eq '/') { $iBunFlg = 1; } elsif (substr($sFmtObj, $i, 1) eq '?') { ; } else { if (($iBunFlg) && (substr($sFmtObj, $i, 1) =~ /[0-9]/)) { ; } else { last; } } $i++; } $i--; push @aRep, [substr($sFmtObj, $iFflg, $i - $iFflg + 1), length($sFmtRes), $i - $iFflg + 1]; $iFflg = -1; } elsif (substr($sFmtObj, $i, 3) =~ /^[eE][\+\-][0#]$/) { if (substr($sFmtObj, $i) =~ /([eE])([\+\-])([0#]+)/) { push @aRep, [substr($sFmtObj, $i, length($&)), $i, length($&)]; $i += length($&); } $iFflg = -1; } else { if ($iFflg != -1) { push @aRep, [substr($sFmtObj, $iFflg, $i - $iFflg), $iRpos, $i - $iFflg]; $iFflg = -1; } if (substr($sFmtObj, $i, 1) =~ /[\+\-]/) { push @aRep, [substr($sFmtObj, $i, 1), length($sFmtRes), 1]; $iFugouFlg = 1; } elsif (substr($sFmtObj, $i, 1) eq '.') { push @aRep, [substr($sFmtObj, $i, 1), length($sFmtRes), 1]; } elsif (substr($sFmtObj, $i, 1) eq ',') { $iCmmCnt++; push @aRep, [substr($sFmtObj, $i, 1), length($sFmtRes), 1]; } elsif (substr($sFmtObj, $i, 1) eq '%') { $iPer = 1; } elsif ((substr($sFmtObj, $i, 1) eq '(') || (substr($sFmtObj, $i, 1) eq ')')) { push @aRep, [substr($sFmtObj, $i, 1), length($sFmtRes), 1]; $iFugouFlg = 1; } } $i++; } elsif ($sWk =~ /[ymdhsapg]/) { $iFmtMode = 2 unless ($iFmtMode); if (substr($sFmtObj, $i, 5) =~ /am\/pm/i) { push @aRep, ['am/pm', length($sFmtRes), 5]; $iAm = 1; $i += 5; } elsif (substr($sFmtObj, $i, 3) =~ /a\/p/i) { push @aRep, ['a/p', length($sFmtRes), 3]; $iAm = 1; $i += 3; } elsif (substr($sFmtObj, $i, 5) eq 'mmmmm') { push @aRep, ['mmmmm', length($sFmtRes), 5]; $i += 5; } elsif ((substr($sFmtObj, $i, 4) eq 'mmmm') || (substr($sFmtObj, $i, 4) eq 'dddd') || (substr($sFmtObj, $i, 4) eq 'yyyy') || (substr($sFmtObj, $i, 4) eq 'ggge')) { push @aRep, [substr($sFmtObj, $i, 4), length($sFmtRes), 4]; $i += 4; } elsif ((substr($sFmtObj, $i, 3) eq 'mmm') || (substr($sFmtObj, $i, 3) eq 'yyy')) { push @aRep, [substr($sFmtObj, $i, 3), length($sFmtRes), 3]; $i += 3; } elsif ((substr($sFmtObj, $i, 2) eq 'yy') || (substr($sFmtObj, $i, 2) eq 'mm') || (substr($sFmtObj, $i, 2) eq 'dd') || (substr($sFmtObj, $i, 2) eq 'hh') || (substr($sFmtObj, $i, 2) eq 'ss') || (substr($sFmtObj, $i, 2) eq 'ge')) { if ( (substr($sFmtObj, $i, 2) eq 'mm') && ($#aRep >= 0) && (($aRep[$#aRep]->[0] eq 'h') or ($aRep[$#aRep]->[0] eq 'hh'))) { push @aRep, ['mm', length($sFmtRes), 2, 'min']; } else { push @aRep, [substr($sFmtObj, $i, 2), length($sFmtRes), 2]; } if ((substr($sFmtObj, $i, 2) eq 'ss') && ($#aRep > 0)) { if ( ($aRep[$#aRep - 1]->[0] eq 'm') || ($aRep[$#aRep - 1]->[0] eq 'mm')) { push(@{$aRep[$#aRep - 1]}, 'min'); } } $i += 2; } elsif ((substr($sFmtObj, $i, 1) eq 'm') || (substr($sFmtObj, $i, 1) eq 'd') || (substr($sFmtObj, $i, 1) eq 'h') || (substr($sFmtObj, $i, 1) eq 's')) { if ( (substr($sFmtObj, $i, 1) eq 'm') && ($#aRep >= 0) && (($aRep[$#aRep]->[0] eq 'h') or ($aRep[$#aRep]->[0] eq 'hh'))) { push @aRep, ['m', length($sFmtRes), 1, 'min']; } else { push @aRep, [substr($sFmtObj, $i, 1), length($sFmtRes), 1]; } if ((substr($sFmtObj, $i, 1) eq 's') && ($#aRep > 0)) { if ( ($aRep[$#aRep - 1]->[0] eq 'm') || ($aRep[$#aRep - 1]->[0] eq 'mm')) { push(@{$aRep[$#aRep - 1]}, 'min'); } } $i += 1; } } elsif ((substr($sFmtObj, $i, 3) eq '[h]')) { push @aRep, ['[h]', length($sFmtRes), 3]; $i += 3; } elsif ((substr($sFmtObj, $i, 4) eq '[mm]')) { push @aRep, ['[mm]', length($sFmtRes), 4]; $i += 4; } elsif ($sWk eq '@') { push @aRep, ['@', length($sFmtRes), 1]; $i++; } elsif ($sWk eq '*') { push @aRep, [substr($sFmtObj, $i, 1), length($sFmtRes), 1]; } else { $i++; } $i++ if ($i == $iSt); #No Format match $sFmtRes .= substr($sFmtObj, $iSt, $i - $iSt); } #print "FMT: $iRpos ",$sFmtRes, "\n"; if ($iFflg != -1) { push @aRep, [substr($sFmtObj, $iFflg, $i - $iFflg + 1), $iRpos,, $i - $iFflg + 1]; $iFflg = 0; } #For Date format $iFmtMode = 0 if (defined $sType && $sType eq 'Text'); #Not Convert Non Numeric if (($iFmtMode == 2) && ($iData =~ /$sNUMEXP/)) { my @aTime = ExcelLocaltime($iData, $i1904); $aTime[4]++; $aTime[5] += 1900; my @aMonL = qw (dum January February March April May June July August September October November December ); my @aMonNm = qw (dum Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); my @aWeekNm = qw (Mon Tue Wed Thu Fri Sat Sun); my @aWeekL = qw (Monday Tuesday Wednesday Thursday Friday Saturday Sunday); my $sRep; for (my $iIt = $#aRep ; $iIt >= 0 ; $iIt--) { my $rItem = $aRep[$iIt]; if ((scalar @$rItem) >= 4) { #Min if ($rItem->[0] eq 'mm') { $sRep = sprintf("%02d", $aTime[1]); } else { $sRep = sprintf("%d", $aTime[1]); } } #Year elsif ($rItem->[0] eq 'yyyy') { $sRep = sprintf('%04d', $aTime[5]); } elsif ($rItem->[0] eq 'yy') { $sRep = sprintf('%02d', $aTime[5] % 100); } #Mon elsif ($rItem->[0] eq 'mmmmm') { $sRep = substr($aMonNm[$aTime[4]], 0, 1); } elsif ($rItem->[0] eq 'mmmm') { $sRep = $aMonL[$aTime[4]]; } elsif ($rItem->[0] eq 'mmm') { $sRep = $aMonNm[$aTime[4]]; } elsif ($rItem->[0] eq 'mm') { $sRep = sprintf('%02d', $aTime[4]); } elsif ($rItem->[0] eq 'm') { $sRep = sprintf('%d', $aTime[4]); } #Day elsif ($rItem->[0] eq 'dddd') { $sRep = $aWeekL[$aTime[7]]; } elsif ($rItem->[0] eq 'ddd') { $sRep = $aWeekNm[$aTime[7]]; } elsif ($rItem->[0] eq 'dd') { $sRep = sprintf('%02d', $aTime[3]); } elsif ($rItem->[0] eq 'd') { $sRep = sprintf('%d', $aTime[3]); } #Hour elsif ($rItem->[0] eq 'hh') { if ($iAm) { $sRep = sprintf('%02d', $aTime[2] % 12); } else { $sRep = sprintf('%02d', $aTime[2]); } } elsif ($rItem->[0] eq 'h') { if ($iAm) { $sRep = sprintf('%d', $aTime[2] % 12); } else { $sRep = sprintf('%d', $aTime[2]); } } #SS elsif ($rItem->[0] eq 'ss') { $sRep = sprintf('%02d', $aTime[0]); } elsif ($rItem->[0] eq 'S') { $sRep = sprintf('%d', $aTime[0]); } #am/pm elsif ($rItem->[0] eq 'am/pm') { $sRep = ($aTime[4] > 12) ? 'pm' : 'am'; } elsif ($rItem->[0] eq 'a/p') { $sRep = ($aTime[4] > 12) ? 'p' : 'a'; } elsif ($rItem->[0] eq '.') { $sRep = '.'; } elsif ($rItem->[0] =~ /^0+$/) { my $i0Len = length($&); #print "SEC:", $aTime[7], "\n"; $sRep = substr(sprintf("%.${i0Len}f", $aTime[7] / 1000.0), 2, $i0Len); } elsif ($rItem->[0] eq '[h]') { $sRep = sprintf('%d', int($iData) * 24 + $aTime[2]); } elsif ($rItem->[0] eq '[mm]') { $sRep = sprintf('%d', (int($iData) * 24 + $aTime[2]) * 60 + $aTime[1]); } #NENGO(Japanese) elsif ($rItem->[0] eq 'ge') { $sRep = Spreadsheet::XLSX::FmtJapan::CnvNengo(1, @aTime); } elsif ($rItem->[0] eq 'ggge') { $sRep = Spreadsheet::XLSX::FmtJapan::CnvNengo(2, @aTime); } elsif ($rItem->[0] eq '@') { $sRep = $iData; } #print "REP:$sRep ",$rItem->[0], ":", $rItem->[1], ":" ,$rItem->[2], "\n"; substr($sFmtRes, $rItem->[1], $rItem->[2]) = $sRep; } } elsif (($iFmtMode == 1) && ($iData =~ /$sNUMEXP/)) { if ($#aRep >= 0) { while ($aRep[$#aRep]->[0] eq ',') { $iCmmCnt--; substr($sFmtRes, $aRep[$#aRep]->[1], $aRep[$#aRep]->[2]) = ''; $iData /= 1000; pop @aRep; } my $sNumFmt = join('', map {$_->[0]} @aRep); my $sNumRes; my $iTtl = 0; my $iE = 0; my $iP = 0; my $iInt = 0; my $iAftP = undef; foreach my $sItem (split //, $sNumFmt) { if ($sItem eq '.') { $iTtl++; $iP = 1; } elsif (($sItem eq 'E') || ($sItem eq 'e')) { $iE = 1; } elsif ($sItem eq '0') { $iTtl++; $iAftP++ if ($iP); $iInt = 1; } elsif ($sItem eq '#') { #$iTtl++; $iAftP++ if ($iP); $iInt = 1; } elsif ($sItem eq '?') { #$iTtl++; $iAftP++ if ($iP); } } $iData *= 100.0 if ($iPer); my $iDData = ($iFugouFlg) ? abs($iData) : $iData + 0; if ($iBunFlg) { $sNumRes = sprintf("%0${iTtl}d", int($iDData)); } else { if ($iP) { $sNumRes = sprintf((defined($iAftP) ? "%0${iTtl}.${iAftP}f" : "%0${iTtl}f"), $iDData); } else { $sNumRes = sprintf("%0${iTtl}.0f", $iDData); } } $sNumRes = AddComma($sNumRes) if ($iCmmCnt > 0); my $iLen = length($sNumRes); my $iPPos = -1; my $sRep; for (my $iIt = $#aRep ; $iIt >= 0 ; $iIt--) { my $rItem = $aRep[$iIt]; if ($rItem->[0] =~ /([#0]*)([\.]?)([0#]*)([eE])([\+\-])([0#]+)/) { substr($sFmtRes, $rItem->[1], $rItem->[2]) = MakeE($rItem->[0], $iData); } elsif ($rItem->[0] =~ /\//) { substr($sFmtRes, $rItem->[1], $rItem->[2]) = MakeBun($rItem->[0], $iData, $iInt); } elsif ($rItem->[0] eq '.') { $iLen--; $iPPos = $iLen; } elsif ($rItem->[0] eq '+') { substr($sFmtRes, $rItem->[1], $rItem->[2]) = ($iData > 0) ? '+' : (($iData == 0) ? '+' : '-'); } elsif ($rItem->[0] eq '-') { substr($sFmtRes, $rItem->[1], $rItem->[2]) = ($iData > 0) ? '' : (($iData == 0) ? '' : '-'); } elsif ($rItem->[0] eq '@') { substr($sFmtRes, $rItem->[1], $rItem->[2]) = $iData; } elsif ($rItem->[0] eq '*') { substr($sFmtRes, $rItem->[1], $rItem->[2]) = ''; #REMOVE } elsif (($rItem->[0] eq "\xA2\xA4") or ($rItem->[0] eq "\xA2\xA5") or ($rItem->[0] eq "\x81\xA2") or ($rItem->[0] eq "\x81\xA3")) { substr($sFmtRes, $rItem->[1], $rItem->[2]) = $rItem->[0]; } elsif (($rItem->[0] eq '(') or ($rItem->[0] eq ')')) { substr($sFmtRes, $rItem->[1], $rItem->[2]) = $rItem->[0]; } else { if ($iLen > 0) { if ($iIt <= 0) { $sRep = substr($sNumRes, 0, $iLen); $iLen = 0; } else { my $iReal = length($rItem->[0]); if ($iPPos >= 0) { my $sWkF = $rItem->[0]; $sWkF =~ s/^#+//; $iReal = length($sWkF); $iReal = ($iLen <= $iReal) ? $iLen : $iReal; } else { $iReal = ($iLen <= $iReal) ? $iLen : $iReal; } $sRep = substr($sNumRes, $iLen - $iReal, $iReal); $iLen -= $iReal; } } else { $sRep = ''; } substr($sFmtRes, $rItem->[1], $rItem->[2]) = "\x00" . $sRep; } } $sRep = ($iLen > 0) ? substr($sNumRes, 0, $iLen) : ''; $sFmtRes =~ s/\x00/$sRep/; $sFmtRes =~ s/\x00//g; } } else { my $iAtMk = 0; for (my $iIt = $#aRep ; $iIt >= 0 ; $iIt--) { my $rItem = $aRep[$iIt]; if ($rItem->[0] eq '@') { substr($sFmtRes, $rItem->[1], $rItem->[2]) = $iData; $iAtMk++; } else { substr($sFmtRes, $rItem->[1], $rItem->[2]) = ''; } } $sFmtRes = $iData unless ($iAtMk); } return wantarray() ? ($sFmtRes, $sColor) : $sFmtRes; } #------------------------------------------------------------------------------ # AddComma (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ sub AddComma { my ($sNum) = @_; if ($sNum =~ /^([^\d]*)(\d\d\d\d+)(\.*.*)$/) { my ($sPre, $sObj, $sAft) = ($1, $2, $3); for (my $i = length($sObj) - 3 ; $i > 0 ; $i -= 3) { substr($sObj, $i, 0) = ','; } return $sPre . $sObj . $sAft; } else { return $sNum; } } #------------------------------------------------------------------------------ # MakeBun (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ sub MakeBun { my ($sFmt, $iData, $iFlg) = @_; my $iBunbo; my $iShou; #1. Init #print "FLG: $iFlg\n"; if ($iFlg) { $iShou = $iData - int($iData); return '' if ($iShou == 0); } else { $iShou = $iData; } $iShou = abs($iShou); my $sSWk; #2.Calc BUNBO #2.1 BUNBO defined if ($sFmt =~ /\/(\d+)$/) { $iBunbo = $1; return sprintf("%d/%d", $iShou * $iBunbo, $iBunbo); } else { #2.2 Calc BUNBO $sFmt =~ /\/(\?+)$/; my $iKeta = length($1); my $iSWk = 1; my $sSWk = ''; my $iBunsi; for (my $iBunbo = 2 ; $iBunbo < 10**$iKeta ; $iBunbo++) { $iBunsi = int($iShou * $iBunbo + 0.5); my $iCmp = abs($iShou - ($iBunsi / $iBunbo)); if ($iCmp < $iSWk) { $iSWk = $iCmp; $sSWk = sprintf("%d/%d", $iBunsi, $iBunbo); last if ($iSWk == 0); } } return $sSWk; } } #------------------------------------------------------------------------------ # MakeE (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ sub MakeE { my ($sFmt, $iData) = @_; $sFmt =~ /(([#0]*)[\.]?[#0]*)([eE])([\+\-][0#]+)/; my ($sKari, $iKeta, $sE, $sSisu) = ($1, length($2), $3, $4); $iKeta = 1 if ($iKeta <= 0); my $iLog10 = 0; $iLog10 = ($iData == 0) ? 0 : (log(abs($iData)) / log(10)); $iLog10 = (int($iLog10 / $iKeta) + ((($iLog10 - int($iLog10 / $iKeta)) < 0) ? -1 : 0)) * $iKeta; my $sUe = ExcelFmt($sKari, $iData * (10**($iLog10 * -1)), 0); my $sShita = ExcelFmt($sSisu, $iLog10, 0); return $sUe . $sE . $sShita; } #------------------------------------------------------------------------------ # LeapYear (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ sub LeapYear { my ($iYear) = @_; return 1 if ($iYear == 1900); #Special for Excel return ((($iYear % 4) == 0) && (($iYear % 100) || ($iYear % 400) == 0)) ? 1 : 0; } #------------------------------------------------------------------------------ # LocaltimeExcel (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ sub LocaltimeExcel { my ($iSec, $iMin, $iHour, $iDay, $iMon, $iYear, $iMSec, $flg1904) = @_; #0. Init $iMon++; $iYear += 1900; #1. Calc Time my $iTime; $iTime = $iHour; $iTime *= 60; $iTime += $iMin; $iTime *= 60; $iTime += $iSec; $iTime += $iMSec / 1000.0 if (defined($iMSec)); $iTime /= 86400.0; #3600*24(1day in seconds) my $iY; my $iYDays; #2. Calc Days if ($flg1904) { $iY = 1904; $iTime--; #Start from Jan 1st $iYDays = 366; } else { $iY = 1900; $iYDays = 366; #In Excel 1900 is leap year (That's not TRUE!) } while ($iY < $iYear) { $iTime += $iYDays; $iY++; $iYDays = (LeapYear($iY)) ? 366 : 365; } for (my $iM = 1 ; $iM < $iMon ; $iM++) { if ( $iM == 1 || $iM == 3 || $iM == 5 || $iM == 7 || $iM == 8 || $iM == 10 || $iM == 12) { $iTime += 31; } elsif ($iM == 4 || $iM == 6 || $iM == 9 || $iM == 11) { $iTime += 30; } elsif ($iM == 2) { $iTime += (LeapYear($iYear)) ? 29 : 28; } } $iTime += $iDay; return $iTime; } #------------------------------------------------------------------------------ # ExcelLocaltime (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ sub ExcelLocaltime { my ($dObj, $flg1904) = @_; my ($iSec, $iMin, $iHour, $iDay, $iMon, $iYear, $iwDay, $iMSec); my ($iDt, $iTime, $iYDays); $iDt = int($dObj); $iTime = $dObj - $iDt; #1. Calc Days if ($flg1904) { $iYear = 1904; $iDt++; #Start from Jan 1st $iYDays = 366; $iwDay = (($iDt + 4) % 7); } else { $iYear = 1900; $iYDays = 366; #In Excel 1900 is leap year (That's not TRUE!) $iwDay = (($iDt + 6) % 7); } while ($iDt > $iYDays) { $iDt -= $iYDays; $iYear++; $iYDays = ((($iYear % 4) == 0) && (($iYear % 100) || ($iYear % 400) == 0)) ? 366 : 365; } $iYear -= 1900; for ($iMon = 1 ; $iMon < 12 ; $iMon++) { my $iMD; if ( $iMon == 1 || $iMon == 3 || $iMon == 5 || $iMon == 7 || $iMon == 8 || $iMon == 10 || $iMon == 12) { $iMD = 31; } elsif ($iMon == 4 || $iMon == 6 || $iMon == 9 || $iMon == 11) { $iMD = 30; } elsif ($iMon == 2) { $iMD = (($iYear % 4) == 0) ? 29 : 28; } last if ($iDt <= $iMD); $iDt -= $iMD; } #2. Calc Time $iDay = $iDt; $iTime += (0.0005 / 86400.0); $iTime *= 24.0; $iHour = int($iTime); $iTime -= $iHour; $iTime *= 60.0; $iMin = int($iTime); $iTime -= $iMin; $iTime *= 60.0; $iSec = int($iTime); $iTime -= $iSec; $iTime *= 1000.0; $iMSec = int($iTime); return ($iSec, $iMin, $iHour, $iDay, $iMon - 1, $iYear, $iwDay, $iMSec); } # ----------------------------------------------------------------------------- # col2int (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ # converts a excel row letter into an int for use in an array sub col2int { my $result = 0; my $str = shift; my $incr = 0; for (my $i = length($str) ; $i > 0 ; $i--) { my $char = substr($str, $i - 1); my $curr += ord(lc($char)) - ord('a') + 1; $curr *= $incr if ($incr); $result += $curr; $incr += 26; } # this is one out as we range 0..x-1 not 1..x $result--; return $result; } # ----------------------------------------------------------------------------- # int2col (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ ### int2col # convert a column number into column letters # @note this is quite a brute force coarse method # does not manage values over 701 (ZZ) # @arg number, to convert # @returns string, column name # sub int2col { my $out = ""; my $val = shift; do { $out .= chr(($val % 26) + ord('A')); $val = int($val / 26) - 1; } while ($val >= 0); return reverse $out; } # ----------------------------------------------------------------------------- # sheetRef (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ # ----------------------------------------------------------------------------- ### sheetRef # convert an excel letter-number address into a useful array address # @note that also Excel uses X-Y notation, we normally use Y-X in arrays # @args $str, excel coord eg. A2 # @returns an array - 2 elements - column, row, or undefined # sub sheetRef { my $str = shift; my @ret; $str =~ m/^(\D+)(\d+)$/; if ($1 && $2) { push(@ret, $2 - 1, col2int($1)); } if ($ret[0] < 0) { undef @ret; } return @ret; } # ----------------------------------------------------------------------------- # xls2csv (for Spreadsheet::XLSX::Utility2007) #------------------------------------------------------------------------------ ### xls2csv # convert a chunk of an excel file into csv text chunk # @args $param, sheet-colrow:colrow (1-A1:B2 or A1:B2 for sheet 1 # @args $rotate, 0 or 1 decides if output should be rotated or not # @returns string containing a chunk of csv # sub xls2csv { my ($filename, $regions, $rotate) = @_; my $sheet = 0; my $output = ""; # extract any sheet number from the region string $regions =~ m/^(\d+)-(.*)/; if ($2) { $sheet = $1 - 1; $regions = $2; } # now extract the start and end regions $regions =~ m/(.*):(.*)/; if (!$1 || !$2) { print STDERR "Bad Params"; return ""; } my @start = sheetRef($1); my @end = sheetRef($2); if (!@start) { print STDERR "Bad coorinates - $1"; return ""; } if (!@end) { print STDERR "Bad coorinates - $2"; return ""; } if ($start[1] > $end[1]) { print STDERR "Bad COLUMN ordering\n"; print STDERR "Start column " . int2col($start[1]); print STDERR " after end column " . int2col($end[1]) . "\n"; return ""; } if ($start[0] > $end[0]) { print STDERR "Bad ROW ordering\n"; print STDERR "Start row " . ($start[0] + 1); print STDERR " after end row " . ($end[0] + 1) . "\n"; exit; } # start the excel object now my $oExcel = new Spreadsheet::XLSX; my $oBook = $oExcel->Parse($filename); # open the sheet my $oWkS = $oBook->{Worksheet}[$sheet]; # now check that the region exists in the file # if not trucate to the possible region # output a warning msg if ($start[1] < $oWkS->{MinCol}) { print STDERR int2col($start[1]) . " < min col " . int2col($oWkS->{MinCol}) . " Reseting\n"; $start[1] = $oWkS->{MinCol}; } if ($end[1] > $oWkS->{MaxCol}) { print STDERR int2col($end[1]) . " > max col " . int2col($oWkS->{MaxCol}) . " Reseting\n"; $end[1] = $oWkS->{MaxCol}; } if ($start[0] < $oWkS->{MinRow}) { print STDERR "" . ($start[0] + 1) . " < min row " . ($oWkS->{MinRow} + 1) . " Reseting\n"; $start[0] = $oWkS->{MinCol}; } if ($end[0] > $oWkS->{MaxRow}) { print STDERR "" . ($end[0] + 1) . " > max row " . ($oWkS->{MaxRow} + 1) . " Reseting\n"; $end[0] = $oWkS->{MaxRow}; } my $x1 = $start[1]; my $y1 = $start[0]; my $x2 = $end[1]; my $y2 = $end[0]; if (!$rotate) { for (my $y = $y1 ; $y <= $y2 ; $y++) { for (my $x = $x1 ; $x <= $x2 ; $x++) { my $cell = $oWkS->{Cells}[$y][$x]; $output .= $cell->Value if (defined $cell); $output .= "," if ($x != $x2); } $output .= "\n"; } } else { for (my $x = $x1 ; $x <= $x2 ; $x++) { for (my $y = $y1 ; $y <= $y2 ; $y++) { my $cell = $oWkS->{Cells}[$y][$x]; $output .= $cell->Value if (defined $cell); $output .= "," if ($y != $y2); } $output .= "\n"; } } return $output; } sub unescape_HTML { my $string = shift; my %options = @_; return $string if ($string eq ''); $string =~ s/"/"/g; $string =~ s/’/'/g; $string =~ s/&/&/g; return $string if $options{textarea}; # for textboxes, we leave < and > as < and > # so that people who enter "" into # our text boxes can't break forms $string =~ s/<//g; return $string; } 1; __END__ =head1 NAME Spreadsheet::XLSX::Utility2007 - Utility function for Spreadsheet::XLSX =head1 SYNOPSIS use strict; #Declare use Spreadsheet::XLSX::Utility2007 qw(ExcelFmt ExcelLocaltime LocaltimeExcel); #Convert localtime ->Excel Time my $iBirth = LocaltimeExcel(11, 10, 12, 23, 2, 64); # = 1964-3-23 12:10:11 print $iBirth, "\n"; # 23459.5070717593 #Convert Excel Time -> localtime my @aBirth = ExcelLocaltime($iBirth, undef); print join(":", @aBirth), "\n"; # 11:10:12:23:2:64:1:0 #Formatting print ExcelFmt('yyyy-mm-dd', $iBirth), "\n"; #1964-3-23 print ExcelFmt('m-d-yy', $iBirth), "\n"; # 3-23-64 print ExcelFmt('#,##0', $iBirth), "\n"; # 23,460 print ExcelFmt('#,##0.00', $iBirth), "\n"; # 23,459.51 print ExcelFmt('"My Birthday is (m/d):" m/d', $iBirth), "\n"; # My Birthday is (m/d): 3/23 =head1 DESCRIPTION Spreadsheet::XLSX::Utility2007 exports utility functions concerned with Excel format setting. ExcelFmt is used by Spreadsheet::XLSX::Fmt2007.pm which is used by Spreadsheet::XLSX. =head1 Functions This module can export 3 functions: ExcelFmt, ExcelLocaltime and LocaltimeExcel. =head2 ExcelFmt $sTxt = ExcelFmt($sFmt, $iData [, $i1904]); I<$sFmt> is a format string for Excel. I<$iData> is the target value. If I<$flg1904> is true, this functions assumes that epoch is 1904. I<$sTxt> is the result. For more detail and examples, please refer sample/chkFmt.pl in this distribution. ex. =head2 ExcelLocaltime ($iSec, $iMin, $iHour, $iDay, $iMon, $iYear, $iwDay, $iMSec) = ExcelLocaltime($iExTime [, $flg1904]); I converts time information in Excel format into Perl localtime format. I<$iExTime> is a time of Excel. If I<$flg1904> is true, this functions assumes that epoch is 1904. I<$iSec>, I<$iMin>, I<$iHour>, I<$iDay>, I<$iMon>, I<$iYear>, I<$iwDay> are same as localtime. I<$iMSec> means 1/1,000,000 seconds(ms). =head2 LocaltimeExcel I<$iExTime> = LocaltimeExcel($iSec, $iMin, $iHour, $iDay, $iMon, $iYear [,$iMSec] [,$flg1904]) I converts time information in Perl localtime format into Excel format . I<$iSec>, I<$iMin>, I<$iHour>, I<$iDay>, I<$iMon>, I<$iYear> are same as localtime. If I<$flg1904> is true, this functions assumes that epoch is 1904. I<$iExTime> is a time of Excel. =head2 col2int I<$iInt> = col2int($sCol); converts a excel row letter into an int for use in an array This function was contributed by Kevin Mulholland. =head2 int2col I<$sCol> = int2col($iRow); convert a column number into column letters NOET: This is quite a brute force coarse method does not manage values over 701 (ZZ) This function was contributed by Kevin Mulholland. =head2 sheetRef (I<$iRow>, I<$iCol>) = sheetRef($sStr); convert an excel letter-number address into a useful array address NOTE: That also Excel uses X-Y notation, we normally use Y-X in arrays $sStr, excel coord (eg. A2). This function was contributed by Kevin Mulholland. =head2 xls2csv $sCsvTxt = xls2csv($sFileName, $sRegion, $iRotate); convert a chunk of an excel file into csv text chunk $sRegions = "sheet-colrow:colrow" (ex. '1-A1:B2' means 'A1:B2' for sheet 1) $iRotate = 0 or 1 (output should be rotated or not) This function was contributed by Kevin Mulholland. =head1 AUTHOR Rob Polocz rob.polocz@trackvia.com based on work by for Spreadsheet::ParseExcel by Kawai Takanori (Hippo2000) used with permission =head1 SEE ALSO Spreadsheet::ParseExcel, Spreadsheet::WriteExcel =head1 COPYRIGHT This module is part of the Spreadsheet::XLSX distribution. =cut Spreadsheet-XLSX-0.18/lib/Spreadsheet/XLSX/Fmt2007.pm0000644000000000000000000001346414573141240020424 0ustar rootrootpackage Spreadsheet::XLSX::Fmt2007; use strict; use warnings; use Spreadsheet::XLSX::Utility2007 qw(ExcelFmt); our $VERSION = '0.18'; # my %hFmtDefault = ( 0x00 => '@', 0x01 => '0', 0x02 => '0.00', 0x03 => '#,##0', 0x04 => '#,##0.00', 0x05 => '($#,##0_);($#,##0)', 0x06 => '($#,##0_);[RED]($#,##0)', 0x07 => '($#,##0.00_);($#,##0.00_)', 0x08 => '($#,##0.00_);[RED]($#,##0.00_)', 0x09 => '0%', 0x0A => '0.00%', 0x0B => '0.00E+00', 0x0C => '# ?/?', 0x0D => '# ??/??', 0x0E => 'yyyy-mm-dd', 0x0F => 'd-mmm-yy', 0x10 => 'd-mmm', 0x11 => 'mmm-yy', 0x12 => 'h:mm AM/PM', 0x13 => 'h:mm:ss AM/PM', 0x14 => 'h:mm', 0x15 => 'h:mm:ss', 0x16 => 'm-d-yy h:mm', #0x17-0x24 -- Differs in Natinal 0x25 => '(#,##0_);(#,##0)', 0x26 => '(#,##0_);[RED](#,##0)', 0x27 => '(#,##0.00);(#,##0.00)', 0x28 => '(#,##0.00);[RED](#,##0.00)', 0x29 => '_(*#,##0_);_(*(#,##0);_(*"-"_);_(@_)', 0x2A => '_($*#,##0_);_($*(#,##0);_(*"-"_);_(@_)', 0x2B => '_(*#,##0.00_);_(*(#,##0.00);_(*"-"??_);_(@_)', 0x2C => '_($*#,##0.00_);_($*(#,##0.00);_(*"-"??_);_(@_)', 0x2D => 'mm:ss', 0x2E => '[h]:mm:ss', 0x2F => 'mm:ss.0', 0x30 => '##0.0E+0', 0x31 => '@', ); #------------------------------------------------------------------------------ # new (for Spreadsheet::XLSX::Fmt2007) #------------------------------------------------------------------------------ sub new { my ($sPkg, %hKey) = @_; my $oThis = {}; bless $oThis; return $oThis; } #------------------------------------------------------------------------------ # TextFmt (for Spreadsheet::XLSX::Fmt2007) #------------------------------------------------------------------------------ sub TextFmt { my ($oThis, $sTxt, $sCode) = @_; return $sTxt if ((!defined($sCode)) || ($sCode eq '_native_')); return pack('U*', unpack('n*', $sTxt)); } #------------------------------------------------------------------------------ # FmtStringDef (for Spreadsheet::XLSX::Fmt2007) #------------------------------------------------------------------------------ sub FmtStringDef { my ($oThis, $iFmtIdx, $oBook, $rhFmt) = @_; my $sFmtStr = $oBook->{FormatStr}->{$iFmtIdx}; if (!(defined($sFmtStr)) && defined($rhFmt)) { $sFmtStr = $rhFmt->{$iFmtIdx}; } $sFmtStr = $hFmtDefault{$iFmtIdx} unless ($sFmtStr); return $sFmtStr; } #------------------------------------------------------------------------------ # FmtString (for Spreadsheet::XLSX::Fmt2007) #------------------------------------------------------------------------------ sub FmtString { my ($oThis, $oCell, $oBook) = @_; my $sFmtStr; # = $oThis->FmtStringDef( # $oBook->{Format}[$oCell->{FormatNo}]->{FmtIdx}, $oBook); # Check for formula error before evaluating format return '@' if ( $oCell->{Val} =~ m/^#/ ); unless (defined($sFmtStr)) { if ($oCell->{Type} eq 'Numeric') { if ($oCell->{Format}) { $sFmtStr = $oCell->{Format}; } elsif (int($oCell->{Val}) != $oCell->{Val}) { $sFmtStr = '0.00'; } else { $sFmtStr = '0'; } } elsif ($oCell->{Type} eq 'Date') { if ($oCell->{Format}) { $sFmtStr = $oCell->{Format}; } elsif (int($oCell->{Val}) <= 0) { $sFmtStr = 'h:mm:ss'; } else { $sFmtStr = 'm-d-yy'; } } else { $sFmtStr = '@'; } } return $sFmtStr; } #------------------------------------------------------------------------------ # ValFmt (for Spreadsheet::XLSX::Fmt2007) #------------------------------------------------------------------------------ sub ValFmt { my ($oThis, $oCell, $oBook) = @_; my ($Dt, $iFmtIdx, $iNumeric, $Flg1904); if ($oCell->{Type} eq 'Text') { $Dt = ((defined $oCell->{Val}) && ($oCell->{Val} ne '')) ? $oThis->TextFmt($oCell->{Val}, $oCell->{Code}) : ''; } else { $Dt = $oCell->{Val}; } $Flg1904 = $oBook->{Flg1904}; my $sFmtStr = $oThis->FmtString($oCell, $oBook); return ExcelFmt($sFmtStr, $Dt, $Flg1904, $oCell->{Type}); } #------------------------------------------------------------------------------ # ChkType (for Spreadsheet::XLSX::Fmt2007) #------------------------------------------------------------------------------ sub ChkType { my ($oPkg, $iNumeric, $iFmtIdx) = @_; if ($iNumeric) { if ( (($iFmtIdx >= 0x0E) && ($iFmtIdx <= 0x16)) || (($iFmtIdx >= 0x2D) && ($iFmtIdx <= 0x2F))) { return "Date"; } else { return "Numeric"; } } else { return "Text"; } } 1; __END__ =head1 NAME Spreadsheet::XLSX::Fmt2007 - A class for Cell formats. =head1 SYNOPSIS See the documentation of L. my $cell = $myworkbook->worksheet->{Cells}[$row][$col] my $type = $cell->{Type}; # Date, Text, or Numeric my $disp_value = $cell->Value; # displayed (formatted) value set in XLSX by $myFmt2007->ValFmt($cell, $workbook) my $fund_value = $cell->{Val}; # fundemental (underlying) value my $formatter; if( $myworkbook->excel07 ) { $formatter = Spreadsheet::XLSX::Fmt2007->new(); } else { $formatter = Spreadsheet::ParseExcel::FmtDefault->new(); } my $format_string = $formatter->FmtString($cell, $self->workbook); =head1 DESCRIPTION This module is used in conjunction with L. See the documentation for L. This code is adapted for Excel 2007 from L by Kawai, Takanori (Hippo2000) 2001-02-02. This Program is ALPHA version. =head1 AUTHOR See the documentation for L. =head1 COPYRIGHT See the documentation for L. =cut Spreadsheet-XLSX-0.18/META.yml0000644000000000000000000000143214573141341014457 0ustar rootroot--- abstract: 'Perl extension for reading MS Excel 2007 files.' author: - 'Dmitry Ovsyanko ' - 'Mike Blackwell