From dc3962a402b718c445796c65031070f535ebd4e5 Mon Sep 17 00:00:00 2001 From: AntonSikidin Date: Sat, 30 Oct 2021 22:49:50 +0300 Subject: [PATCH] Add ability to generate report from template (#669) write tool to automate abap2xlsx fix merged cells code style Convert keyword to UPPER case adapt code to 702 New proposal fix of Lint errors Co-authored-by: sandraros <34005250+sandraros@users.noreply.github.com> Co-authored-by: Abo --- src/demos/zdemo_excel_fill_template.prog.abap | 353 ++++++++++ src/demos/zdemo_excel_fill_template.prog.xml | 58 ++ src/demos/zdemo_excel_template.w3mi.data.xlsx | Bin 0 -> 11114 bytes src/demos/zdemo_excel_template.w3mi.xml | 29 + .../zexcel_template_get_types.prog.abap | 381 ++++++++++ .../zexcel_template_get_types.prog.xml | 58 ++ src/zcl_excel.clas.abap | 27 + src/zcl_excel_fill_template.clas.abap | 649 ++++++++++++++++++ src/zcl_excel_fill_template.clas.xml | 42 ++ src/zcl_excel_template_data.clas.abap | 42 ++ src/zcl_excel_template_data.clas.xml | 16 + src/zcl_excel_worksheet.clas.abap | 20 +- 12 files changed, 1665 insertions(+), 10 deletions(-) create mode 100644 src/demos/zdemo_excel_fill_template.prog.abap create mode 100644 src/demos/zdemo_excel_fill_template.prog.xml create mode 100644 src/demos/zdemo_excel_template.w3mi.data.xlsx create mode 100644 src/demos/zdemo_excel_template.w3mi.xml create mode 100644 src/not_cloud/zexcel_template_get_types.prog.abap create mode 100644 src/not_cloud/zexcel_template_get_types.prog.xml create mode 100644 src/zcl_excel_fill_template.clas.abap create mode 100644 src/zcl_excel_fill_template.clas.xml create mode 100644 src/zcl_excel_template_data.clas.abap create mode 100644 src/zcl_excel_template_data.clas.xml diff --git a/src/demos/zdemo_excel_fill_template.prog.abap b/src/demos/zdemo_excel_fill_template.prog.abap new file mode 100644 index 0000000..fc7ec89 --- /dev/null +++ b/src/demos/zdemo_excel_fill_template.prog.abap @@ -0,0 +1,353 @@ +*&---------------------------------------------------------------------* +*& Report Fill Template +*& +*&---------------------------------------------------------------------* +*& +*& +*&---------------------------------------------------------------------* + +REPORT zdemo_excel_fill_template. + +*================= +* Start of generated code. +* All these types were generated +* by ZEXCEL_TEMPLATE_GET_TYPES based +* on the Excel file ZDEMO_EXCEL_TEMPLATE +* from SMW0. +*================= +TYPES t_number TYPE p length 16 decimals 4. +TYPES: + begin of t_TABLE1, + PERSON type string, + SALARY type t_number, + end of t_TABLE1, + + tt_TABLE1 type standard table of t_TABLE1 with default key, + + begin of t_LINE1, + CARRID type string, + CONNID type string, + FLDATE type d, + PRICE type t_number, + end of t_LINE1, + + tt_LINE1 type standard table of t_LINE1 with default key, + + begin of t_TABLE2, + CARRID type string, + PRICE type t_number, + LINE1 type tt_LINE1, + end of t_TABLE2, + + tt_TABLE2 type standard table of t_TABLE2 with default key, + + begin of t_Sheet1, + DATE type d, + TIME type t, + USER type string, + TOTAL type t_number, + PRICE type t_number, + TABLE1 type tt_TABLE1, + TABLE2 type tt_TABLE2, + end of t_Sheet1, + + + begin of t_TABLE3, + PERSON type string, + SALARY type t_number, + end of t_TABLE3, + + tt_TABLE3 type standard table of t_TABLE3 with default key, + + begin of t_Sheet2, + DATE type d, + TIME type t, + USER type string, + TOTAL type t_number, + TABLE3 type tt_TABLE3, + end of t_Sheet2. + + +DATA: lo_data type ref to ZCL_EXCEL_TEMPLATE_DATA. +*================= +* End of generated code +*================= + +* define variables +DATA: gs_sheet1 TYPE t_sheet1, + gs_sheet2 TYPE t_sheet2. + +TABLES: sscrfields. + +CONSTANTS: gc_save_file_name TYPE string VALUE 'fill_template.xlsx'. +INCLUDE zdemo_excel_outputopt_incl. + +PARAMETERS: p_smw0 RADIOBUTTON GROUP rad1 DEFAULT 'X'. +PARAMETERS: p_objid TYPE w3objid OBLIGATORY DEFAULT 'ZDEMO_EXCEL_TEMPLATE'. + +PARAMETERS: p_file RADIOBUTTON GROUP rad1. +PARAMETERS: p_fpath TYPE string OBLIGATORY LOWER CASE DEFAULT 'c:\temp\whatever.xlsx'. + +SELECTION-SCREEN SKIP 1. + +SELECTION-SCREEN PUSHBUTTON /1(45) but_txt USER-COMMAND get_types. + + +INITIALIZATION. + but_txt = '@BY@ Analyze file to propose TYPES'. + +AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fpath. + PERFORM get_file_path CHANGING p_fpath. + +AT SELECTION-SCREEN. + CASE sscrfields-ucomm. + WHEN 'GET_TYPES'. + SUBMIT zexcel_template_get_types + WITH p_smw0 = p_smw0 + WITH p_objid = p_objid + WITH p_file = p_file + WITH p_fpath = p_fpath + AND RETURN. + ENDCASE. + +START-OF-SELECTION. + PERFORM load_data. + PERFORM generate_file. + +FORM load_data. + + FIELD-SYMBOLS: TYPE t_table1, + TYPE t_line1, + TYPE t_table2. + + gs_sheet1-date = sy-datum. + gs_sheet1-time = sy-uzeit. + gs_sheet1-user = sy-uname. + gs_sheet1-total = 5600. + + APPEND INITIAL LINE TO gs_sheet1-table1 ASSIGNING . + -person = 'Lurch Schpellchek'. + -salary = 1200. + + APPEND INITIAL LINE TO gs_sheet1-table1 ASSIGNING . + -person = 'Russell Sprout'. + -salary = 1300. + + APPEND INITIAL LINE TO gs_sheet1-table1 ASSIGNING . + -person = 'Fergus Douchebag'. + -salary = 3000. + + APPEND INITIAL LINE TO gs_sheet1-table1 ASSIGNING . + -person = 'Bartholomew Shoe'. + -salary = 100. + + + gs_sheet1-price = 14003. + + APPEND INITIAL LINE TO gs_sheet1-table2 ASSIGNING . + -carrid = 'AC'. + -price = 1222. + + APPEND INITIAL LINE TO -line1 ASSIGNING . + -carrid = 'AC'. + -connid = '0820'. + -fldate = '20021220'. + -price = 1222. + + + APPEND INITIAL LINE TO gs_sheet1-table2 ASSIGNING . + -carrid = 'AF'. + -price = 2222. + + APPEND INITIAL LINE TO -line1 ASSIGNING . + -carrid = 'AF'. + -connid = '0820'. + -fldate = '20021223'. + -price = 2222. + + + APPEND INITIAL LINE TO gs_sheet1-table2 ASSIGNING . + -carrid = 'LH'. + -price = 9488. + + APPEND INITIAL LINE TO -line1 ASSIGNING . + -carrid = 'LH'. + -connid = '0400'. + -fldate = '19950228'. + -price = 899. + + APPEND INITIAL LINE TO -line1 ASSIGNING . + -carrid = 'LH'. + -connid = '0400'. + -fldate = '19951117'. + -price = 1499. + + APPEND INITIAL LINE TO -line1 ASSIGNING . + -carrid = 'LH'. + -connid = '0400'. + -fldate = '19950606'. + -price = 1090. + + APPEND INITIAL LINE TO -line1 ASSIGNING . + -carrid = 'LH'. + -connid = '0400'. + -fldate = '19950428'. + -price = 6000. + + APPEND INITIAL LINE TO -line1 ASSIGNING . + -carrid = 'LH'. + -connid = '0400'. + -fldate = '20021221'. + -price = 222. + + APPEND INITIAL LINE TO gs_sheet1-table2 ASSIGNING . + -carrid = 'SQ'. + -price = 849. + + APPEND INITIAL LINE TO -line1 ASSIGNING . + -carrid = 'SQ'. + -connid = '0026'. + -fldate = '19950228'. + -price = 849. + + + MOVE-CORRESPONDING gs_sheet1 TO gs_sheet2. + gs_sheet2-table3 = gs_sheet1-table1. + +ENDFORM. + +FORM generate_file. + + DATA: lo_excel TYPE REF TO zcl_excel, + lo_reader TYPE REF TO zif_excel_reader, + lo_root TYPE REF TO cx_root. + + TRY. + +* prepare data + CREATE OBJECT lo_data. + lo_data->add( iv_sheet = 'Sheet1' iv_data = gs_sheet1 ). + lo_data->add( iv_sheet = 'Sheet2' iv_data = gs_sheet2 ). + +* create reader + CREATE OBJECT lo_reader TYPE zcl_excel_reader_2007. + +* load template + IF p_file IS NOT INITIAL. + lo_excel = lo_reader->load_file( p_fpath ). + ELSE. + PERFORM load_smw0 USING lo_reader p_objid CHANGING lo_excel. + ENDIF. + +* merge data with template + lo_excel->fill_template( lo_data ). + + +*** Create output + lcl_output=>output( lo_excel ). + + CATCH cx_root INTO lo_root. + MESSAGE lo_root TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + +ENDFORM. + +*&---------------------------------------------------------------------* +*& Form Get_file_path +*&---------------------------------------------------------------------* +FORM get_file_path CHANGING cv_path TYPE string. + + DATA: + lv_rc TYPE i, + lv_user_action TYPE i, + lt_file_table TYPE filetable, + ls_file_table LIKE LINE OF lt_file_table. + + CLEAR cv_path. + + cl_gui_frontend_services=>file_open_dialog( + EXPORTING + window_title = 'select template xlsx' + multiselection = '' + default_extension = '*.xlsx' + file_filter = 'Text file (*.xlsx)|*.xlsx|All (*.*)|*.*' + CHANGING + file_table = lt_file_table + rc = lv_rc + user_action = lv_user_action + EXCEPTIONS + OTHERS = 1 + ). + IF sy-subrc = 0. + IF lv_user_action = cl_gui_frontend_services=>action_ok. + IF lt_file_table IS NOT INITIAL. + READ TABLE lt_file_table INTO ls_file_table INDEX 1. + IF sy-subrc = 0. + cv_path = ls_file_table-filename. + ENDIF. + ENDIF. + ENDIF. + ENDIF. +ENDFORM. " Get_file_path + +FORM load_smw0 + USING + io_reader TYPE REF TO zif_excel_reader + iv_w3objid TYPE w3objid + CHANGING + ro_excel TYPE REF TO zcl_excel + RAISING + zcx_excel. + + DATA: lv_excel_data TYPE xstring, + lt_mime TYPE TABLE OF w3mime, + ls_key TYPE wwwdatatab, + lv_errormessage TYPE string, + lv_filesize TYPE i, + lv_filesizec TYPE c LENGTH 10. + +*--------------------------------------------------------------------* +* Read file into binary string +*--------------------------------------------------------------------* + + ls_key-relid = 'MI'. + ls_key-objid = iv_w3objid . + + CALL FUNCTION 'WWWDATA_IMPORT' + EXPORTING + key = ls_key + TABLES + mime = lt_mime + EXCEPTIONS + OTHERS = 1. + IF sy-subrc <> 0. + lv_errormessage = 'A problem occured when reading the MIME object'(004). + zcx_excel=>raise_text( lv_errormessage ). + ENDIF. + + CALL FUNCTION 'WWWPARAMS_READ' + EXPORTING + relid = ls_key-relid + objid = ls_key-objid + name = 'filesize' + IMPORTING + value = lv_filesizec. + + lv_filesize = lv_filesizec. + CALL FUNCTION 'SCMS_BINARY_TO_XSTRING' + EXPORTING + input_length = lv_filesize + IMPORTING + buffer = lv_excel_data + TABLES + binary_tab = lt_mime + EXCEPTIONS + failed = 1 + OTHERS = 2. + +*--------------------------------------------------------------------* +* Parse Excel data into ZCL_EXCEL object from binary string +*--------------------------------------------------------------------* + ro_excel = io_reader->load( i_excel2007 = lv_excel_data ). + +ENDFORM. diff --git a/src/demos/zdemo_excel_fill_template.prog.xml b/src/demos/zdemo_excel_fill_template.prog.xml new file mode 100644 index 0000000..e75f886 --- /dev/null +++ b/src/demos/zdemo_excel_fill_template.prog.xml @@ -0,0 +1,58 @@ + + + + + + ZDEMO_EXCEL_FILL_TEMPLATE + 1 + T + E + X + X + + + + R + abap2xlsx Demo: Fill template + 29 + + + S + P_FILE + Load template from file + 31 + + + S + P_FPATH + Path to template.xlsx + 29 + + + S + P_OBJID + Object ID + 17 + + + S + P_PATH + . + 9 + D + + + S + P_SMW0 + Load template from SMW0 + 31 + + + S + RB_BACK + 17 + + + + + diff --git a/src/demos/zdemo_excel_template.w3mi.data.xlsx b/src/demos/zdemo_excel_template.w3mi.data.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..d4e57b4d306ba9beadf965052eff06268c966932 GIT binary patch literal 11114 zcmeHtWmsHmvUTI`u0aFA1C0fD*Wm8%5Fo+bo!|)s3ogNeyK8WFcY^!vBnf*MycU!IAU3*p4+EuT-6a*wD02%-b002k5rV}JNkEJf(vc8b^`f9Oj1P2yTQM+wI6yr^w#^#(5 zR@&=!LxE0VTvhNPK&uF>)6ULoD!qtDuWbU`Q337R^hJ4IhC&i2N`k5+4!+18p2=vT zL5T^8+lQenx-`nNc*QVM=zCS_iOk$}>&|9&$=t5cb>oWCoW6kXO>6;V*ffbMkE9aX z>M7urwAe^OrrQwI5m*4$H=BO?T};qqY=MHr>xlAe#@U*xc&eiMYIsp7R`;+%^$znB z)rWCW95#_W&O19Wx}Z~=IjX8TrRh>JV^|-74uolyZ`lc zm4)VqchJ84&=-U6wnvZf-kxa@aaC5x`0=*Tuh9|RfoS&l2mz4)TdYHqMygB`BDu;;kfH|$y7 zBB*TrbCA4wcc>Hs3J^SK000H#8CNSt7h4BQ16y0mAH^(NX~}k$3Dq;b^0Bq*CgnM@ zgm>cKkGF`ceIn=d|A(&G1M{eykLl zzQdYchcF!m12)>jt*OB|6AddC++emI+Ts`VCFEu=0;_C|p=>QO0IIS7>*BDH>V6Jm zPI_CTR!Fl=#SJCDJZxumYSB1mW9hBrgIBV8Tk!}DLa-B*xDLEqF9~{G-?MyjAqh2B zg1Bei5Shu?IH9!TRPI;S?__2K7<93e)UZ;Ez9p2!5u|z5PqH6+m8WU z-o3f(v1c$g&4vqZYi|7rb&(UNN8E*5^D#P8L^3xPiWhahgQ2o~;s*zgc`i z{e=*+ZZ>tO3SQ?@PW6%`xQeCj5*aI8ysVgkk!^U|QdZ8Wo}VnALs2ie-7j8AlMrak zn<16h)h*zNZ%FG`f>I}PuLs>zdJS>i8${?< z;(e9FqRB|+(q~ub8teu-PJ*?DS!h2a6y##Gv7Iy85=t} zGX6Zg{E_(5R5U?}5A#RjL%nXKko6H1&Qqe+$gxi8Vi@jvsmB^ZKBqNn{^+sALHfzx zq7v4?!0VyO@l-;z=9ccfT96?Bd(wz3KX;7d`yO|!xO6@fRftu*{_p-dG&nEcq6f}L z@_FJO#CrlQNsC|*YeRZxXUV>Mv`>*4=4QdiwD&3QgsXp@pk2b$DC@B9Q{+SRZAyQc z92ZMEnrN4|q3G~Z**z{~K7m3bd%*YJgdV|Bum6hD32!Vabv3lG2oM?|o#Ww<-O=xQ zR@V34Bnu%yyhn*%wkuppzy1LuUKBbUo@gmIeZtFH zge*Ly5I*8s@Egj`A;SAhI?VwQny*+Sf+3ehN^DznSi0rluagims`q9%6An!;ve~fn z3ykS@0~Dh;&H>zDyVvxs$+Ww+vr-+g){3{<2fT2#8k!k9K80$u3g3ZPfkH9hGF1Dd z7^*L(5mg!E>}E+i@aF36sW9pTy((F@&+G16kw%Uq%4u%3OGYfbYAZAk{L5!0+=yn8 zZZaHA(skjv_;LrnoQM~GfH{Z8PV!yZLCSit4D{;^ZWLnTfaS331f+v`Fgimla4f;=R;#aYd2guZeY@5zyZBQl2*m{nYacmqP-+I*IL*xS!lin zZEDNVAd(|X!3|rM=)O;wS0 z*IDfez?>Gt?{7?};`9mH^3E5pREhFS`yr?GW#0e z(N@vgSksX$KWp)vep}=!dK^Wn0S_2IXPd^mBjyIZR9-V7N@A0MWwO(ipTlNcadV+)%nB0?zyS1PhodP%QmnNvF z_#amKlGx5YWN4oUUl{e{5LoCZDBpG|ZrR2E9c`#x7Lm4gOqcWXD5H>DNo6MNueXhf&nV=gLdV!L2`s zrC2m@EEB(JxIb*lz{kfiw-@JVwDvXO`y%qZuM7Zk&_dLj3Du`Pl3q<)6P4m-3S$iX z{-f(V&+ILR7F|plHHqq~Ynsb++$AMwm44XSFSX)fL6l>d;BZ|!z%NQPmi#S@=!7cR zN$?JK-8_uaP%d(fOvqgsqL#TbL-c6mbrYhY>2mn0xaUG9k1~vJDAYBG#h3NZV|Sz^kYhdRcDmiE^GazR(hG{F zSw~;5B}Rrhc5YkiCUy6lwude_T{h_-_kE3Pxwxc*TXGKMY@DA7WpRJiy{6jrfsB(i zQU}i^=AdmP7U@=cJdhoKqR0s?O)tAH9GWJDm1bXn7X1ulLgDZoH#pCY!fzOT&Q5VOPae{_p}78@rsV{2o^pZlM6W?y|cjDQ`p3Fn3n(b0vw+O+Ee-L|aTdGyc* z{Yz>*p|R!#bs=7IOalQ1I3?$~B6W67qM$8L{3t&JQsY^ay13aGU#472xtK=3Rf-Ks zP?3J}H+Q+4v&FH`x~io-(s_=)EV62|_Li#LQ>{BmGUBiHzPdyOzE9Y*^BIN9r0XPd z38{6nz8sS)$s|HsgXGdn|4uY+Z%DeyH9_-C=;f;FG~wrC>%K3LaIS+U6B2>4pBDX9 z_CDgMUdjr1?sRJGL*c5`lye@PTlO!k6)_Fv}L? zw@8Eo>FFIbPin0oGKOWL?(^|<&4oq{5v~92` zhjpG%83q{aX2@*2 zj743#wA6wUgy#CKg;qWig^t&Jl6>jsQ}$z-(z(l2XdNE|$y$biWxuBo2~#B{IDkuonjNoOuY_S1qNfsR#Srm<#Hw@)a9^ z3(@7~XWNJC6{)SGB~SO$eNCxGZ}x`Uo5WI`#}m^STADM_aRBlQrOnC0qmRv=CwCK< zx{v3lESd+dMoveol~;tLV`j@6{S{PtP^f zhpwWt%ZFB3JP|$lhpeAlDIq7$Oyg>3d3T#6F`F{Arp;MJ$_u_p^`J1IMSe}LUz!!b zA3|>&WnhHd>?VssXaEOG5^>_*}2w`-?O}r za{-T!)YsL(ul&vQ!b7w!&*(?zaGk6i{XH=c4QkI7zMgk(QNmtUJ9)a*GGO6%)N2(M zzIXfbW`&nBo;Z}U^H!^Pfm7N&juf*%CSX>*gx%p3mv|%38yaz*PN=V|H|feZ_=-u? zQEho@oXx2#tiW_WnFV>zQ@Mz(<4SA6;<8K}d75IWbkf4XHU&jEQds>EYR_TXGMJEv zt)FMQ?p>#I?nNIh_~=D*^awtS1dxs*rBHAu`~4#wh0-uXfXG~1CS{>+fQ28FyrvkG ziUTrT?JJw*tt~)Vjv%I-QQCL;(o9-E$NZSZP3ZztKoOY=p1f!seXY&G$9?UO7Pe^S ze*OtI&*A8i41uj8&bu&FiFkX?c#3`>ojNUm@xYYgOEk+DWLuR!xpj&o} z%3r3q%)i*bU3r--bZA%G$?pUmWNH|*0r8+6Z~W2zn;7>HQHd~>s-Hh>8fQEOk*c%T z2PB{}e&*MST@u)5bhT_feLrkR!m6b&>xV!S4;zwycJ`_w@A?QM7{o(Rq< zVM(^Tj96o_M@A!-2Xv54ogFX^WB>8v8^(_XIa|PQbX(Fw%IihuIAfRWy_Q9N661RB zrD`;MPZjrOX^Z`YtA@~V2I_2IlA4Y8bs<{Bp5!7*4Khf|SR{TW8R15=IhlJGS@v#K z+tjm+E4|9WSFM;5ET?|0vlXA^#Tt5v=NowipxIap2v?`=?l7JeC<=WgfSOy$8G`B2w6{iu;H+h4xE zQ`jJwV(i@&-{?!CRL(6?EeQQu=b1lIqua~@DZHhi_N8Oh4fO=o~ zMt^)Ch(ad{k3{oC3Gn`1;~sl`vCoo+7M)?nR;@c` z6X23Yr~daPjg*t8Mhg-EPy^L7q(4fUqtja}W5*vVZCp*;c8(3x<5}4w$+q@n5T&{U zy~`VPFsM2Me&&qQO5qvd7o!>5(uZY_O;U>08`H%fN^|;!=oHphR(LLTbR51n73aT+ z5)tC)xAIz^!8Ud#XN72LLu^vg8W(RXRQoz8si(wdAuqGga%xZ`>OTXmuZ5H7JudF9U7F@Q zMN83}CQrtW-(S6JaA)88mERFwNs~`FVB)46wn)W_>RYkc>3BA3!^(R?KuLdLDCSj? z&2BCO&4sx49gu?0p>bL7pxBj6aU0%UF5dmZscrI&PJb88RfOP|u_r8q<%HPpL)Z+4*z#El~++ylIDZ-LcriP-Fw z5fmZoy(v>vD?E-J5}8bn(4dbv0eXJRUDr_@XHKrwSe1l>PRv`G{zbJBm9XRNGGlO^ z?;-J^)afQl*J-c#wiE?Tl4T`*vC~Kk{1+p)qx`K9LRc#{(9ze};zu+buxu=%eUC#+^<*+0Fdo=jD|!oxb4$4qN#iC?6-yi+9Fe`!52r<>s` zudZRux{HQxb7|Hv-#{&Pn1#2`YXv^^=&Ds%?2N(fT!}*9#y%@ph_x`_6z*d00*1d{ zcaI-6GG3Bh_A!vhU1a|ltNhdC^c*CjliAAF%sPMo@ho;4<^mdm2Z=y_sIx65-CbwO zkq+HmeU2O0Kb` z{^qj_()VyFR1Zstn9ZQIz&7QOZS1+2=7kz#=cCS%DSNQW+xan)3tr)-t#zScmo{8V zS#%U~s;Il=SIDO93dHAM#pD|3PPCTTrx-%rfeG1N@nyv-ngKV(BA!hhMu+S4=_|Xd?m(9&oj=WPj@KR2KYBD z5k9AR?N6ex3`GOS>(2EYJlT41b{}NP(8FxO92ZgFIFgoGgpYBYeDHB~JZm)%?Y2Xo zhRU+E3MZWk?WS|XmepJ?`pzRilx{Fbysv5-N-J%uB~d9EOOs$+t1clR85%Z!W?e7y z=DtqjP$#hJXd_p=ER4ksHzCvJ4F}45?j7ggTa7qQ3dzX`v#96URa1!hy063UJbGgs za)ipxgWbGe@>Q>WtJf<8a$Tf*omSiz58rv2pw;l-|Mr%I%bHoL7345Mkn_m@aNLic z>7V_tKbok&x?n$BsQyu{p>0fkRfxe2l`JhKs~;HzA3}# zpu=eUcRcX3@$e51ShO>t3LgdB`Axe~a0SVSQtC>QPCdT|i0I5^UPzkNP+s3|Px}i- zwi_-oX?v;ToQDM%k|7k^@RJ4rg;VI1!( zjHAo@=*3;p4;S=O#_Dlqiu3d+AN2c!Tp)IlJ7?|4_=w%=>ePOCt0K;!B8t!T7Y3XGOoAW1! z>RB}n)-wPfMUx)jAB}1C7j%oRViDvdNr4L%IP)U0yF?T%2i*q$ubc_<|IwL*P`e9A zf`Y;U6gFs}k%Ez}p}d2wog<^6t%LCoaRZte|96rAx`^Six^nF#n4L>9cgRRb^f~9l zqO%MN6;z2y99bt3EeoP_@qpQbIjOl~=U!rWKR0B)p+|=rI%`Xl9GB z`8Aa9G#S_MLeoq&%Idz!XF_mP=9QGf+fdumHB5JTpQCGGiq9(8NLHRM%7+sz`4}+3 zArp1T7-F63Th>f7J#$0b`5NX4_*@{z`7iU8 z!W7PTLNqel)9j!;KXVG_GDhGH&T>0iH?x{!Ge6}O?U6g~-o37}Wlg9{#ez}7@_lXN zbKRu^_0gtH!+T8y|CtGIuxS9(ObTZ+d{kKs2{Cf37hsOde*8UvVu_62tGho;(KQeWLhWv*Ygyj#xYFC2{`S$wb&9 z!bCZUfLoxDMg1!Q_3iBb%RdnD{@l`D%h=8_AvU5+doelLu2%{$L4FC%To`HR^`$%* zDv<6LH0niFC!Z-zw<<2FhlZLY=oI7O3E1tE6Pa|_k9tddU(9ARZ);u}I))Wq$Pw*}1j zHVvLuEogkhr<6euKD3{>EyV;Aa8-#K6D!Z^rh+c#3<;p5>?f)x%|z@auLrl6zp2K1 z@S2tR$_b!NSo8Bi3yCEo@bZL4s9=|nmlws0px$wk+6bKI7Qct177;5%23|*hx+b#L zEZY|#J#&Dc%-4(0qAp~V3L>qhSB!3UpEg9|r*@?i?b+>3W>jLD2Jl3%Y zPI7Q~gpB)nAiNr6pRaR0M{S?$di$7sTxjpsU|I7ZipEXf+n+r>PQ#CPX`z+*lGJ9+ z)1RY_xODH~ZQtjVDgNfs%blgZYlj5gb$d-J&en9Vyu1Hbd%(cyK`QO{Yv}%QS^shT z&5AmCslNmKePPc(41XMpKtK7HWj;?0pDuRzW%>9(`MS0qw{)NJT{uAYCyZR}>({{iw z05H6t0Kb|8Pfedn_+O^MM1Pn*74%OLo@&`&2(83Veehdl`xNl0H2ekF{_Ot)_)920 z1$-*BegSro`~-X=vwkbP{(Vq+(tii^r-FJ4`gi&B>pTH~SrF(yiJ_ + + + + ZDEMO_EXCEL_TEMPLATE + ZDEMO_EXCEL_TEMPLATE + + + MI + ZDEMO_EXCEL_TEMPLATE + fileextension + .xlsx + + + MI + ZDEMO_EXCEL_TEMPLATE + filename + ZABAP2XLSX_EXAMPLE.xlsx + + + MI + ZDEMO_EXCEL_TEMPLATE + mimetype + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + + + + diff --git a/src/not_cloud/zexcel_template_get_types.prog.abap b/src/not_cloud/zexcel_template_get_types.prog.abap new file mode 100644 index 0000000..865bf39 --- /dev/null +++ b/src/not_cloud/zexcel_template_get_types.prog.abap @@ -0,0 +1,381 @@ +*&---------------------------------------------------------------------* +*& Report ZEXCEL_TEMPLATE_GET_TYPES +*& +*&---------------------------------------------------------------------* +*& +*& +*&---------------------------------------------------------------------* + +REPORT zexcel_template_get_types. + +TYPES : tt_text TYPE TABLE OF text80. + +DATA: go_excel TYPE REF TO zcl_excel, + go_reader TYPE REF TO zif_excel_reader, + go_template_filler TYPE REF TO zcl_excel_fill_template, + go_error TYPE REF TO zcx_excel. + +SELECTION-SCREEN BEGIN OF BLOCK b02 WITH FRAME. + +PARAMETERS: p_smw0 RADIOBUTTON GROUP rad2 DEFAULT 'X'. +PARAMETERS: p_objid TYPE w3objid OBLIGATORY DEFAULT 'ZDEMO_EXCEL_TEMPLATE'. + +PARAMETERS: p_file RADIOBUTTON GROUP rad2. +PARAMETERS: p_fpath TYPE string OBLIGATORY LOWER CASE DEFAULT 'c:\temp\whatever.xlsx'. + +SELECTION-SCREEN END OF BLOCK b02. + +SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME. + +PARAMETERS: p_normal RADIOBUTTON GROUP rad1 DEFAULT 'X', + p_other RADIOBUTTON GROUP rad1. + +SELECTION-SCREEN END OF BLOCK b01. + +AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fpath. + PERFORM get_file_path CHANGING p_fpath. + + +START-OF-SELECTION. + + TRY. + + CREATE OBJECT go_reader TYPE zcl_excel_reader_2007. + +* load template + IF p_file IS NOT INITIAL. + go_excel = go_reader->load_file( p_fpath ). + ELSE. + PERFORM load_smw0 USING go_reader p_objid CHANGING go_excel. + ENDIF. + + go_template_filler = zcl_excel_fill_template=>create( go_excel ). + + PERFORM get_types. + + CATCH zcx_excel INTO go_error. + MESSAGE go_error TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + + +*&---------------------------------------------------------------------* +*& Form Get_file_path +*&---------------------------------------------------------------------* +FORM get_file_path CHANGING cv_path TYPE string. + + DATA: + lv_rc TYPE i, + lv_user_action TYPE i, + lt_file_table TYPE filetable, + ls_file_table LIKE LINE OF lt_file_table. + + CLEAR cv_path. + + cl_gui_frontend_services=>file_open_dialog( + EXPORTING + window_title = 'select template xlsx' + multiselection = '' + default_extension = '*.xlsx' + file_filter = 'Text file (*.xlsx)|*.xlsx|All (*.*)|*.*' + CHANGING + file_table = lt_file_table + rc = lv_rc + user_action = lv_user_action + EXCEPTIONS + OTHERS = 1 ). + IF sy-subrc = 0. + IF lv_user_action = cl_gui_frontend_services=>action_ok. + IF lt_file_table IS NOT INITIAL. + READ TABLE lt_file_table INTO ls_file_table INDEX 1. + IF sy-subrc = 0. + cv_path = ls_file_table-filename. + ENDIF. + ENDIF. + ENDIF. + ENDIF. +ENDFORM. " Get_file_path + +FORM get_types . + + DATA: lv_sum TYPE i, + lt_res TYPE tt_text, + lt_buf TYPE tt_text, + lv_lines TYPE i. + + FIELD-SYMBOLS: LIKE LINE OF go_template_filler->mt_sheet, + TYPE text80. + + + LOOP AT go_template_filler->mt_sheet ASSIGNING . + + CLEAR lv_sum. + + READ TABLE go_template_filler->mt_range TRANSPORTING NO FIELDS WITH KEY sheet = . + + ADD sy-subrc TO lv_sum. + + READ TABLE go_template_filler->mt_var TRANSPORTING NO FIELDS WITH KEY sheet = . + + ADD sy-subrc TO lv_sum. + + CHECK lv_sum <= 4. + + PERFORM get_type_r USING 0 CHANGING lt_buf. + + APPEND LINES OF lt_buf TO lt_res. + + ENDLOOP. + + + IF p_normal IS INITIAL. + READ TABLE lt_res ASSIGNING INDEX 1. + TRANSLATE USING ',:'. + INSERT INITIAL LINE INTO lt_res ASSIGNING INDEX 1. + = 'TYPES'. + APPEND INITIAL LINE TO lt_res ASSIGNING . + = '.'. + + lv_lines = lines( lt_res ) - 2. + DELETE lt_res INDEX lv_lines. + DELETE lt_res INDEX lv_lines. + + ELSE. + INSERT INITIAL LINE INTO lt_res ASSIGNING INDEX 1. + = 'TYPES:'. + + lv_lines = lines( lt_res ) - 2. + + READ TABLE lt_res ASSIGNING INDEX lv_lines. + TRANSLATE USING ',.'. + ADD 1 TO lv_lines. + + ENDIF. + + INSERT 'TYPES t_number TYPE p length 16 decimals 4.' INTO lt_res INDEX 1. + + IF p_normal IS INITIAL. + APPEND INITIAL LINE TO lt_res ASSIGNING . + = 'DATA'. + APPEND INITIAL LINE TO lt_res ASSIGNING . + = ': lo_data type ref to ZCL_EXCEL_TEMPLATE_DATA'. + APPEND INITIAL LINE TO lt_res ASSIGNING . + = '.'. + + ELSE. + APPEND INITIAL LINE TO lt_res ASSIGNING . + = 'DATA: lo_data type ref to ZCL_EXCEL_TEMPLATE_DATA.'. + ENDIF. + + cl_demo_output=>new( 'TEXT' )->display( lt_res ). +ENDFORM. + + +FORM get_type_r USING iv_sheet TYPE zexcel_sheet_title + iv_parent TYPE i + CHANGING ct_result TYPE tt_text. + + DATA: lt_buf TYPE tt_text, + lt_tmp TYPE tt_text, + lv_sum TYPE i, + lv_name TYPE string, + lv_type TYPE string, + lv_string TYPE string, + lt_sorted_counters TYPE TABLE OF i, + lv_biggest_counter TYPE i. + + FIELD-SYMBOLS: TYPE text80, + LIKE LINE OF go_template_filler->mt_range, + TYPE zcl_excel_fill_template=>ts_variable, + TYPE zcl_excel_fill_template=>ts_name_style. + + + CLEAR ct_result. + + LOOP AT go_template_filler->mt_range ASSIGNING WHERE sheet = iv_sheet + AND parent = iv_parent. + + PERFORM get_type_r + USING + iv_sheet + -id + CHANGING + lt_tmp. + + APPEND LINES OF lt_tmp TO lt_buf. + + + ENDLOOP. + + ADD sy-subrc TO lv_sum. + + IF iv_parent = 0. + lv_name = iv_sheet. + ELSE. + READ TABLE go_template_filler->mt_range ASSIGNING + WITH KEY sheet = iv_sheet + id = iv_parent. + lv_name = -name. + ENDIF. + + APPEND INITIAL LINE TO lt_buf ASSIGNING . + IF p_normal IS INITIAL. + CONCATENATE ', begin of t_' lv_name INTO . + ELSE. + CONCATENATE ' begin of t_' lv_name ',' INTO . + ENDIF. + + + LOOP AT go_template_filler->mt_var ASSIGNING WHERE sheet = iv_sheet + AND parent = iv_parent. + + READ TABLE go_template_filler->mt_name_styles + WITH KEY sheet = iv_sheet + name = -name + parent = iv_parent + ASSIGNING . + IF sy-subrc <> 0. + lv_type = 'string'. + ELSE. + CLEAR lt_sorted_counters. + APPEND -numeric_counter TO lt_sorted_counters. + APPEND -date_counter TO lt_sorted_counters. + APPEND -time_counter TO lt_sorted_counters. + APPEND -text_counter TO lt_sorted_counters. + SORT lt_sorted_counters BY table_line DESCENDING. + READ TABLE lt_sorted_counters INDEX 1 INTO lv_biggest_counter. + ASSERT sy-subrc = 0. + CASE lv_biggest_counter. + WHEN -numeric_counter. + lv_type = 't_number'. + WHEN -date_counter. + lv_type = 'd'. + WHEN -time_counter. + lv_type = 't'. + WHEN -text_counter. + lv_type = 'string'. + ENDCASE. + ENDIF. + + APPEND INITIAL LINE TO lt_buf ASSIGNING . + IF p_normal IS INITIAL. + CONCATENATE ', ' -name ' type ' lv_type INTO RESPECTING BLANKS. + ELSE. + CONCATENATE ' ' -name ' type ' lv_type ',' INTO RESPECTING BLANKS. + ENDIF. + + + ENDLOOP. + + ADD sy-subrc TO lv_sum. + + LOOP AT go_template_filler->mt_range ASSIGNING WHERE sheet = iv_sheet + AND parent = iv_parent. + + APPEND INITIAL LINE TO lt_buf ASSIGNING . + lv_string = -name. + IF p_normal IS INITIAL. + CONCATENATE ', ' -name ' type tt_' lv_string INTO RESPECTING BLANKS . + ELSE. + CONCATENATE ' ' -name ' type tt_' lv_string ',' INTO RESPECTING BLANKS . + ENDIF. + + + ENDLOOP. + + IF lv_sum > 4. + APPEND INITIAL LINE TO lt_buf ASSIGNING . + IF p_normal IS INITIAL. + = ', xz type i'. + ELSE. + = ' xz type i,'. + ENDIF. + + ENDIF. + + + APPEND INITIAL LINE TO lt_buf ASSIGNING . + IF p_normal IS INITIAL. + CONCATENATE ', end of t_' lv_name INTO . + ELSE. + CONCATENATE ' end of t_' lv_name ',' INTO . + ENDIF. + + APPEND INITIAL LINE TO lt_buf ASSIGNING . + + IF iv_parent NE 0. + APPEND INITIAL LINE TO lt_buf ASSIGNING . + IF p_normal IS INITIAL. + CONCATENATE ', tt_' lv_name ' type standard table of t_' lv_name ' with default key' INTO RESPECTING BLANKS . + ELSE. + CONCATENATE ' tt_' lv_name ' type standard table of t_' lv_name ' with default key,' INTO RESPECTING BLANKS . + ENDIF. + + ENDIF. + + APPEND INITIAL LINE TO lt_buf ASSIGNING . + + + ct_result = lt_buf. +ENDFORM. + +FORM load_smw0 + USING + io_reader TYPE REF TO zif_excel_reader + iv_w3objid TYPE w3objid + CHANGING + ro_excel TYPE REF TO zcl_excel + RAISING + zcx_excel. + + DATA: lv_excel_data TYPE xstring, + lt_mime TYPE TABLE OF w3mime, + ls_key TYPE wwwdatatab, + lv_errormessage TYPE string, + lv_filesize TYPE i, + lv_filesizec TYPE c LENGTH 10. + +*--------------------------------------------------------------------* +* Read file into binary string +*--------------------------------------------------------------------* + + ls_key-relid = 'MI'. + ls_key-objid = iv_w3objid . + + CALL FUNCTION 'WWWDATA_IMPORT' + EXPORTING + key = ls_key + TABLES + mime = lt_mime + EXCEPTIONS + OTHERS = 1. + IF sy-subrc <> 0. + lv_errormessage = 'A problem occured when reading the MIME object'(004). + zcx_excel=>raise_text( lv_errormessage ). + ENDIF. + + CALL FUNCTION 'WWWPARAMS_READ' + EXPORTING + relid = ls_key-relid + objid = ls_key-objid + name = 'filesize' + IMPORTING + value = lv_filesizec. + + lv_filesize = lv_filesizec. + CALL FUNCTION 'SCMS_BINARY_TO_XSTRING' + EXPORTING + input_length = lv_filesize + IMPORTING + buffer = lv_excel_data + TABLES + binary_tab = lt_mime + EXCEPTIONS + failed = 1 + OTHERS = 2. + +*--------------------------------------------------------------------* +* Parse Excel data into ZCL_EXCEL object from binary string +*--------------------------------------------------------------------* + ro_excel = io_reader->load( i_excel2007 = lv_excel_data ). + +ENDFORM. diff --git a/src/not_cloud/zexcel_template_get_types.prog.xml b/src/not_cloud/zexcel_template_get_types.prog.xml new file mode 100644 index 0000000..e48b857 --- /dev/null +++ b/src/not_cloud/zexcel_template_get_types.prog.xml @@ -0,0 +1,58 @@ + + + + + + ZEXCEL_TEMPLATE_GET_TYPES + 1 + T + E + X + X + + + + R + Generate ABAP code (Types) for template workbook + 48 + + + S + P_FILE + Load template from file + 31 + + + S + P_FPATH + Path to template.xlsx + 29 + + + S + P_NORMAL + Normal comma at end, + 28 + + + S + P_OBJID + Object ID + 17 + + + S + P_OTHER + , comma at begin of line + 37 + + + S + P_SMW0 + Load template from SMW0 + 31 + + + + + diff --git a/src/zcl_excel.clas.abap b/src/zcl_excel.clas.abap index 361eb6e..29a6b12 100644 --- a/src/zcl_excel.clas.abap +++ b/src/zcl_excel.clas.abap @@ -146,6 +146,11 @@ CLASS zcl_excel DEFINITION METHODS set_theme IMPORTING !io_theme TYPE REF TO zcl_excel_theme . + METHODS fill_template + importing + !iv_data TYPE REF TO ZCL_EXCEL_TEMPLATE_DATA + RAISING + zcx_excel . PROTECTED SECTION. DATA worksheets TYPE REF TO zcl_excel_worksheets . @@ -670,4 +675,26 @@ CLASS zcl_excel IMPLEMENTATION. METHOD zif_excel_book_vba_project~set_vbaproject. me->zif_excel_book_vba_project~vbaproject = ip_vbaproject. ENDMETHOD. + + + METHOD fill_template. + + DATA: lo_template_filler TYPE REF TO zcl_excel_fill_template. + + FIELD-SYMBOLS: + TYPE zexcel_sheet_title, + TYPE zcl_excel_template_data=>ts_template_data_sheet. + + + lo_template_filler = zcl_excel_fill_template=>create( me ). + + LOOP AT lo_template_filler->mt_sheet ASSIGNING . + + READ TABLE iv_data->mt_data ASSIGNING WITH KEY sheet = . + CHECK sy-subrc = 0. + lo_template_filler->fill_sheet( ). + + ENDLOOP. + + ENDMETHOD. ENDCLASS. diff --git a/src/zcl_excel_fill_template.clas.abap b/src/zcl_excel_fill_template.clas.abap new file mode 100644 index 0000000..f332eb5 --- /dev/null +++ b/src/zcl_excel_fill_template.clas.abap @@ -0,0 +1,649 @@ +CLASS zcl_excel_fill_template DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + + TYPES: tv_range_name TYPE c LENGTH 30, + BEGIN OF ts_range, + sheet TYPE zexcel_sheet_title, + name TYPE tv_range_name, + start TYPE zexcel_cell_row, + stop TYPE zexcel_cell_row, + id TYPE i, + parent TYPE i, + length TYPE i, + END OF ts_range, + tt_ranges TYPE STANDARD TABLE OF ts_range WITH DEFAULT KEY, + BEGIN OF ts_variable, + sheet TYPE zexcel_sheet_title, + parent TYPE i, + name TYPE tv_range_name, + END OF ts_variable, + BEGIN OF ts_name_style, + sheet TYPE zexcel_sheet_title, + name TYPE tv_range_name, + parent TYPE i, + numeric_counter TYPE i, + date_counter TYPE i, + time_counter TYPE i, + text_counter TYPE i, + END OF ts_name_style, + tt_variables TYPE STANDARD TABLE OF ts_variable WITH DEFAULT KEY, + tt_sheet_titles TYPE STANDARD TABLE OF zexcel_sheet_title WITH DEFAULT KEY, + tt_name_styles TYPE STANDARD TABLE OF ts_name_style WITH DEFAULT KEY. + + DATA mt_sheet TYPE tt_sheet_titles READ-ONLY. + DATA mt_range TYPE tt_ranges READ-ONLY. + DATA mt_var TYPE tt_variables READ-ONLY. + DATA mo_excel TYPE REF TO zcl_excel READ-ONLY. + DATA mt_name_styles TYPE tt_name_styles READ-ONLY. + + CLASS-METHODS create + IMPORTING + !io_excel TYPE REF TO zcl_excel + RETURNING + VALUE(eo_template_filler) TYPE REF TO zcl_excel_fill_template + RAISING + zcx_excel. + + METHODS fill_sheet + IMPORTING + !iv_data TYPE zcl_excel_template_data=>ts_template_data_sheet + RAISING + zcx_excel . + + PROTECTED SECTION. + PRIVATE SECTION. + + TYPES: tt_cell_data_no_key TYPE STANDARD TABLE OF zexcel_s_cell_data WITH DEFAULT KEY. + + METHODS fill_range + IMPORTING + !iv_sheet TYPE zexcel_sheet_title + !iv_parent TYPE zexcel_cell_row + !iv_data TYPE data + VALUE(iv_range_length) TYPE zexcel_cell_row + !io_sheet TYPE REF TO zcl_excel_worksheet + CHANGING + !ct_cells TYPE tt_cell_data_no_key + !cv_diff TYPE zexcel_cell_row + !ct_merged_cells TYPE zcl_excel_worksheet=>mty_ts_merge + RAISING + zcx_excel . + METHODS get_range . + METHODS validate_range + IMPORTING + !io_range TYPE REF TO zcl_excel_range . + METHODS discard_overlapped . + METHODS sign_range . + METHODS find_var + RAISING + zcx_excel . + +ENDCLASS. + + + +CLASS zcl_excel_fill_template IMPLEMENTATION. + + + METHOD create. + + CREATE OBJECT eo_template_filler . + + eo_template_filler->mo_excel = io_excel. + eo_template_filler->get_range( ). + eo_template_filler->discard_overlapped( ). + eo_template_filler->sign_range( ). + eo_template_filler->find_var( ). + + ENDMETHOD. + + METHOD discard_overlapped. + DATA: + lt_range TYPE tt_ranges. + FIELD-SYMBOLS: + TYPE ts_range, + TYPE ts_range. + + SORT mt_range BY sheet start stop. + + LOOP AT mt_range ASSIGNING . + + LOOP AT mt_range ASSIGNING WHERE sheet = -sheet + AND name <> -name + AND stop >= -start + AND start < -start + AND stop < -stop. + EXIT. + ENDLOOP. + + IF sy-subrc NE 0. + APPEND TO lt_range. + ENDIF. + + ENDLOOP. + + mt_range = lt_range. + + SORT mt_range BY sheet start stop DESCENDING. + + ENDMETHOD. + + + METHOD fill_range. + + DATA: lt_tmp_cells_template TYPE tt_cell_data_no_key, + lt_cells_result TYPE tt_cell_data_no_key, + lt_tmp_cells TYPE tt_cell_data_no_key, + ls_cell TYPE zexcel_s_cell_data, + lt_tmp_merged_cells_template TYPE zcl_excel_worksheet=>mty_ts_merge, + lt_merged_cells_result TYPE zcl_excel_worksheet=>mty_ts_merge, + lt_tmp_merged_cells TYPE zcl_excel_worksheet=>mty_ts_merge, + ls_merged_cell LIKE LINE OF lt_tmp_merged_cells, + lv_start_row TYPE i, + lv_stop_row TYPE i, + lv_cell_row TYPE i, + lv_column_alpha TYPE string, + lt_matches TYPE match_result_tab, + lv_search TYPE string, + lv_var_name TYPE string, + lv_cell_value TYPE string. + + FIELD-SYMBOLS: + TYPE ANY TABLE, + TYPE any, + TYPE ts_range, + TYPE zexcel_s_cell_data, + TYPE match_result, + TYPE any. + + + cv_diff = cv_diff + iv_range_length . + + lv_start_row = 1. + + +* recursive fill nested range + + LOOP AT mt_range ASSIGNING WHERE sheet = iv_sheet + AND parent = iv_parent. + + + lv_stop_row = -start - 1. + +* update cells before any range + + LOOP AT ct_cells INTO ls_cell WHERE cell_row >= lv_start_row AND cell_row <= lv_stop_row . + ls_cell-cell_row = ls_cell-cell_row + cv_diff. + lv_column_alpha = zcl_excel_common=>convert_column2alpha( ls_cell-cell_column ). + + ls_cell-cell_coords = ls_cell-cell_row. + CONCATENATE lv_column_alpha ls_cell-cell_coords INTO ls_cell-cell_coords. + CONDENSE ls_cell-cell_coords NO-GAPS. + + APPEND ls_cell TO lt_cells_result. + ENDLOOP. + + + +* update merged cells before range + + LOOP AT ct_merged_cells INTO ls_merged_cell WHERE row_from >= lv_start_row AND row_to <= lv_stop_row. + ls_merged_cell-row_from = ls_merged_cell-row_from + cv_diff. + ls_merged_cell-row_to = ls_merged_cell-row_to + cv_diff. + + APPEND ls_merged_cell TO lt_merged_cells_result. + + ENDLOOP. + + + + lv_start_row = -stop + 1. + + + + CLEAR: + lt_tmp_cells_template, + lt_tmp_merged_cells_template. + + +*copy cell template + LOOP AT ct_cells INTO ls_cell WHERE cell_row >= -start AND cell_row <= -stop. + APPEND ls_cell TO lt_tmp_cells_template. + ENDLOOP. + + LOOP AT ct_merged_cells INTO ls_merged_cell WHERE row_from >= -start AND row_to <= -stop. + APPEND ls_merged_cell TO lt_tmp_merged_cells_template. + ENDLOOP. + + + ASSIGN COMPONENT -name OF STRUCTURE iv_data TO
. + CHECK sy-subrc = 0. + + cv_diff = cv_diff - -length. + +*merge each line of data table with template + LOOP AT
ASSIGNING . +* make local copy + lt_tmp_cells = lt_tmp_cells_template. + lt_tmp_merged_cells = lt_tmp_merged_cells_template. + +*fill data + + fill_range( + EXPORTING + io_sheet = io_sheet + iv_sheet = iv_sheet + iv_parent = -id + iv_data = + iv_range_length = -length + CHANGING + ct_cells = lt_tmp_cells + ct_merged_cells = lt_tmp_merged_cells + cv_diff = cv_diff ). + +*collect data + + APPEND LINES OF lt_tmp_cells TO lt_cells_result. + APPEND LINES OF lt_tmp_merged_cells TO lt_merged_cells_result. + + ENDLOOP. + + ENDLOOP. + + + IF IS ASSIGNED. + + LOOP AT ct_cells INTO ls_cell WHERE cell_row > -stop . + ls_cell-cell_row = ls_cell-cell_row + cv_diff. + lv_column_alpha = zcl_excel_common=>convert_column2alpha( ls_cell-cell_column ). + + ls_cell-cell_coords = ls_cell-cell_row. + CONCATENATE lv_column_alpha ls_cell-cell_coords INTO ls_cell-cell_coords. + CONDENSE ls_cell-cell_coords NO-GAPS. + + APPEND ls_cell TO lt_cells_result. + ENDLOOP. + + ct_cells = lt_cells_result. + + LOOP AT ct_merged_cells INTO ls_merged_cell WHERE row_from > -stop. + ls_merged_cell-row_from = ls_merged_cell-row_from + cv_diff. + ls_merged_cell-row_to = ls_merged_cell-row_to + cv_diff. + + APPEND ls_merged_cell TO lt_merged_cells_result. + ENDLOOP. + + ct_merged_cells = lt_merged_cells_result. + + ELSE. + + + LOOP AT ct_cells ASSIGNING . + -cell_row = -cell_row + cv_diff. + lv_column_alpha = zcl_excel_common=>convert_column2alpha( -cell_column ). + + -cell_coords = -cell_row. + CONCATENATE lv_column_alpha -cell_coords INTO -cell_coords. + CONDENSE -cell_coords NO-GAPS. + ENDLOOP. + + LOOP AT ct_merged_cells INTO ls_merged_cell . + ls_merged_cell-row_from = ls_merged_cell-row_from + cv_diff. + ls_merged_cell-row_to = ls_merged_cell-row_to + cv_diff. + + APPEND ls_merged_cell TO lt_merged_cells_result. + ENDLOOP. + + ct_merged_cells = lt_merged_cells_result. + + ENDIF. + + +*check if variables in this range + READ TABLE mt_var TRANSPORTING NO FIELDS WITH KEY sheet = iv_sheet parent = iv_parent. + + IF sy-subrc = 0. + +* replace variables of current range with data + LOOP AT ct_cells ASSIGNING . + + + REFRESH lt_matches. + + lv_cell_value = -cell_value. + + FIND ALL OCCURRENCES OF REGEX '\[[^\]]*\]' IN -cell_value RESULTS lt_matches. + + SORT lt_matches BY offset DESCENDING . + + LOOP AT lt_matches ASSIGNING . + lv_search = -cell_value+-offset(-length). + lv_var_name = lv_search. + + TRANSLATE lv_var_name TO UPPER CASE. + TRANSLATE lv_var_name USING '[ ] '. + CONDENSE lv_var_name . + + ASSIGN COMPONENT lv_var_name OF STRUCTURE iv_data TO . + CHECK sy-subrc = 0. + + " Use SET_CELL to format correctly + io_sheet->set_cell( ip_column = -cell_column ip_row = -cell_row - cv_diff ip_value = ). + lv_cell_row = -cell_row - cv_diff. + READ TABLE io_sheet->sheet_content INTO ls_cell + WITH KEY cell_column = -cell_column + cell_row = lv_cell_row. + REPLACE ALL OCCURRENCES OF lv_search IN -cell_value WITH ls_cell-cell_value. + ENDLOOP. + + IF lines( lt_matches ) = 1. + lv_cell_row = -cell_row - cv_diff. + READ TABLE io_sheet->sheet_content INTO ls_cell + WITH KEY cell_column = -cell_column + cell_row = lv_cell_row. + -data_type = ls_cell-data_type. + ENDIF. + + ENDLOOP. + ENDIF. + + ENDMETHOD. + + + METHOD fill_sheet. + + DATA: lo_worksheet TYPE REF TO zcl_excel_worksheet, + lt_sheet_cells TYPE tt_cell_data_no_key, + lt_merged_cells TYPE zcl_excel_worksheet=>mty_ts_merge, + lt_merged_cells_2 TYPE zcl_excel_worksheet=>mty_ts_merge, + lv_initial_diff TYPE i. + FIELD-SYMBOLS: + TYPE any, + TYPE zexcel_s_cell_data, + TYPE zcl_excel_worksheet=>mty_merge. + + + lo_worksheet = mo_excel->get_worksheet_by_name( iv_data-sheet ). + + lt_sheet_cells = lo_worksheet->sheet_content. + lt_merged_cells = lo_worksheet->mt_merged_cells. + + ASSIGN iv_data-data->* TO . + + fill_range( + EXPORTING + io_sheet = lo_worksheet + iv_range_length = 0 + iv_sheet = iv_data-sheet + iv_parent = 0 + iv_data = + CHANGING + ct_cells = lt_sheet_cells + ct_merged_cells = lt_merged_cells + cv_diff = lv_initial_diff ). + + + REFRESH lo_worksheet->sheet_content. + + LOOP AT lt_sheet_cells ASSIGNING . + INSERT INTO TABLE lo_worksheet->sheet_content. + ENDLOOP. + + lt_merged_cells_2 = lo_worksheet->mt_merged_cells. + LOOP AT lt_merged_cells_2 ASSIGNING . + lo_worksheet->delete_merge( ip_cell_column = -col_from ip_cell_row = -row_from ). + ENDLOOP. + + LOOP AT lt_merged_cells ASSIGNING . + lo_worksheet->set_merge( + ip_column_start = -col_from + ip_column_end = -col_to + ip_row = -row_from + ip_row_to = -row_to ). + ENDLOOP. + + ENDMETHOD. + + + METHOD find_var. + + DATA: lv_row TYPE i, + lv_column TYPE i, + lv_column_alpha TYPE string, + lv_value TYPE string, + ls_name_style TYPE ts_name_style, + lo_style TYPE REF TO zcl_excel_style, + lo_worksheet TYPE REF TO zcl_excel_worksheet, + ls_variable TYPE ts_variable, + lv_highest_column TYPE zexcel_cell_column, + lv_highest_row TYPE int4, + lt_matches TYPE match_result_tab, + lv_search TYPE string, + lv_replace TYPE string. + + FIELD-SYMBOLS: + TYPE match_result, + TYPE ts_range, + TYPE zexcel_sheet_title, + TYPE ts_name_style. + + + LOOP AT mt_sheet ASSIGNING . + + lo_worksheet ?= mo_excel->get_worksheet_by_name( ). + lv_row = 1. + + lv_highest_column = lo_worksheet->get_highest_column( ). + lv_highest_row = lo_worksheet->get_highest_row( ). + + WHILE lv_row <= lv_highest_row. + lv_column = 1. + WHILE lv_column <= lv_highest_column. + lv_column_alpha = zcl_excel_common=>convert_column2alpha( lv_column ). + CLEAR lo_style. + lo_worksheet->get_cell( + EXPORTING + ip_column = lv_column_alpha + ip_row = lv_row + IMPORTING + ep_value = lv_value + ep_style = lo_style ). + + FIND ALL OCCURRENCES OF REGEX '\[[^\]]*\]' IN lv_value RESULTS lt_matches. + + LOOP AT lt_matches ASSIGNING . + lv_search = lv_value+-offset(-length). + lv_replace = lv_search. + + TRANSLATE lv_replace TO UPPER CASE. + + CLEAR ls_variable. + + ls_variable-sheet = . + ls_variable-name = lv_replace. + TRANSLATE ls_variable-name USING '[ ] '. + CONDENSE ls_variable-name . + + LOOP AT mt_range ASSIGNING WHERE sheet = + AND start <= lv_row + AND stop >= lv_row. + ls_variable-parent = -id. + EXIT. + ENDLOOP. + + READ TABLE mt_var TRANSPORTING NO FIELDS WITH KEY sheet = ls_variable-sheet name = ls_variable-name parent = ls_variable-parent. + IF sy-subrc NE 0. + APPEND ls_variable TO mt_var. + ENDIF. + + READ TABLE mt_name_styles WITH KEY sheet = ls_variable-sheet name = ls_variable-name parent = ls_variable-parent ASSIGNING . + IF sy-subrc NE 0. + CLEAR ls_name_style. + ls_name_style-sheet = . + ls_name_style-name = ls_variable-name. + ls_name_style-parent = ls_variable-parent. + APPEND ls_name_style TO mt_name_styles ASSIGNING . + ENDIF. + IF lo_style IS NOT BOUND. + -text_counter = -text_counter + 1. + ELSE. + IF lo_style->number_format->format_code CA '0' + AND lo_style->number_format->format_code NS '0]'. + -numeric_counter = -numeric_counter + 1. + ELSEIF lo_style->number_format->format_code CA 'm' + AND lo_style->number_format->format_code CA 'd' + AND lo_style->number_format->format_code NA 'h'. + -date_counter = -date_counter + 1. + ELSEIF ( lo_style->number_format->format_code CA 'h' OR lo_style->number_format->format_code CA 's' ) + AND lo_style->number_format->format_code NA 'd'. + -time_counter = -time_counter + 1. + ELSE. + -text_counter = -text_counter + 1. + ENDIF. + ENDIF. + + ENDLOOP. + lv_column = lv_column + 1. + ENDWHILE. + lv_row = lv_row + 1. + ENDWHILE. + ENDLOOP. + + SORT mt_range BY id . + ENDMETHOD. + + + METHOD get_range. + + DATA: + lo_worksheets_iterator TYPE REF TO cl_object_collection_iterator, + lo_worksheet TYPE REF TO zcl_excel_worksheet, + lo_range_iterator TYPE REF TO cl_object_collection_iterator, + lo_range TYPE REF TO zcl_excel_range. + + + lo_worksheets_iterator = mo_excel->get_worksheets_iterator( ). + + + WHILE lo_worksheets_iterator->has_next( ) = abap_true. + lo_worksheet ?= lo_worksheets_iterator->get_next( ). + APPEND lo_worksheet->get_title( ) TO mt_sheet. + ENDWHILE. + + lo_range_iterator = mo_excel->get_ranges_iterator( ). + + WHILE lo_range_iterator->has_next( ) = abap_true. + lo_range ?= lo_range_iterator->get_next( ). + validate_range( lo_range ). + ENDWHILE. + + ENDMETHOD. + + + METHOD sign_range. + + DATA: lv_tabix TYPE i. + FIELD-SYMBOLS: + TYPE ts_range, + TYPE ts_range. + + LOOP AT mt_range ASSIGNING . + -id = sy-tabix. + ENDLOOP. + + LOOP AT mt_range ASSIGNING . + lv_tabix = sy-tabix + 1. + + LOOP AT mt_range ASSIGNING + FROM lv_tabix + WHERE sheet = -sheet. + + IF -start >= -start AND -stop <= -stop. + -parent = -id. + ENDIF. + + ENDLOOP. + + ENDLOOP. + + SORT mt_range BY id DESCENDING. + ENDMETHOD. + + + METHOD validate_range. + + DATA: lv_range_name TYPE string, + lv_range_address TYPE string, + lv_range_start TYPE string, + lv_range_stop TYPE string, + lv_range_sheet TYPE string, + lv_tmp_value TYPE string, + lt_cell_coord_parts TYPE TABLE OF string, + lv_cell_coord_start TYPE string, + lv_cell_coord_stop TYPE string, + lv_column_start TYPE zexcel_cell_column_alpha, + lv_column_end TYPE zexcel_cell_column_alpha, + lv_row_start TYPE zexcel_cell_row, + lv_row_end TYPE zexcel_cell_row. + + FIELD-SYMBOLS: TYPE ts_range. + + + lv_range_name = io_range->name. + TRANSLATE lv_range_name TO UPPER CASE. + lv_range_address = io_range->get_value( ). + + SPLIT lv_range_address AT '!' INTO lv_range_sheet lv_tmp_value. + + SPLIT lv_tmp_value AT ':' INTO lv_range_start lv_range_stop. + + SPLIT lv_range_start AT '$' INTO TABLE lt_cell_coord_parts. + + IF lines( lt_cell_coord_parts ) > 2. + TRY. + zcl_excel_common=>convert_range2column_a_row( + EXPORTING + i_range = lv_range_address + IMPORTING + e_column_start = lv_column_start + e_column_end = lv_column_end + e_row_start = lv_row_start + e_row_end = lv_row_end + ). + CATCH zcx_excel. " + RETURN. + ENDTRY. + IF lv_column_start = 'A' AND lv_column_end = 'XFD'. + lv_cell_coord_start = |{ lv_row_start }|. + lv_cell_coord_stop = |{ lv_row_end }|. + CLEAR lt_cell_coord_parts. + CLEAR lv_range_stop. + ELSE. + RETURN. + ENDIF. + ENDIF. + + IF lines( lt_cell_coord_parts ) >= 2. + READ TABLE lt_cell_coord_parts INTO lv_cell_coord_start INDEX 2. + ENDIF. + + IF lv_cell_coord_start CO '0123456789'. + APPEND INITIAL LINE TO mt_range ASSIGNING . + -sheet = lv_range_sheet. + -name = lv_range_name. + -start = lv_cell_coord_start. + + SPLIT lv_range_stop AT '$' INTO TABLE lt_cell_coord_parts. + READ TABLE lt_cell_coord_parts INTO lv_cell_coord_stop INDEX 2. + -stop = lv_cell_coord_stop. + + -length = -stop - -start + 1. + + ENDIF. + + ENDMETHOD. +ENDCLASS. diff --git a/src/zcl_excel_fill_template.clas.xml b/src/zcl_excel_fill_template.clas.xml new file mode 100644 index 0000000..0797907 --- /dev/null +++ b/src/zcl_excel_fill_template.clas.xml @@ -0,0 +1,42 @@ + + + + + + ZCL_EXCEL_FILL_TEMPLATE + E + poopulate excell template with data + 1 + X + X + X + + + + ZCL_EXCEL_FILL_TEMPLATE + MO_EXCEL + E + Excel creator + + + ZCL_EXCEL_FILL_TEMPLATE + MT_RANGE + E + Range description + + + ZCL_EXCEL_FILL_TEMPLATE + MT_SHEET + E + table of sheet title + + + ZCL_EXCEL_FILL_TEMPLATE + MT_VAR + E + var description + + + + + diff --git a/src/zcl_excel_template_data.clas.abap b/src/zcl_excel_template_data.clas.abap new file mode 100644 index 0000000..709b778 --- /dev/null +++ b/src/zcl_excel_template_data.clas.abap @@ -0,0 +1,42 @@ +CLASS zcl_excel_template_data DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + + TYPES: tt_sheet_titles TYPE STANDARD TABLE OF zexcel_sheet_title WITH DEFAULT KEY, + BEGIN OF ts_template_data_sheet, + sheet TYPE zexcel_sheet_title, + data TYPE REF TO data, + END OF ts_template_data_sheet, + tt_template_data_sheets TYPE STANDARD TABLE OF ts_template_data_sheet WITH DEFAULT KEY. + + DATA mt_data TYPE tt_template_data_sheets READ-ONLY. + + METHODS add + IMPORTING + iv_sheet TYPE zexcel_sheet_title + iv_data TYPE data . + PROTECTED SECTION. + PRIVATE SECTION. +ENDCLASS. + + + +CLASS zcl_excel_template_data IMPLEMENTATION. + + + METHOD add. + FIELD-SYMBOLS: TYPE ts_template_data_sheet, + TYPE any. + + APPEND INITIAL LINE TO mt_data ASSIGNING . + -sheet = iv_sheet. + CREATE DATA -data LIKE iv_data. + + ASSIGN -data->* TO . + = iv_data. + + ENDMETHOD. +ENDCLASS. diff --git a/src/zcl_excel_template_data.clas.xml b/src/zcl_excel_template_data.clas.xml new file mode 100644 index 0000000..01a37db --- /dev/null +++ b/src/zcl_excel_template_data.clas.xml @@ -0,0 +1,16 @@ + + + + + + ZCL_EXCEL_TEMPLATE_DATA + E + Data for template + 1 + X + X + X + + + + diff --git a/src/zcl_excel_worksheet.clas.abap b/src/zcl_excel_worksheet.clas.abap index 3d74467..b077b47 100644 --- a/src/zcl_excel_worksheet.clas.abap +++ b/src/zcl_excel_worksheet.clas.abap @@ -71,6 +71,15 @@ CLASS zcl_excel_worksheet DEFINITION TYPE HASHED TABLE OF mty_s_column_formula WITH UNIQUE KEY id . TYPES ty_doc_url TYPE c LENGTH 255. + TYPES: + BEGIN OF mty_merge, + row_from TYPE i, + row_to TYPE i, + col_from TYPE i, + col_to TYPE i, + END OF mty_merge . + TYPES: + mty_ts_merge TYPE SORTED TABLE OF mty_merge WITH UNIQUE KEY table_line . CONSTANTS c_break_column TYPE zexcel_break VALUE 2. "#EC NOTEXT CONSTANTS c_break_none TYPE zexcel_break VALUE 0. "#EC NOTEXT @@ -90,6 +99,7 @@ CLASS zcl_excel_worksheet DEFINITION formula_not_in_this_table TYPE string, formula_in_other_column TYPE string, END OF c_messages. + DATA mt_merged_cells TYPE mty_ts_merge READ-ONLY . METHODS add_comment IMPORTING @@ -636,17 +646,8 @@ CLASS zcl_excel_worksheet DEFINITION mty_th_font_cache TYPE HASHED TABLE OF mty_s_font_cache WITH UNIQUE KEY font_name font_height flag_bold flag_italic . - TYPES: * types: * mty_ts_row_dimension TYPE SORTED TABLE OF zexcel_s_worksheet_rowdimensio WITH UNIQUE KEY row . - BEGIN OF mty_merge, - row_from TYPE i, - row_to TYPE i, - col_from TYPE i, - col_to TYPE i, - END OF mty_merge . - TYPES: - mty_ts_merge TYPE SORTED TABLE OF mty_merge WITH UNIQUE KEY table_line . *"* private components of class ZCL_EXCEL_WORKSHEET *"* do not include other source files here!!! @@ -668,7 +669,6 @@ CLASS zcl_excel_worksheet DEFINITION DATA lower_cell TYPE zexcel_s_cell_data . DATA mo_pagebreaks TYPE REF TO zcl_excel_worksheet_pagebreaks . CLASS-DATA mth_font_cache TYPE mty_th_font_cache . - DATA mt_merged_cells TYPE mty_ts_merge . DATA mt_row_outlines TYPE mty_ts_outlines_row . DATA print_title_col_from TYPE zexcel_cell_column_alpha . DATA print_title_col_to TYPE zexcel_cell_column_alpha .