Skip to Content
Technical Articles

ABAP Code to Internal Table as Excel File on SAP Application Server

I recently got a requirement to write a file on application server in excel format. This post explains how I reached to a solution and how to code the solution.


At first, I thought its very simple. The first thing I did – created a tab separated file with ‘.xlsx’ extension.

I could write the file. There is no issue there. The problem is, Excel does not open this file and simply says, it is not Excel file.

Then, I started experimenting or simply put Trial and Error method.

  • Changed extension to ‘.xls’
  • Toggled between writing modes TEXT and BINARY in OPEN DATASET
  • Toggled between downloading options – ASC and BIN formats (Using CG3Y) 
  • Tried accessing file at Unix Level and downloaded the file using WINSCP
  • Used Tab, Comma, Semi-Colon to separate file

None of these worked. I also searched over SAP blogs for some help. I did find below which says you can do this with using tabs.

Writing Excel file into Application Server using horizontal tab | SAP Blogs

But this method did not work for me. It continued to give the same error.

I did find few more discussions like below, but none with a satisfactory outcome and also some of them were very old.

Create XLS file on Application Server (no tab-delimited format) | SAP Community

Create excel file on application server | SAP Community

At this point, I was convinced that I should now try to convince the user who requested this to use .csv file. As .csv can be opened in Excel. I did try that but that did not work either.

Then I took a step back, started looking at it from different point of view and it struct me. Creating excel attachment works. Why not application server file?

Yes, I was providing the extension as ‘.xlsx’, but what I was writing was not Excel. The missing piece was that the contents were not transformed to Excel content. So, there it was – the solution.

So, I created below method for the transformation.


        IMPORTING ir_data_ref       TYPE REF TO data
        RETURNING VALUE(rv_xstring) TYPE xstring.

CLASS zcl_itab_to_excel IMPLEMENTATION.
  METHOD itab_to_xstring.


    CLEAR rv_xstring.
    ASSIGN ir_data_ref->* TO <fs_data>.

          IMPORTING r_salv_table = DATA(lo_table)
          CHANGING  t_table      = <fs_data> ).
        DATA(lt_fcat) = 
            r_columns      = lo_table->get_columns( )
            r_aggregations = lo_table->get_aggregations( ) ).

        DATA(lo_result) =
            r_data         = ir_data_ref
            t_fieldcatalog = lt_fcat ).

            xml_type      = if_salv_bs_xml=>c_type_xlsx
            xml_version   = cl_salv_bs_a_xml_base=>get_version( )
            r_result_data = lo_result
            xml_flavour   = if_salv_bs_c_tt=>c_tt_xml_flavour_export
            gui_type      = if_salv_bs_xml=>c_gui_type_gui
            xml           = rv_xstring ).
      CATCH cx_root.
        CLEAR rv_xstring.

And it worked very well. You simply need to pass your internal table reference to the method, get the excel content in xstring and transfer it to application server.

GET REFERENCE OF it_out_rec INTO DATA(lo_data_ref).
DATA(lv_xstring) = NEW zcl_itab_to_excel( )->itab_to_xstring( lo_data_ref ). 
IF sy-subrc EQ 0.
  TRANSFER lv_xstring TO lv_xls_file.


  • It is easy to create excel file on application server with help of the SALV and related classes
  • This method also works well if xlsx attachment is required to be sent in an email
  • This method also helps formatting the excel with aggregations and layout settings. Explore class cl_salv_controller_metadata for more details.

Your comments and suggestions are welcome to further improve this code. Please use the comment section below or you can also post your questions here.


– Jagdish Patil

You must be Logged on to comment or reply to a post.
    • Yes, I checked it, but I had to do this in a day and did not have time to try it out. And from the experience - we wont be able to use this on client's system. 

      It is however very interesting and I am currently trying to understand it. 

      • If I may ask, what was the issue with the client system, too old perhaps?

        I've had a colleague extend an existing custom report to use abap2xlsx in about half a day but I had already done the installation long before that, to try it out.

        • It may come down to restrictions as far as "just" grabbing source code (and potentially many other workbench objects) from "somewhere on the internet" and putting that into the productive system landscape. Not all companies will allow that.

          • I managed to get it into a validated system of a regulated industry with very tight processes.

            I asked the person responsible for the development platforms, and they wrote an exception to usual naming standards. Far too useful not to use abap2xlsx - saves an absolute fortune in programming and maintenance as well...

            I must admit when it came to trying to get it done another time, I just used the technique described here. But from one of these blogs...


          • Yes, I had used this technique to attach xlsx for an email. Tried the same thing and it worked.

            The only reason I posted it here that I thought it will help someone some day.

        • I've experienced once system owners who were against the use of open source solutions in ABAP. For example no abapGit. Crazy but true: the note of a lawyer. Liability for the use of open source must first be clarified. Technically it was all ok, but neither organizationally nor legally. What a day 😉

          • Ok, then I got lucky: customer's IT was very interested in this library! 🙂

            And also my colleague liked it, so it's already 2 installations 😀

  • Nice, you can also achieve the same result by simply calling this code instead of cl_salv_bs_tt_util=>if_salv_bs_tt_util~transform

    * lo_salv TYPE REF TO cl_salv_table
    DATA(l_xml) = lo_salv->to_xml( xml_type = if_salv_bs_xml=>c_type_xslx )
  • The Excel message is clear. "Excel cannot open the file 'Outtabxlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file." means that your file has the extension xlsx but the format inside it is not Office Open XML for Excel (what xlsx means), it's a text with tab-delimited values. If you have a text file with tab-delimited values, you should use the extension txt.

    There are other blog posts or answers about the same kind of logic, but you sum up very shortly. NB: 2 little remarks about your code, zcl_itab_to_excel=>convert_to_excel doesn't exist; you may also avoid the reference parameter ir_data_ref because anyway it can still fail if the internal table is read-only -you may instead duplicate the memory (unfortunately) by defining the internal table as a pass-by-value parameter-.

    It's also a nice solution for people who can't install abap2xlsx because of company policy.

    So, thanks for that!

    • Hi Sandra

      Thanks for pointing out the method name. I missed to change it where it is called. Updated now.

      On the parameter, it did not feel right to create a copy as the I was working with huge number of records, but can you explain a bit on the potential failure? In that case I would move the code where I already have the internal table instead of calling the method.

      • I would measure memory aspect. ABAP has optimised stuff in this area and I believe it uses a Copy-On-Write approach, meaning internally only one dataset exists until you change it. SALV doesn't change data so you should be OK there.

        What Sandra referred to was that SALV will fail on a readonly table. So if a method calls your method with its own importing parameter (these are always readonly), the ref will point to a readonly variable.

        METHOD foo.  "IMPORTING i_table
          excel = itab_to_excel->itab_to_xstring( REF #( i_table ) ).

        But anyhow my other reason for writing here was that I too started thinking "not another Excel export blog", but yours is actually a neat solution for simple 1:1 downloads. Sure abap2xlsx can do a lot more and is just as simple, but SALV is already available in every system and I learnt something new that it can do, so thanks 🙂

      • 2 other syntax errors found by using your code (missing parenthesis + it's an instance method):

                xml           = rv_xstring ).
          DATA(lv_xstring) = NEW zcl_itab_to_excel( )->itab_to_xstring( lo_data_ref ).

        Concerning my comment about "can still fail", here is the case to make the internal table read-only, it will fail when it tries to execute cl_salv_table=>factory (can be seen in debug, xstring is returned empty):

        CLASS lcl_app DEFINITION.
            CLASS-METHODS run IMPORTING it_out_rec TYPE any.
          METHOD run.
            DATA lo_data_ref TYPE REF TO data.
            GET REFERENCE OF it_out_rec INTO lo_data_ref.
            DATA(lv_xstring) = NEW zcl_itab_to_excel( )->itab_to_xstring( lo_data_ref ).
          SELECT * FROM sflight INTO TABLE @DATA(flights).
          lcl_app=>run( flights ).


        • As I mentioned in the post itself, I did search for this. All I could find was excel download to front end and that works fine. I did not find a single one for writing one to application server.

          If you do have it - please let me know. I will be happy to put that in the post so that we will have multiple solutions linked together when next time someone searches for this.

          • abap2xlsx definitely works for backend and has done since at least 2016 - it's fairly obvious that it does really, as its main output is an xstring which you can write anywhere. You could even send it out in a restful web service.

      • Well,

        Nothing personally about your own blog post,

        just mentioned the fact that every month a new post regarding export to an XLSX file is being published (and without SAP releases an official solution nor adopting the great ABAP2XLSX project).