Summary
If you need a simple way to generate some custom files this code might help you. I developed this to be able to download very fast very large internal tables from the application server to the local PC. This project started because I needed to download a lot of records (millions) in an Access and/or Excel file. The usual way (direct download to Access or Excel) failed because it was taking a lot of time, so I downloaded the tables as CSV files on the computer and another script (in VBA) imported them into the Access or Excel files. After testing this I managed to reduce the download time from 20 minutes (or more) to 30 seconds for the download plus another 10 seconds to import in the target file. I tested this with the MARA table.
In the example below I’ll show you how to create a generic file on the application server. This code was later used to generate a CSV file and download it on the local PC. This class features a browse and download function for the file and other helpful methods.
The code
The file represents an instance of the class ZCL_RAW_FILE
. Inside the class we have the property GV_FILE_CONTENT
that holds the contents of the file (table with header).
The class also has a property to hold the file’s name GV_FILE_NAME
and the file’s extension GV_FILE_EXTENSION
. Those two will be concatenated to generate the full name of the file when exported.
Other helpfull methods are: SAVE_TO_PATH
to start the GUI Download, BROWSE_FOR_SAVE_PATH
to browse for the path to download to, SET_FILE_EXTENSION
and SET_FILE_NAME
to change the file’ extension and name (the”.” will be automatically put in place), GET_FILE_SIZE
to query the current size of the file, the check_path
method to help you validate a path in case you ask the user to enter it manually.
types: tyt_raw_string TYPE STANDARD TABLE OF string WITH DEFAULT KEY . ... private section. data GV_FILE_EXTENSION type STRING . data GV_FILE_SIZE type INT4 . data GV_FILE_CONTENT type TYT_RAW_STRING . data GV_FILE_NAME type STRING .
There is also a property that holds the file’s size GV_FILE_SIZE. This is used when we need to know the current size of the file before exporting it to the local computer or before appending to it.
class ZCL_RAW_FILE
Here we have the code as it appears in the source code view. You can just copy it and the system will take care of it automatically.
class ZCL_RAW_FILE definition public create public . public section. class-methods BROWSE_FOR_SAVE_PATH returning value(MV_PATH) type STRING . methods SET_FILE_EXTENSION importing !MV_FILE_EXTENSION type STRING . methods CLEAR_CONTENTS . methods GET_FILE_SIZE returning value(MV_FILE_SIZE) type INT4 . methods SET_FILE_NAME importing !MV_FILE_NAME type STRING . methods CONSTRUCTOR importing !MV_ENCODING type STRING default SPACE !MV_FILE_NAME type STRING !MV_FILE_EXTENSION type STRING . methods SAVE_TO_PATH importing value(MV_SAVE_PATH) type STRING . methods ADD_LINE importing !MV_STRING_LINE type STRING . class-methods CHECK_PATH changing !MV_PATH_TO_CHECK type STRING returning value(MV_IS_CORRECT) type ABAP_BOOL . protected section. types: tyt_raw_string TYPE STANDARD TABLE OF string WITH DEFAULT KEY . data GV_FILE_ENCODING type ABAP_ENCOD value SPACE ##NO_TEXT. private section. data GV_FILE_EXTENSION type STRING . data GV_FILE_SIZE type INT4 . data GV_FILE_CONTENT type TYT_RAW_STRING . data GV_FILE_NAME type STRING . ENDCLASS. CLASS ZCL_RAW_FILE IMPLEMENTATION. * ---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_RAW_FILE->ADD_LINE * +-------------------------------------------------------------------------------------------------+ * | [--->] MV_STRING_LINE TYPE STRING * +-------------------------------------------------------------------------------------- METHOD ADD_LINE. " add the length of the new row to the file length plus the end of line terminators \n\r me->gv_file_size = me->gv_file_size + strlen( mv_string_line ) + 2. " append the contents to the file contents APPEND mv_string_line TO gv_file_content. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Static Public Method ZCL_RAW_FILE=>BROWSE_FOR_SAVE_PATH * +-------------------------------------------------------------------------------------------------+ * | [<-()] MV_PATH TYPE STRING * +-------------------------------------------------------------------------------------- METHOD browse_for_save_path. " call the GUI browse for folder dialog cl_gui_frontend_services=>directory_browse( EXPORTING window_title = 'Please select the folder to save to' initial_folder = 'c:\' CHANGING selected_folder = mv_path " here we get the selected path EXCEPTIONS cntl_error = 1 error_no_gui = 2 not_supported_by_gui = 3 OTHERS = 4 ). " if an error occured IF sy-subrc <> 0. " Implement suitable error handling here MESSAGE 'Folder selection failed' TYPE 'E'. ENDIF. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Static Public Method ZCL_RAW_FILE=>CHECK_PATH * +-------------------------------------------------------------------------------------------------+ * | [<-->] MV_PATH_TO_CHECK TYPE STRING * | [<-()] MV_IS_CORRECT TYPE ABAP_BOOL * +-------------------------------------------------------------------------------------- METHOD check_path. DATA: lo_regex TYPE REF TO cl_abap_regex, lo_matcher TYPE REF TO cl_abap_matcher. DATA: pos TYPE i, chr TYPE char01. * get the last character in string the path should look like: x:\zxy\...\ pos = strlen( mv_path_to_check ) - 1. chr = mv_path_to_check+pos. * Concatenates '\' at the end if the path does not end with it IF chr <> '\'. CONCATENATE mv_path_to_check '\' INTO mv_path_to_check. ENDIF. * Establishes the REGEX to check if the rest of the path is correct CREATE OBJECT lo_regex EXPORTING pattern = '^[a-zA-Z]:\\.*\\' ignore_case = abap_true. * Establishes the path to be checked CREATE OBJECT lo_matcher EXPORTING regex = lo_regex text = mv_path_to_check. * Confirms the path validity lo_matcher->match( RECEIVING success = mv_is_correct ). ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_RAW_FILE->CLEAR_CONTENTS * +-------------------------------------------------------------------------------------------------+ * +-------------------------------------------------------------------------------------- METHOD clear_contents. " clear the contents of the internal table CLEAR gv_file_content. " set the file size to zero gv_file_size = 0. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_RAW_FILE->CONSTRUCTOR * +-------------------------------------------------------------------------------------------------+ * | [--->] MV_ENCODING TYPE STRING (default =SPACE) * | [--->] MV_FILE_NAME TYPE STRING * | [--->] MV_FILE_EXTENSION TYPE STRING * +-------------------------------------------------------------------------------------- METHOD constructor. " initialize the size of the current file me->gv_file_size = 0. " set the file encoding me->gv_file_encoding = mv_encoding. " set the file's name me->set_file_name( EXPORTING mv_file_name = mv_file_name ). " and extension me->set_file_extension( EXPORTING mv_file_extension = mv_file_extension ). ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_RAW_FILE->GET_FILE_SIZE * +-------------------------------------------------------------------------------------------------+ * | [<-()] MV_FILE_SIZE TYPE INT4 * +-------------------------------------------------------------------------------------- METHOD GET_FILE_SIZE. " return the current file's size mv_file_size = me->gv_file_size. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_RAW_FILE->SAVE_TO_PATH * +-------------------------------------------------------------------------------------------------+ * | [--->] MV_SAVE_PATH TYPE STRING * +-------------------------------------------------------------------------------------- METHOD save_to_path. DATA: lv_complete_file_name TYPE string, lv_path_is_correct TYPE abap_bool VALUE abap_true. " check if the given path is correct zcl_raw_file=>check_path( CHANGING mv_path_to_check = mv_save_path RECEIVING mv_is_correct = lv_path_is_correct ). IF lv_path_is_correct = abap_true. IF gv_file_extension IS NOT INITIAL. " create the complete path + file name + extension CONCATENATE mv_save_path gv_file_name gv_file_extension INTO lv_complete_file_name. ELSE. " create the complete path + file name + extension CONCATENATE mv_save_path gv_file_name INTO lv_complete_file_name. ENDIF. " call GUI download function CALL FUNCTION 'GUI_DOWNLOAD' EXPORTING filename = lv_complete_file_name codepage = me->gv_file_encoding TABLES data_tab = me->gv_file_content. " if errors occured display a message IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. ELSE. " abort the save process if an incorrect path is found MESSAGE 'Incorrect path, aborting export.' TYPE 'E'. ENDIF. ENDMETHOD. * ---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_RAW_FILE->SET_FILE_EXTENSION * +-------------------------------------------------------------------------------------------------+ * | [--->] MV_FILE_EXTENSION TYPE STRING * +-------------------------------------------------------------------------------------- method SET_FILE_EXTENSION. " set the current file's extension me->gv_file_extension = mv_file_extension. endmethod. * ---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_RAW_FILE->SET_FILE_NAME * +-------------------------------------------------------------------------------------------------+ * | [--->] MV_FILE_NAME TYPE STRING * +-------------------------------------------------------------------------------------- method SET_FILE_NAME. " set the current file's name me->gv_file_name = mv_file_name. endmethod. ENDCLASS.
Example of use
After building the class you can use it as follows:
" variables related to the file to which we export DATA: lo_my_file TYPE REF TO zcl_csv_file, " file that is generated lv_current_file_length TYPE i, " the current length of the current file lv_path_to_save TYPE string. " the path where you save the file * create the file object CREATE OBJECT lo_my_file EXPORTING mv_file_name = 'my_file' mv_file_extension = 'txt' . * You can use the static method to browse for a path on the local host lv_path_to_save = zcl_csv_file=>browse_for_save_path * Write the first line in the first file lo_my_file->add_line( 'some text on the first line' ). * get the file size lv_current_file_length = lo_my_file->get_file_size( ). * then save the current data to the file lo_my_file->save_to_path( lv_path_to_save ). * clear the contents lo_my_file->clear_contents( ). * change the file name lo_my_file->set_file_name( 'my_second_file' ). * add some other line to the file lo_my_file->add_line( 'second line in the file' ). * save it again with the new contents lo_my_file->save_to_path( 'c:\folder\ ' ).