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\ ' ).