Skip to Content
Personal Insights
Author's profile photo Paul Hardy

Monthly ABAP to EXCEL Blog – February 2023

Monthly ABAP to EXCEL Blog – February 2023

For over ten years now every month on the SAP Community Site someone publishes a blog about how to upload/download data from EXCEL to ABAP. So, I am going to start doing this as well – only I will always be talking about ABAP2XLSX as the preferred mechanism to do this.


Excel Blogs

The 120 blogs posted over the last ten years usually never mention ABAP2XLSX at all. They either talk about the archaic OLE technology that can be used to communicate with Microsoft products or re-invent the ABAP2XLSX concept.

Then myself and about three or four other people (the “usual suspects” as I call them) will post in the comments section talking about ABAP2XLSX and the original poster will either admit they had never heard of ABAP2XLSX or sometimes get all offended and say of course they had heard of it, just forgot to mention in their blog.

The most wonderful thing that happened this week was that as an experiment someone got CHAT GPT to write a blog on how to download from ABAP to Excel. It did a better job than some of the hundreds I have read.

Anyway, to fight back I am going to try an explain ABAP2XLSX as best I can and why it is a Good Thing.

The last blog in this new series I posted can be found at: –


Now in some ways I am going to start off by shooting myself in the foot. As well as putting example code I am going to also create a public GitHub repository so people can download the examples via abapGit.

This immediately begs the question – if the reason assorted people do not want to use ABAP2XLSX is because of a hatred/fear of anything remotely open-source plus a fictitious “no open-source” policy then why in the world would they go anywhere near GitHub in a billion years? The answer is of course they will not, but as it turns out the no open-source brigade have no problem at all copying code off an SCN blog into their development systems – after all if they had a problem with that concept then why in the world would they post their own code on SCN every month and expect other people to download that code to their development systems?

Monsieur Example-Mousse

A lot of examples on the internet – and indeed the standard ABAP2XLSX demo programs – are divorced from any actual use cases and consist of an executable program which does whatever is being demonstrated in as few lines as possible so as not to distract from the point being made.

That makes sense does it not? But I cannot do it. I cannot write a program, even as an example, which just has everything after START-OF-SELECTION in a big, coagulated mass without even any FORM routines, let alone methods.

So, I am going to shoot myself in the foot again and have an example OO program with methods. The reason that is such a bad decision of my part is that many of the opponents of ABAP2XLSX dislike it because it is all classes and methods and new-fangled nonsense like that.

However, if after 23 years every new ABAP code example on the internet is still made up of all FORM routines, then new people will still think FORM routines are the go.

The B-side is that for incredibly simple example OO programs take one billion times more code than the procedural code – leading the observation that whilst reading a blog about transforming a procedural program to the OO equivalent someone said “the <better> the code gets the longer and more complicated it is”. Meaning it is not better at all.

I would of course disagree on the grounds that in the real-world simple programs never stay simple – they expand at a geometric rate and once a program reaches a certain (quite small really) size then it is easier to maintain it going forward if it is written in an OO manner.

I will however make a slight compromise and use – for the example data – SFLIGHT as opposed to Monsters.

Use Casey Jones, Working on the Railroad

So as a starting point we are going to be displaying the good old SFLIGHT table in class CL_SALV_TABLE (which is not editable by the way, did I ever mention that?)

Much as the IT world hates it the truth is that 99.99% of data generated out of SAP reports ends up getting downloaded to Excel and then having all sorts of further processing done on that data at the Excel level. This is so called “Spreadsheet Hell” – so called by software vendors who are trying to convince you to stop using Excel altogether and buy their alternative instead.

As another alternative perhaps another way forward is to stop trying to be King Canute and ordering the tide to go back out but instead working with reality and improving the bi-directional integration between SAP and Excel.

With ABAP2XLSX you have three options once you have turned your ALV grid into a spreadsheet: –

  • Show that spreadsheet “in place” embedded inside the SAP GUI
  • Download the spreadsheet to your local PC
  • Email the spreadsheet to yourself or someone else (who will then open the XLSX attachment and then download it to their local PC if they feel like it)

The standard ABAP2XLSX demo programs let you do all three, but in my example, I am going to focus on the emailing aspect. I have found in real life this is the most widely used scenario. Often the amount of data is too large to run the program online and then download it, and I have not used the “in-place” option enough to be able to talk with any authority about it.

So, the end user is going to input some SFLIGHT selection criteria, an ALV grid will appear if run in the foreground and if a box is ticked an email will be sent to the selected email address (even if the program is run in the background) and that email will contain an XLSX version of the ALV grid.

Over-Complicated, Overpaid, and Over Here

As mentioned before the initial version of the example program will seem like a violently over-complicated program, all full of classes that do one thing only (the so-called single responsibility principle or SRP which is the S in SOLID). Given that the program at this stage is doing hardly anything at all some people will throw their hands up in the air and walk away screaming “this OO nonsense arrived in ABAP in the year 2000 – no wonder no-one ever used it!”. The program is even going to have a unit test section – empty initially – leading to some other people screaming “this unit testing nonsense was developed in 1944 – no wonder no-one ever uses it!”.

Max Bygraves – I Wanna Tell You a GitHub Repository

The GitHub repository for the evolving demonstration program is going to be


using local package $ABAP2XLSX_PDH_DEMO. There will be several versions of the same program (Z_ABAP2XLSX_PDH_DEMO) one per blog, and you can download them to your development system using abapGit (which again many people will hate the very idea of, even though SAP itself is starting to supply software via this medium e.g., the “Code Pal”)

Class Warfare

This is going to be an executable program comprised of a big bunch of local classes, with the entry point coming straight after START-OF-SELECTION.

  • Model – responsible for all business logic (there will be none initially)
  • Test Class – to do unit tests on the business logic in the model
  • Persistency Layer – responsible for database access
  • View – responsible for displaying the data – here we use CL_SALV_TABLE
  • Controller – responsible for linking the model and the view. This class can handle user commands received from the view. If no business logic involved it can handle them itself, if business logic is involved it can call upon the model.
  • Selection-Options – this (as might be expected) is responsible for storing the selection-options entered by the user. We do this because we do not like global variables and SELECT-OPTIONS are global variables. There have been half a zillion attempts on the SCN to do this in the best possible OO way, none of them optimal. My way is not optimal either, but I have yet to find a better way.
  • Application – a class that acts like a conductor and makes all the other classes play their musical instruments properly in the correct order. In could be argued this is not strictly needed, I could have the controller do this, but what if one day the program gets so complex there are multiple MVC constructs, some of which are global?

This is nothing AT ALL do with ABAP2XLSX – You Fiend!

In my mind (such as it is) everything is interlinked – OO programming, Test Driven Development, ABAP2XLSX and so on. No-one is using any of it, and everybody needs to. Thus, I keep on about every aspect, all at once, forever, like a broken record.

You will have noted that in the above list of classes I have not even mentioned ABAP2XLSX at all yet, thus proving my madness once again. At first glance it is difficult to see where ABAP2XLSX fits into the MVC equation. We are going to be sending the data to the end user in the form of a spreadsheet – so that is like a view i.e., a representation of the data viewable by a human just like the GUI representation provided by CL_SALV_TABLE (which is not editable by the way). Yet the exact appearance of the spreadsheet e.g., conditional formatting and what have you is 100% based on business logic which is the job of the model. Put another way only the model knows if a value in a cell is invalid, but only the view knows how to colour that cell red.

Put like that the answer is obvious – the spreadsheet is another view i.e., another way of displaying the same data. Another view could be a Gateway link to a ten-foot-tall robot frog which tells you jokes about the data in the model and so on. The controller can use some sort of logic to decide which type of view is most appropriate to send the data to the end user. You could have multiple models and only one view, you could have only one model and lots of views. See how complicated this is? That might seem like madness at first glance, but it is a complicated world, and thus you need as much flexibility as you can.

View to a Kill

In “The Robots of Death” there was something like the MVC pattern. There was one “Super-Voc” which had all the business logic of the mining craft and controlled all the other robots. Then you have the “Vocs” (controllers) which obeyed the Super-Voc (model) but could also respond to user commands from the human crew. Lastly you had the “dums” (views) which actually did all the work but had no intelligence whatsoever they just did whatever the controllers told them, orders which could have come from the model or from user-commands received by the controller. In that story the robots killed all the humans but let’s not go there apart from that it is a good analogy.

Therefore, when I am designing an ALV report I put all the “smarts” in the model e.g., what columns are hidden, sort order, what cells are invalid and should be highlighted and so on, and then the controller can pass them into whatever view is going to present the information to the end user. That way you do not have to duplicate that business logic in different views. As soon as you start duplicating code in different places it starts to drift apart the very next day. So, if I want to highlight a cell because the value is above a threshold then the model indicates this and an ALV view gives that cell a red background and the generated spreadsheet does the exact same but the underlying technology is very different.

Now, I know what you are going to say next – in this example the XLSX view is going to not only create an XML representation of the data (that can be viewed as a spreadsheet) but also send that data as an attachment in an email. Is not only creating such data but also emailing such data – two different things and therefore should you not have two different classes?

I say back to you – are you crazy? Why do you always have to over-complicate everything? This is just a simple example for goodness’ sake! Let us just stick with one local XLSX view class for now thank you very much and then maybe we can split it up later in a subsequent version.

Code in the Hole

Now you want to see some actual code, do you? OK, here we go. You can see all the code on the GitHub repository and there is not actually all that much of it (50% of the code is class declarations) so I will just highlight the important bits.

We will have a selection screen with the three primary keys of SFLIGHT as the selection criteria plus a box where you can put the target email address. Note the little icons to make it blindingly obvious that an email is being sent with a spreadsheet attached.


Selection Screen

This is a type 1 executable program, so processing kicks off at START-OF-SELECTION. The aim of the game here is to have no global variables, so instead we use static classes (which are global variables really but let’s not go there).

    is_carrid = s_carrid[]
    is_connid = s_connid[]
    is_fldate = s_fldate[]
    ip_vari   = p_vari
    ip_send   = p_send
    ip_email  = p_email ).

  lcl_application=>main( ).

* Class Implementations

  METHOD set_data.

    s_carrid[] = is_carrid[].
    s_connid[] = is_connid[].
    s_fldate[] = is_fldate[].
    p_vari     = ip_vari.
    p_send     = ip_send.
    p_email    = ip_email.




So, the first step is to change the real global variables (the selection criteria) into static attributes of a class. This way we make all the OO diehard people happy and at one and the same time puzzle everyone who never uses OO, which is most ABAP people. Next comes the MAIN method – in Java and many other languages that is the name of the first method called which in turn calls all the others.

At this stage we just want to do four things

  1. Read the Database
  2. Prepare an ALV object
  3. Email that ALV object to the target email address
  4. Show the ALV object on the screen (just so you can make sure the data in the spreadsheet is correct)

There are no user commands in this initial version, there is no business logic and hence no need for unit tests. Showing the screen and emailing are “dependencies” and therefore cannot be unit tested. We only need unit tests once the business logic starts to come along, as it will in later blogs. Due to the “over-complicated” design the MAIN method consists of a series of calls to assorted specialised classes which do one thing only. In this case we have the model for the data retrieval (which it outsources to a specialised data access class) the controller which does nothing at all yet, and two views – one to email out the data, one to show the data on the screen.


  METHOD main.

    mo_model      = NEW #( ).
    mo_alv_view   = NEW #( ).
    mo_controller = NEW #( io_model = mo_model
                           io_view  = mo_alv_view ) ##NEEDED."For User Commands

    mo_model->derive_data( ).
    mo_alv_view->initialise( CHANGING ct_output_data = mo_model->mt_output_data[] ).

    IF lcl_selections=>p_send EQ abap_true.
      mo_xlsx_view = NEW #( mo_alv_view->mo_alv ).
      mo_xlsx_view->create_spreadsheet( mo_model->mt_output_data[] ).
      mo_xlsx_view->email_spreadsheet( ).

    mo_alv_view->display( ).



There is nothing shocking about the data retrieval (unless you are shocked by using methods instead of just doing a SELECT statement directly after STARt-OF-SELECTION).


  METHOD derive_data.

    mo_pers = NEW #( ).

    mt_output_data = mo_pers->derive_data( ).



  METHOD derive_data.

    SELECT *
      FROM sflight
      WHERE carrid IN lcl_selections=>s_carrid[]
      AND   connid IN lcl_selections=>s_connid[]
      AND   fldate IN lcl_selections=>s_fldate[]

    IF sy-subrc NE 0.



There is also nothing shocking about the ALV view methods.


  METHOD initialise.

          IMPORTING r_salv_table = mo_alv
          CHANGING  t_table      = ct_output_data[]  ).
      CATCH cx_salv_msg INTO DATA(lx_salv_msg).
        MESSAGE lx_salv_msg->get_text( ) TYPE 'I'.


  METHOD display.

    mo_alv->display( ).




Thus far everything is 100% bog standard. Now we come to the XLSX view and the method for turning the ALV object into a spreadsheet, which will be stored in class attribute MO_EXCEL. The prefix MO is a reference to the barman in “The Simpsons” no hang on that is not right, it is short for “Member Object”. Leaving aside some surrounding code needed to get the basics working this is in essence such a single call to a “converter” class.

  METHOD create_spreadsheet.
    "Convert SALV object into excel
    DATA: ld_sheet_title TYPE zexcel_sheet_title,
          l_ws           TYPE c LENGTH 10 VALUE 'ITS'.

    "If we do this (call the convertor) in the foreground we get a dump
    "unless we do a dirty trick
    IF sy-batch EQ abap_false.
      EXPORT l_ws = l_ws TO MEMORY ID 'WWW_ALV_ITS'.

    DATA(lo_converter) = NEW zcl_excel_converter( ).

        IF mo_alv IS BOUND.
              io_alv        = mo_alv
              it_table      = it_table[]
              i_table       = abap_true "Create as Table
              i_style_table = zcl_excel_table=>builtinstyle_medium2
              co_excel      = mo_excel ).


        DATA(lo_worksheet) = mo_excel->get_active_worksheet( ).

        ld_sheet_title = 'SFLIGHT'.
        lo_worksheet->set_title( ld_sheet_title ).

      CATCH zcx_excel INTO DATA(lo_exception).
        DATA(ld_message) = lo_exception->get_text( ).
        MESSAGE ld_message TYPE 'I'.


Now we have an EXCEL object the last stage is to email it out. In the next method there is a call to an ABAP2XLSX message to convert that EXCEL object to an XML string and the rest of the code is 100% bog standard code to email things out of SAP, code you will have seen a million times before.

  METHOD email_spreadsheet.
* Some of the code here may look VERY familiar, because instead of re-inventing the wheel I copied it straight off
* the internet about 10+ years ago. It worked straightaway so I never bothered changing it aprt from adding inline
* declarations
    DATA: lo_excel_writer TYPE REF TO zif_excel_writer,
          lo_recipient    TYPE REF TO if_recipient_bcs,
          ld_bytecount    TYPE i,
          ld_maxbytecount TYPE i,
          ld_filelen      TYPE so_obj_len.

    CHECK lcl_selections=>p_send  EQ abap_true.
    CHECK lcl_selections=>p_email IS NOT INITIAL.

        lo_excel_writer   = NEW zcl_excel_writer_2007( ).
        DATA(ld_xml_file) = lo_excel_writer->write_file( mo_excel ).

      CATCH zcx_excel INTO DATA(lo_exception).
        DATA(ld_message) = lo_exception->get_text( ).
        MESSAGE ld_message TYPE 'I'.

        "Convert to binary
        DATA(lt_file_tab) = cl_bcs_convert=>xstring_to_solix( iv_xstring  = ld_xml_file ).
        ld_bytecount      = xstrlen( ld_xml_file ).
        ld_maxbytecount   = 10000000 ##NUMBER_OK.

        "Create persistent send request
        DATA(lo_send_request) = cl_bcs=>create_persistent( ).

        "Create document object from internal table with text
        DATA(lt_main_text) = VALUE bcsy_text( ( line = 'This is the text in the body of the email'(009) ) ).
        IF ld_bytecount >= ld_maxbytecount.
          APPEND INITIAL LINE TO lt_main_text ASSIGNING FIELD-SYMBOL(<ls_main_text>).
          <ls_main_text>-line =
          |{ 'The excel extract of the report cannot be sent because the resulting file is beyond the'(008) } | &&
          |{ ld_maxbytecount / 1000000 DECIMALS = 0 }{ 'MB limit'(007) }|.

        DATA(lo_document) = cl_document_bcs=>create_document( i_type    = 'RAW'
                                                              i_text    = lt_main_text
                                                              i_subject = 'Email Subject'(006) ).

        IF ld_bytecount < ld_maxbytecount.

          "Add the spreadsheet as attachment to document object
          ld_filelen = ld_bytecount.

          DATA: lt_att_head  TYPE soli_tab,
                lv_text_line TYPE soli.
          CONCATENATE '&SO_FILENAME=' 'Attachment Subject.XLSX'(005) INTO lv_text_line."Must end in XLSX or XLSM
          APPEND lv_text_line TO lt_att_head.

          lo_document->add_attachment( i_attachment_type    = 'EXT'
                                       i_attachment_subject = 'Attachment Subject.XLSX'(005)
                                       i_attachment_size    = ld_filelen
                                       i_att_content_hex    = lt_file_tab
                                       i_attachment_header  = lt_att_head ) ##NO_TEXT.


        "Add document object to send request
        lo_send_request->set_document( lo_document ).

        "Create recipient object
        lo_recipient = cl_cam_address_bcs=>create_internet_address( lcl_selections=>p_email ).

        "Add recipient object to send request
        lo_send_request->add_recipient( lo_recipient ).

        lo_send_request->set_status_attributes( 'N' )."Never

        "Send Document
        DATA(lf_sent_to_all) = lo_send_request->send( 'X' )."With Error Screen

        COMMIT WORK.

        IF lf_sent_to_all IS INITIAL.
          MESSAGE i500(sbcoms) WITH lcl_selections=>p_email."Document not sent to &1
          MESSAGE s022(so)."Document sent
          "Kick off the send job so the email goes out immediately
          WAIT UP TO 2 SECONDS.     "ensure the mail has been queued
          SUBMIT rsconn01
            WITH mode   = '*'       "process everything you find.
            WITH output = ' '
          AND RETURN.                                    "#EC CI_SUBMIT

      CATCH cx_bcs INTO DATA(lo_bcs_exception).
        "Error occurred during transmission - return code: <&>
        MESSAGE i865(so) WITH lo_bcs_exception->error_type.


And that is that. 99% bog standard code you will already have seen dozens of times plus two calls to ABAP2XLSX class methods. For the life of me I cannot see why people keep saying ABAP2XLSX is far too difficult to use. The result is the data shown on screen plus a spreadsheet in your inbox.


ALV Output


Spreadsheet Output

Moreover, as we will see going forward, since most of the code to create an EXCEL object and to email it out is “boilerplate” you would want to encapsulate it into a global class with importing parameters for the small portion of values that change e.g., the name of the spreadsheet, contents of the email body and so on.


Just to re-iterate the main point of these blogs is to dispute the argument that ABAP2XLSX is too impossibly difficult to use.

In this blog I have started with the absolute basics i.e., the main use case which is emailing out a spreadsheet which looks like an ALV report, filled with SAP data. In subsequent blogs we will start to look at all the fancy things you can pro programmatically do with that spreadsheet e.g., print settings and the like, all of which are pretty much obvious how to do as well.

Cheersy Cheers


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Karthikeya NM
      Karthikeya NM

      I have used ABAP2XLSX in many programs and I found it useful when I want to format, email or use colors in the excel. I never found it difficult to use! The examples given in the demo programs are very good and you just have to Adapt it to your use case and you are all set!

      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author

      I would 100% agree. The demo programs are easy to understand, everything is easy to understand.

      Yet for ten years every month someone new posts a blog on the SCN saying they have invented a new way to download from ABAP to Excel and if I mention ABAP2XLSX they say it is far too difficult to use, and not documented at all.

      Every month. For over ten years. It will happen again next month, maybe even this month.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      I have two questions

      Why have you used [] within the classes?

          s_carrid[] = is_carrid[].
          s_connid[] = is_connid[].
          s_fldate[] = is_fldate[].

      And what's with all this Hungarian notation? 😉

      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author

      To answer the second question first the other night I woke up and said "Oh Dear!" (It was actually somewhat stronger than that, shocking my wife and the fluffy animals). I had realised in my dream I had forgotten to take the Hungarian Notation out. I have to use it at work, but I do not use it in my books etc. and I had been copying the code form actual productive classes.

      It might be an urban myth but as I understand it Hungarian Notation came about because a developer from Microsoft (who was Hungarian) wrote a gigantic essay saying you SHOULD NOT prefix your variables. Trouble was he started with a short section explaining how you might prefix variables, and then the remaining 95% of the article explained why that was a really bad idea. Second trouble was no-one every read past the first bit and so concluded he was extolling the virtues of prefixes and before you knew it was company policy at Microsoft. It is clearly the policy in all new standard SAP code. So, the "Hungarian" became famous for appearing to advocate the very thing he was advising not to do. In the same way Morrisey did not like it much when "The Simpsons" portrayed him as a burger-eating champion.

      I will remove this (H.Notation) from the local variables in the code on GitHub. I still like prefixes for parameters and member variables. I also like how Lars (inventor of abapGit) says "My name is Lars and I prefix my variables" like he was at an AA meeting.

      As to the [] to denote a table, you do not need that at all in methods. I love it though; the same way i love ADD 1 TO MONSTER_COUNT as opposed to MONSTER_COUNT ===++???//. To me the former reads more like plain English and less like machine code. I used to program in machine code when I was 14 and whilst it was not the end of the world, I think code that reads like English is far easier to understand and thus maintain. I realise this is a matter of ascetics though, so it [] really offends you then pluck it out, as the bible would say.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      A twelve step program for recovering prefixers.


      Author's profile photo Vicenç Xavier Lozano
      Vicenç Xavier Lozano

      Every time I see a conversation between Matt and Haul Pardy I learn new things, I have a laugh and/or I get a confirmation of a good thing I'm trying to do.

      I'm glad for it and thankful for each one of those nice times.

      Author's profile photo Shai Sinai
      Shai Sinai

      I don't want to start another (long) discussion here,

      but I wonder if the MO prefix is still allowed, even in the Anti-Hungarian (Notation) union.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      MO wouldn't be. M represented member object. O represents object reference.

      If you want to specify a member object, you can use me->. I used to use it, but stopped as I began to view it as a "code smell" i.e. if I have to differentiate member objects from other objects I'm doing something wrong.

      I'm only anti-Hungarian Notation, not anti-Hungarian!


      Author's profile photo Alexandre Henrat
      Alexandre Henrat

      For the background story, Joel Spolsky wrote an interesting blog on Simonyi and the Hungarian Notation a few years ago :

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Asking real questions! 🙂

      Author's profile photo Shai Sinai
      Shai Sinai

      Shouldn't the issue with the foreground execution be fixed in the class ZCL_EXCEL_CONVERTER_SALV_TABLE itself instead of local "trick"?

      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author

      I have to admit I just copied the code from a "wrapper" class i wrote about ten years ago. The problem has most likely been fixed by now (I just compared the code in the old class vs the current one and it is very different).

      I will have a test and if the problem is no longer there then that proves open-source projects are good and if the problem is still there I will fix it myself and submit a pull request or whatever you call it to fix the problem for everybody and that would also prove open-source projects are good.

      Author's profile photo Clemens Li
      Clemens Li

      Thank you for keeping abap2xlsx alive.

      Just my 2 Cents concerning the mail: Just use send_request->set_send_immediately( 'X' ) and forget about subbmitting RSCONN..

      I think the problem about abap2xlsx is that you have to convince your company to transport a whole bunch of objects into production system that nobody understands in detail.

      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author

      The send immediately is a good improvement.

      As to sending loads of stuff to production no-one understands that happens all the time.Support stacks are the obvious example, but many companies have third party add-ons l(e.g. SAST REVTRAC, there are millions) which get updates every so often, and in go all the transports, no problems.

      The only difference is that issues with open-source projects as opposed to things you pay for are more visible and easier to track, and of course you can fix them yoiurself.

      Cheersy Cheers


      Author's profile photo Evgeny Lapshin
      Evgeny Lapshin

      Hi Paul.

      Thank you for your blog-posts about Excel tools.

      ABAP2XLSX has a big disadvantage: it's hard maintaining.

      Try this. I think you will be found it very useful.



      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author

      OK, I would really love for you to expand on why ABAP2XLSX is hard to maintain, given it is an open-source project on GitHub. If I want a new version I just do a pull request, if there is a bug I submit an issue and it is fixed in no time at all, or I fix it myself and share the fix with the world.

      And the other program you mention is an open-source project as well, so what is the difference getting new versions and doing bug fixes on the code?

      Obviously, I am missing something fundamental here so if you could explain I would be most grateful.

      If I had to guess - and it would be a guess - are you saying that programs using ABAP2XLSX are hard to maintain because you have to do method calls to ABAP2XLSX classes and the like?

      Cheersy Cheers


      Author's profile photo Shai Sinai
      Shai Sinai

      I don't want to answer on behalf of Evgeny Lapshin ,

      but he might refer to the fact that in XLSX Workbench you have a "design time" (The Excel file itself) and you don't have to code all of it, but may just use an XLSX template instead.

      Of course, any of these approaches has its' own pros and cons (mostly depends on how dynamic your code is).

      Happily, Anton Sikidin has enhanced ABAP2XLSX and it's now possible to work also with XLSX templates.

      Author's profile photo Andrea Borgia
      Andrea Borgia

      A quick note: the enhancement is already included in the current version of abap2xlsx


      Author's profile photo Yury Kostin
      Yury Kostin

      Hi Paul,

      thanks for the interesting article.

      Where do I find how classes like zcl_excel_writer_2007, zcl_excel_converter are implemented? Or maybe some other, which are mentioned in the code with no reference?

      Thanks in advance.

      Yuri Kostin

      Author's profile photo Shai Sinai
      Shai Sinai

      They are part of the ABAP2XLSX project.

      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author

      I apologize - I really should have been clearer as to what this series of blogs is about.

      ABAP2XLSX is an open-source project which can be found on the GitHub repository mentioned below.

      abap2xlsx/abap2xlsx: Generate your professional Excel spreadsheet from ABAP (

      The problem is that even after 10 years no-one has heard of this - and thus every month for that ten-year period someone has re-invented the wheel and published a blog on how to upload/download from ABAP to Excel.

      So, I am firstly trying to make people aware of the existence of ABAP2XLSX.

      The second part is that when people do download the classes and demo programs from GitHub they complain that those classes are far too complicated to use, and the demonstration programs cannot be understood either.

      I would disagree with both points, and my aim with these blogs is to show how easy it is to use those ABAP2XLSX classes (the ones that start with ZCL_EXCEL).

      Author's profile photo Yury Kostin
      Yury Kostin

      Thanks, Paul!

      Regards, Yuri

      Author's profile photo Dmitry Balykov
      Dmitry Balykov
      • Application – a class that acts like a conductor and makes all the other classes play their musical instruments properly in the correct order. In could be argued this is not strictly needed, I could have the controller do this, but what if one day the program gets so complex there are multiple MVC constructs, some of which are global?


      In case of a program evolving towards multiple MVCs consider the H-MVC extention of the MVC pattern where any conductor is still a controller, higher level controllers orchestrate lower level ones, and it's no shame for a controller to know not only about the model and the view but also about all the direct subordinate controllers.
      Then your application classes become just main controllers, and there is no need to mark them as something special.

      Essentially, the application class in your example is already a controller by your own definition. See how in the main method it instantiates the model and the two views and says how the instances must be used together, i.e. links them. So it does all the controller job except handling commands of one of the views which is delegated to a subordinate controller but, in my opinion, to make it pure H-MVC, a subordinate controller must encapsulate a view, otherwise it seems as a violation of the SoC principle where two controllers are concerned about one view.

      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author

      I love discussions like this. I am always trying to make my programs more SOLID.

      it makes a welcome change from trying to convince people to use classes and methods and unit tests and things like that, or even FORM routines as opposed to just a big huge blob of code after START-OF-SELECTION.

      "ABAP Objects" came out in 4.6C in the year 2000 - we are now twenty three years later and as far as I can see most ABAP people still use FORM routines all the time.