class ZCL_EXCEL_COMMON definition public final create public . public section. *"* public components of class ZCL_EXCEL_COMMON *"* do not include other source files here!!! constants C_EXCEL_BASELINE_DATE type D value '19000101'. "#EC NOTEXT class-data C_EXCEL_NUMFMT_OFFSET type INT1 value 164. "#EC NOTEXT . constants C_EXCEL_SHEET_MAX_COL type INT4 value 16384. "#EC NOTEXT constants C_EXCEL_SHEET_MIN_COL type INT4 value 1. "#EC NOTEXT class-data C_SPRAS_EN type SPRAS value 'E'. "#EC NOTEXT . class-data O_CONV type ref to CL_ABAP_CONV_OUT_CE . class-methods CONVERT_COLUMN2ALPHA importing !IP_COLUMN type ZEXCEL_CELL_COLUMN returning value(EP_COLUMN) type ZEXCEL_CELL_COLUMN_ALPHA . class-methods CONVERT_COLUMN2INT importing !IP_COLUMN type ZEXCEL_CELL_COLUMN_ALPHA returning value(EP_COLUMN) type ZEXCEL_CELL_COLUMN . class-methods CONVERT_COLUMNROW2COLUMN_A_ROW importing !I_COLUMNROW type STRING exporting !E_COLUMN type ZEXCEL_CELL_COLUMN_ALPHA !E_ROW type ZEXCEL_CELL_ROW . class-methods CONVERT_RANGE2COLUMN_A_ROW importing !I_RANGE type STRING exporting !E_COLUMN_START type ZEXCEL_CELL_COLUMN_ALPHA !E_COLUMN_END type ZEXCEL_CELL_COLUMN_ALPHA !E_ROW_START type ZEXCEL_CELL_ROW !E_ROW_END type ZEXCEL_CELL_ROW !E_SHEET type ZEXCEL_SHEET_TITLE . class-methods DATE_TO_EXCEL_STRING importing !IP_VALUE type D returning value(EP_VALUE) type ZEXCEL_CELL_VALUE . class-methods ENCRYPT_PASSWORD importing !I_PWD type ZEXCEL_AES_PASSWORD returning value(R_ENCRYPTED_PWD) type ZEXCEL_AES_PASSWORD . class-methods ESCAPE_STRING importing !IP_VALUE type STRING returning value(EP_ESCAPED_VALUE) type STRING . class-methods EXCEL_STRING_TO_DATE importing !IP_VALUE type ZEXCEL_CELL_VALUE returning value(EP_VALUE) type D . class-methods EXCEL_STRING_TO_TIME importing !IP_VALUE type ZEXCEL_CELL_VALUE returning value(EP_VALUE) type T . class-methods GET_FIELDCATALOG importing !IP_TABLE type STANDARD TABLE returning value(EP_FIELDCATALOG) type ZEXCEL_T_FIELDCATALOG . class-methods NUMBER_TO_EXCEL_STRING importing value(IP_VALUE) type NUMERIC returning value(EP_VALUE) type ZEXCEL_CELL_VALUE . class-methods TIME_TO_EXCEL_STRING importing !IP_VALUE type T returning value(EP_VALUE) type ZEXCEL_CELL_VALUE . *"* protected components of class ZCL_EXCEL_COMMON *"* do not include other source files here!!! protected section. private section. *"* private components of class ZCL_EXCEL_COMMON *"* do not include other source files here!!! class-data C_EXCEL_COL_MODULE type INT2 value 64. "#EC NOTEXT . class-methods CHAR2HEX importing !I_CHAR type CHAR1 returning value(R_HEX) type ZEXCEL_PWD_HASH . class-methods SHL01 importing !I_PWD_HASH type ZEXCEL_PWD_HASH returning value(R_PWD_HASH) type ZEXCEL_PWD_HASH . class-methods SHR14 importing !I_PWD_HASH type ZEXCEL_PWD_HASH returning value(R_PWD_HASH) type ZEXCEL_PWD_HASH . *"* local class implementation for public class *"* use this source file for the implementation part of *"* local helper classes *"* use this source file for any type declarations (class *"* definitions, interfaces or data types) you need for method *"* implementation or private method's signature *"* use this source file for any macro definitions you need *"* in the implementation part of the class method CHAR2HEX. IF o_conv IS NOT BOUND. o_conv = cl_abap_conv_out_ce=>create( endian = 'L' ignore_cerr = 'X' replacement = '#' ). ENDIF. CALL METHOD o_conv->reset( ). CALL METHOD o_conv->write( data = i_char ). r_hex+1 = o_conv->get_buffer( ). " x'65' must be x'0065' endmethod. method CONVERT_COLUMN2ALPHA. DATA: lo_conv TYPE REF TO cl_abap_conv_in_ce, lv_uccpi TYPE i, lv_text TYPE sychar02, lv_module TYPE int4, lv_column TYPE zexcel_cell_column. lv_column = ip_column. WHILE lv_column GT 0. lv_module = ( lv_column - 1 ) MOD 26. lv_uccpi = 65 + lv_module. lv_column = ( lv_column - lv_module ) / 26. lv_text = cl_abap_conv_in_ce=>uccpi( lv_uccpi ). CONCATENATE lv_text ep_column INTO ep_column. ENDWHILE. endmethod. method CONVERT_COLUMN2INT. DATA: lv_uccpi TYPE i, lv_factor TYPE i, lv_offset TYPE i, lv_char TYPE c, lv_column TYPE ZEXCEL_CELL_COLUMN_ALPHA. * Upper case lv_column = ip_column. TRANSLATE lv_column TO UPPER CASE. CONDENSE lv_column NO-GAPS. * Get string lenght and align to right lv_offset = 3 - STRLEN( lv_column ). SHIFT lv_column RIGHT BY lv_offset PLACES. * Claculate column position DO 3 TIMES. lv_offset = sy-index - 1. lv_char = lv_column+lv_offset(1). if lv_char IS INITIAL. CONTINUE. ENDIF. lv_uccpi = cl_abap_conv_out_ce=>uccpi( lv_char ). lv_factor = 26 ** ( 3 - sy-index ). ep_column = ep_column + ( lv_uccpi MOD zcl_excel_common=>c_excel_col_module ) * lv_factor. ENDDO. endmethod. method CONVERT_COLUMNROW2COLUMN_A_ROW. DATA: width TYPE i, col_width TYPE i, row_str TYPE string, col_str TYPE string. width = strlen( i_columnrow ). col_width = width. col_str = i_columnrow. WHILE col_str CA '0123456789'. col_width = col_width - 1. col_str = i_columnrow(col_width). ENDWHILE. e_column = col_str. width = width - col_width. row_str = i_columnrow+col_width(width). e_row = row_str. endmethod. METHOD convert_range2column_a_row. DATA: sheet TYPE string, range TYPE string, columnrow_start TYPE string, columnrow_end TYPE string. IF i_range IS INITIAL OR NOT i_range CS ':'. RETURN. ENDIF. IF i_range CS '!'. SPLIT i_range AT '!' INTO sheet range. e_sheet = sheet. ELSE. range = i_range. ENDIF. REPLACE ALL OCCURRENCES OF '$' IN range WITH ''. SPLIT range AT ':' INTO columnrow_start columnrow_end. convert_columnrow2column_a_row( EXPORTING i_columnrow = columnrow_start IMPORTING e_column = e_column_start e_row = e_row_start ). convert_columnrow2column_a_row( EXPORTING i_columnrow = columnrow_end IMPORTING e_column = e_column_end e_row = e_row_end ). ENDMETHOD. method DATE_TO_EXCEL_STRING. DATA: lv_date_diff TYPE i. CHECK ip_value IS NOT INITIAL. lv_date_diff = ip_value - c_excel_baseline_date + 2. ep_value = zcl_excel_common=>number_to_excel_string( ip_value = lv_date_diff ). endmethod. method ENCRYPT_PASSWORD. DATA lv_curr_offset TYPE i. DATA lv_curr_char TYPE c LENGTH 1. DATA lv_curr_hex TYPE zexcel_pwd_hash. DATA lv_pwd_len TYPE zexcel_pwd_hash. DATA lv_pwd_hash TYPE zexcel_pwd_hash. CONSTANTS: lv_0x7fff TYPE zexcel_pwd_hash VALUE '7FFF', lv_0x0001 TYPE zexcel_pwd_hash VALUE '0001', lv_0xce4b TYPE zexcel_pwd_hash VALUE 'CE4B'. DATA lv_pwd TYPE zexcel_aes_password. lv_pwd = i_pwd(15). lv_pwd_len = STRLEN( lv_pwd ). lv_curr_offset = lv_pwd_len - 1. WHILE lv_curr_offset GE 0. lv_curr_char = lv_pwd+lv_curr_offset(1). lv_curr_hex = char2hex( lv_curr_char ). lv_pwd_hash = ( shr14( lv_pwd_hash ) BIT-AND lv_0x0001 ) BIT-OR ( shl01( lv_pwd_hash ) BIT-AND lv_0x7fff ). lv_pwd_hash = lv_pwd_hash BIT-XOR lv_curr_hex. SUBTRACT 1 FROM lv_curr_offset. ENDWHILE. lv_pwd_hash = ( shr14( lv_pwd_hash ) BIT-AND lv_0x0001 ) BIT-OR ( shl01( lv_pwd_hash ) BIT-AND lv_0x7fff ). lv_pwd_hash = lv_pwd_hash BIT-XOR lv_0xce4b. lv_pwd_hash = lv_pwd_hash BIT-XOR lv_pwd_len. WRITE lv_pwd_hash TO r_encrypted_pwd. endmethod. method ESCAPE_STRING. DATA lv_value TYPE string. lv_value = ip_value. REPLACE ALL OCCURRENCES OF `'` IN lv_value WITH `''`. IF lv_value CP '* *'. CONCATENATE `'` lv_value `'` INTO lv_value . ENDIF. ep_escaped_value = lv_value. endmethod. method EXCEL_STRING_TO_DATE. DATA: lv_date_int TYPE i. TRY . lv_date_int = ip_value. ep_value = lv_date_int + c_excel_baseline_date - 2. CATCH cx_sy_conversion_error. CLEAR ep_value. ENDTRY. endmethod. method EXCEL_STRING_TO_TIME. DATA: lv_seconds_in_day TYPE i, lv_day_fraction TYPE f, lc_seconds_in_day TYPE i VALUE 86400. TRY. lv_day_fraction = ip_value. lv_seconds_in_day = lv_day_fraction * lc_seconds_in_day. ep_value = lv_seconds_in_day. CATCH cx_sy_conversion_error. CLEAR ep_value. ENDTRY. endmethod. method GET_FIELDCATALOG. DATA: lr_data TYPE REF TO data, lo_structdescr TYPE REF TO cl_abap_structdescr, lo_elemdescr TYPE REF TO cl_abap_elemdescr, lt_dfies TYPE ddfields, ls_dfies TYPE dfies, lv_sytabix TYPE sytabix, ls_fieldcatalog TYPE zexcel_s_fieldcatalog, lt_components TYPE abap_component_tab, ls_component LIKE LINE OF lt_components. CREATE DATA lr_data LIKE LINE OF ip_table. lo_structdescr ?= cl_abap_structdescr=>describe_by_data_ref( lr_data ). "for DDIC structure get the info directly IF lo_structdescr->is_ddic_type( ) = abap_true. lt_dfies = lo_structdescr->get_ddic_field_list( ). LOOP AT lt_dfies INTO ls_dfies. CLEAR ls_fieldcatalog. MOVE-CORRESPONDING ls_dfies TO ls_fieldcatalog. APPEND ls_fieldcatalog TO ep_fieldcatalog. ENDLOOP. ELSE. "if structure is not DDIC check components lt_components = lo_structdescr->get_components( ). LOOP AT lt_components INTO ls_component. lv_sytabix = sy-tabix. CLEAR ls_fieldcatalog. lo_elemdescr ?= ls_component-type. "component is DDIC IF lo_elemdescr->is_ddic_type( ) = abap_true. ls_dfies = lo_elemdescr->get_ddic_field( ). MOVE-CORRESPONDING ls_dfies TO ls_fieldcatalog. ls_fieldcatalog-fieldname = ls_component-name. ELSE. "component is not DDIC -> return minimum information required ls_fieldcatalog-fieldname = ls_component-name. ls_fieldcatalog-dynpfld = abap_true. ls_fieldcatalog-scrtext_m = ls_component-name. ENDIF. ls_fieldcatalog-position = lv_sytabix. APPEND ls_fieldcatalog TO ep_fieldcatalog. ENDLOOP. ENDIF. endmethod. method NUMBER_TO_EXCEL_STRING. DATA: lv_value_c TYPE c LENGTH 100. WRITE ip_value TO lv_value_c EXPONENT 0 NO-GROUPING NO-SIGN. REPLACE ALL OCCURRENCES OF ',' IN lv_value_c WITH '.'. ep_value = lv_value_c. CONDENSE ep_value. IF ip_value < 0. CONCATENATE '-' ep_value INTO ep_value. ELSEIF ip_value EQ 0. ep_value = '0'. ENDIF. endmethod. method SHL01. DATA: lv_bit TYPE i, lv_curr_pos TYPE i VALUE 2, lv_prev_pos TYPE i VALUE 1. DO 15 TIMES. GET BIT lv_curr_pos OF i_pwd_hash INTO lv_bit. SET BIT lv_prev_pos OF r_pwd_hash TO lv_bit. ADD 1 TO lv_curr_pos. ADD 1 TO lv_prev_pos. ENDDO. SET BIT 16 OF r_pwd_hash TO 0. endmethod. method SHR14. DATA: lv_bit TYPE i, lv_curr_pos TYPE i, lv_next_pos TYPE i. r_pwd_hash = i_pwd_hash. DO 14 TIMES. lv_curr_pos = 15. lv_next_pos = 16. DO 15 TIMES. GET BIT lv_curr_pos OF r_pwd_hash INTO lv_bit. SET BIT lv_next_pos OF r_pwd_hash TO lv_bit. SUBTRACT 1 FROM lv_curr_pos. SUBTRACT 1 FROM lv_next_pos. ENDDO. SET BIT 1 OF r_pwd_hash TO 0. ENDDO. endmethod. method TIME_TO_EXCEL_STRING. DATA: lv_seconds_in_day TYPE i, lv_day_fraction TYPE f, lc_time_baseline TYPE t VALUE '000000', lc_seconds_in_day TYPE i VALUE 86400. lv_seconds_in_day = ip_value - lc_time_baseline. lv_day_fraction = lv_seconds_in_day / lc_seconds_in_day. ep_value = zcl_excel_common=>number_to_excel_string( ip_value = lv_day_fraction ). endmethod.