Skip to Content
Updated on July 18, 2005.  New functionality for this solution to apply an iterator to the download content was added via another weblog: BSP Extension for Downloading a Table: Applying an Iterator  (BSP Extension for Downloading a Table: Applying an Iterator)    *Introduction*  The purpose of this web log is really two fold. First I wanted to share the code from a BSP extension element that we wrote that allows for the easy download of a table to Excel, XML, or HTML. This seems to be one of those features that users who are used to the SAPGui and ALV Grids always expect from BSP pages. The also seems to be a lot of interest in the BSP forums for this kind of functionality. The second reason for this web log is to provide a detailed walk-through of a BSP extension element. There also seems to be a high interest in people creating their own elements and hopefully this weblog will add to the other documentation that already exists on SDN.    I have to say that I also struggled with the best way to share the source code. I thought about upload the Transport files to SDN. However I didn’t think that people would want to import this directly into their systems (security concerns, naming conventions, etc). I also though about including the source code in a file that can be downloaded. But there are so many separate pieces to the element that ultimately I thought this might be difficult to use. Finally I decided to include the code inline in textboxes. That way users can decided what code they want and cut and paste it out of the WebLog. If there is demand I can upload the code as file as well and add it to the WebLog later.    *What we are going to build*  Before I start breaking down each piece of code, lets first look at what we are going to build. As far as what the user will see – we will have an Icon and Label that trigger a popup menu (based upon the PHTMLB popup Menu object). This popup menu will contain our different download options. The following is what the finished product will look like in action: image   *Element Definition*  We will start off with the element definition. I named my element downloadTableExcel . When I started the project I was only going to offer Excel as a download option. It was only later that I decided to enhance the element to include XML and HTML. For the Element content I selected BSP Elements and Static HTML . For Further options I only selected “PAGE DONE” is not returned at the end of BSP element .    The following are some screen shots of how my Extension, Element, and the underlying class defintions look. Some people were having some problems with the inheritance from CL_HTMLB_ELEMENT, so I though adding these screen shots might help.  image  image  image  image   Moving on we will take a look at the element attributes. The following is a screen shot of my defined attributes: image
To report this post you need to login first.

100 Comments

You must be Logged on to comment or reply to a post.

  1. Craig Cmehil
    I’ve just read through it all and it’s fantastic – it was shorter than I was expecting I think!

    I’ll try to implement it and see how it works out!!

    Thanks Thomas!!!!!

    (0) 
  2. Brian McKellar
    Thomas,
    This is an absolute excellent weblog. It is so good, that you should have sold the download tag for dollars! For anybody that feels like moving to a high level of BSP extension programming, should first read, and then duplicate your work. I learned two new things reading this text. One will immediately be used to advance from good programmer to excellent programmer. This weblog is a must read for anyone serious about using BSP to the max!
    brian
    (0) 
  3. Daniel Humberg
    Wow, this blog is fantastic.
    I just spend my morning to get in running and it finally works.
    I had 2 problems. Maybe it was my fault, but if not, maybe you can get more specific on these spots:
    1) Can’t compile if_bsp_element~runtime_is_valid because there is no “m_content”. Do I have to add somethinkg?
    2) Can’t compile HANDLE_EVENT, because my handler class has no “selected_id”.
    data: ipopup type ref to MY_HANDLER_CLASS.
    ipopup ?= htmlb_event_ex.
    if ipopup->selected_id cs ‘Item1’. …
    But anyway, you should ne nominated for the “best blog of the year” award…
    (0) 
    1. Thomas Jung
      1.  The first one is easy.  If you don’t have mc_content, then the inheritance on your BSP Extension (not elment is not correct).  Make sure that yoru BSP Extension has the value of CL_HTMLB_ELEMENT in the BSP Element Basis Class field.  You should then look at the Generated Basis Class for your BSP Element.  This class should inherit from CL_HTMLB_ELEMENT.  This will expose many useful attributes such as MC_CONTENT and MC_RUNTIME to your BSP Element.

      2.  I added SELECTED_STRING, SELECTED_ID, AND SELECTED_TEXT as Public, Instance Attributes (type string) to my BSP element class (in my case ZCL_ES_BSP_ELMNT_DWN_TBL_EXCL).  I might not have implicitly stated this in the weblog. 

      I’m glad you enjoyed and found this useful.

      (0) 
      1. Daniel Humberg
        Thx. I ran into 2 follow-up problems:
        1) in runtime_is_valid, there is no “me->_text” in
        me->text = m_validator->bindable_to_string(
                    name = ‘text’
                    value = me->text
                    binding_path = me->_text
                    page_context = m_page_context ).
        Did you mean “me->text”?
        2) after I added selected_… to the handler class I wonder where these values are filled. when I call “ipopup ?= htmlb_event_ex.”, these fields are still initial, so “if ipopup->selected_id CS ‘Item1′” won’t be true.
        (0) 
        1. Thomas Jung
          1.  You should have a TEXT and a _TEXT attribute inherited from your element basis class.  If you don’t have the underscore variable, you probably didn’t selected Bindable when you created teh element attribute.  Go back to the definintion.  TEXT is the only bindable attribute.  You can find the option in the attribute table in the following order: Attribute Name, Required, Dynamic Value Allowed, Call by Reference, and then Bindable.

          2.  These values should be set in your EVENT_SET_PARAMETERS method.  You should get the values for the selected_string, selected_id, and selected_text as parameters pased in by the BSP runtime.  Make sure the you have the interface IF_HTMLB_DATA and that you have implemented the suggested code in the RESTORE_FROM_REQUEST, EVENT_INITIALIZE, and EVENT_SET_PARAMETERS methods.  Also in the DO_AT_BEGINNING method we have code to redirect the event of the Popup Menu to our class.  That is the code toward the end, where we get our class name from the CL_ABAP_CLASSDESCR and add it into the onselect value.

          (0) 
          1. Daniel Humberg
            During the migration process problems have been reported for this blog. The blog content may look corrupt due to not supported HTML code on this platform. Please adjust the blog content manually before moving it to an official community.
            (0) 
          2. Daniel Humberg
            At the moment I am trying to add a “table”-attribute to the extension and to download that table instead of the table that is specified in do_handle_event. However, I would probably have to save the table somehow in hidden input fields in do_at_beginning to be able to use in in handle_event, right? and storing a table in hidden input fields doesn’t seem to be possible and reasonable, right?
            (0) 
            1. Thomas Jung
              I considered adding this kind of functionality.  Untimatly though I decided against it.  You never know if your BSP extension is going to be used in a stateful or stateless application.  That is why I decided to let the consuming application manage the lifetime of the table and perhaps even manipulate the data right before the download.

              If you want to add this, I would study the htmlb:tableView element.  I have never taken it apart to see that this function works, but it has a similar attribute.

              (0) 
  4. Anonymous
    Hi Thomas,

    first of all great work! I really enjoyed reading through the weblog and implementing this great feature in our system. This little thingy made the whole way from implementation to production in one day… !

    My app currently runs standalone but will be started from Enterprise Portal in the near future so I’m constantly checking the integration. The problem I faced was, that the download of the table did not start within portal. After some debugging and html-code inspection I was able to find the bug and a solution. Everything works fine now.

    The point to have a look at:
    At the end of do_at_beginning the url gets build together and passed to the html string. Therefore the String display_url gets moved to the variable url_string of type url. Url is a Char of length 132.

    The environment:
    Our EP is running in https, all backendsystems (where my app resides) are connected via https.

    The Problem:
    When using https the sessionID within the url is a lot longer than in http. In our situation the string display_url is about 320 characters long and gets cut to 132. 🙁
    The iframe gets displayed but the url is not valid and no download is triggered.

    The solution:
    I changed the type of url_string to c, length 500. Should be enough for now and everything works fine now. 🙂

    Once again, excellent work of yours and excellent code. I had no problem extending your tag a little bit so that one can choose in the view which options to display (XSL, XML, HTML)…
    If you want to post a little update on this weblog and want to have a look at the added code just let me know. Would be a pleasure… 🙂

    Regards,
    Alex

    (0) 
    1. Thomas Jung
      Thanks for pointing that out.  I actually changed it in the weblog to type string.  Once might say that SAP needs to think about changing the URL data type to be longer.  🙂 

      That is a nice suggestion to add the ability to choose which options to display. I can certainly add that.  Did you have one attribute to specifiy the types or did you create an attribute for each possible one with a boolean value?

      (0) 
    1. Thomas Jung
      It sounds like you are missing hte parameters on the method calls.  The Parameters are show in screen shots before each section. Both r_xstring and itab are parameters so I am making an assumption.  Let me know if that takes care of it for you.
      (0) 
      1. Marcus Pohl
        Sorry,

        i just saw it after i wrote u.
        But Now I have the following problem:
        @Do_Handle_Event:

        data: model type ref to ZTESTPOHLMODEL.
        data: appl  type ref to ZTESTPOHLDEFAULT2_KLASSE.

        ****Get a Pointer to the application Object
          appl ?= application.
          model ?= get_model( ‘MODEL’ ).

          if event_id cs ‘DOWNLOAD’.
        *    clear model->message1.

            data itab type ref to data.
            get reference of model->TableX into itab.
            clear appl->display_url.
            appl->display_url =

        ……..
        endif.

        The Error appeared: NULL Reference at app !
        So i wundered about that error.

        (0) 
        1. Thomas Jung
          Where exactly do you get the null reference error?  Was it on appl or application?  Before or After the Cast.  It seems that for appl to be null either the cast failed or application was null to begin with.  However application should be filled by your model class.

          Is your application stateful?  Do you have an application class defined?  If not you will have to adapt this code to your application.  This example was taken from a stateful BSP with an application class.  If this isn’t the case you will just have to find a different place to put the display_url.  Perhaps a global attribute of your model class. 

          Also check your inheritence on the Controller Class. You should be recieving the application attribute from the inherited class CL_BSP_CONTROLLER.  My controller classes all have CL_BSP_CONTROLLER2 as their super class.

          (0) 
  5. Tiest van Gool
    Thomas, congrats for writing this BLOG, simply fantastic – your the man. – I am trying to work my way through this genious piece of work and do not understand two things (for now). Can you explain to me the following:

    1 – I added my new extension to the BSP application I am testing however the icon and ‘download’ tag do not show up. When I check the page it’s logic no errors are found but when I double click the newly created extension in the page it does not route me to the newly created BSP element, instead the message occurs ‘Navigation to object not supported’. Any suggestons?
    2 – Where do I add the method ‘DO_AT_BEGINNING’? I understand this method needs to be added to respective BSP applications or not? If so, how?

    Hope you can find some time to help me out. Thanks again and congrats with you 10.000+ points. You deserve them, Tiest.

    (0) 
    1. Thomas Jung

      Your in luck because I believe the answers to your two questions are rather simple (sometimes you need a nice easy pitch over the plate on a Friday morning).

      (0) 
      1. Tiest van Gool
        Thanks for your answers and I guess it was quite late when I finished up because, yes, I had forgotten the extension definition in my pages. Regarding the second question I mistakenly mentioned method ‘DO_AT_BEGINNING’, I am refering to method ‘DO_HANDLE_EVENT’ in stead. Besides that I have on more issue that boggles me. The page seems to work fine but when I select the “download’ option, a pop-up does appear but there are no values in there. Any idea what the reason for this might be? Thanks for sharing with the lucky few, all your knowledge. Tiest.
        (0) 
        1. Thomas Jung

          Sorry I had some problems posting to the comments section this morning, so I posted a reply in the BSP forum.  The following was my reply:

          (0) 
          1. Tiest van Gool
            Hi Thomas, again thanks for the help, the complete application seems to work now except for the pop-up menu that remains blank. I will post a question in the BSP forum on this to see what we can come up with. Again thanks for this splendid solution. Tiest.
            (0) 
  6. jean-christophe lohisse
    Hello,

    I try to implement this nice weblogs but have some problems with the method do_handle_event.
    I add the method do_handle_event in the class ZCL_ES_BSP_ELMNT_DWN_TBL_EXCL as instance method.

    but I can not compile it I get some errors:
    1) field event is unknow.
    2)  htmlb_event is unknow too.
    3)  what are the class zcl_bsp_m_mxref_query and zcl_em_bsp_appl_mat_xref.

    thanks for your help.
    Jean christophe

    (0) 
    1. Thomas Jung
      The DO_HANDLE_EVENT method is just an example of how to use this element.  This is the event handler in my hosting application (DO_HANDLE_EVENT is an inherited method of the controller class).  This isn’t part of the extension itself. 

      If you aren’t using MVC, then this is the code that you would place in your OnInputProcessing event handler.  The point was to just give a demo of how to catch the event and trigger the static method of the element class for processing the download. 

      The two class, zcl_bsp_m_mxref_query and zcl_em_bsp_appl_mat_xref, are out of context.  They are part of the example that I took this from.  They are the model and application classes respetively for the the hosting application.

      (0) 
  7. Marcus Pohl
    Hi,

    I just implemented the feature to download a tab to excel, html. It works great!
    But now I have a problem.
    The downloaded excel file has the wrong column header names, because i changed it in the iterator.
    Is it possible to download the file to excel and the changed column header names are also displayed correct?

    (0) 
    1. Thomas Jung
      Anything is possible. 🙂

      There is nothing in the current functionality to do that.  However all it would take is a different static event handler method that took the iterator class instance as an import parameter as well. You would then use the iterator class to adjust the output. 

      I have considered doing this myself, but haven’t gotten around to.  I will see if I can prepair an example in the next day or so.

      (0) 
      1. Marcus Pohl
        Good morning Thomas,

        your the best!!!!
        Haven’t thought you reply so rapidly!
        I hope i can implement it in the next few days (currently no time) but it will work!
        many thanks!

        Regards,

        Marcus

        (0) 
  8. Anonymous
    Hi thomas .
    i am not perfect . but i have created the extension    by following all ur steps but i stucked at creating the class zcl_es_serializable_error .
         u just given the constructor not any attributes, but in the constructor u used the attributes here i am just confused can u help me regarding this class.
    (0) 
    1. Thomas Jung
      Sure, they are all public, instance attributes.  They are as follows:
      short_text type string, long_text type string, program type syrepid, include type syrepid, source_line type i, and kernel_errid type S380errid.

      Let me know if you have any other equestions. 

      (0) 
  9. Consultores SAP
    Hi Thomas, you can help in simple issue for you.

    I have ZTABLE and one Field ZCLIENTE.

    My Abap program upload CSV in ZTABLE using Batch-Input.

    Delete from table need will be delete before upload.

    How i can implement in BSP ?

    Thank you, for you time.

    (0) 
    1. Thomas Jung

      I’m afraid there is no single function solution like CL_GUI_FRONTEND_SERVICES=>UPLOAD in the SAPGui Environment.  You will need to use the <htmlb:fileUpload> element to get the content from the frontend.  You then must parse the data.  There are various function modules that have been discussed in order to go from CSV or Tab Delimited into an internal table.  If the structure is simple I just write my own SPLIT <br/>AT INTO commands.  <br/><br/>Is this what you were looking for, or are you more interested in the SQL/Batch-Input?

      (0) 
      1. Consultores SAP
        Really, Batch-Input is not correct word.

        I Need Run BPS WEB and Request CSV File, after insert contents inside Internal Table.

        Table is simple, only use one field type Customer.

        (0) 
  10. Daniel Sulzer
    hi thomas

    thanks for this phantastic weblog thomas, it works perfectly!

    let me ask one question anyway:
    is it somehow possible to format the cells of the excel or to use a template from BDS including a makro?

    thank you very much
    daniel

    (0) 
    1. Thomas Jung
      >is it somehow possible to format the cells of the excel or to use a template from BDS including a makro?

      Not with the approach taken here.  I choose to go with a simple Text Tab Delimited format.  This way the output is not specific to MsExcel.  What you want to accomplish is possible, you would just have to take a different, slightly more complicated approach.  Instead of text tab delimited, you probably want to create an Excel formatted XML file.  A great way to study the Excel XML format is to bring up a document in Excel and then do the Save As XML.  The file output is considerable larger than a text file however. 

      This is the approach you use when working with OWC (Interactive Excel from the Web).  Also from what I have seen in ABAP WebDynpro, this is what SAP did to support Excel download from the WDA version of ALV Grid.  It looks like the output was XML formatted for Excel.  There are also documents on Microsoft’s website about their XML Schema.  There are several major enhancements for the XML output of Excel for the next major release of office that will help reduce the overall file size. 

      (0) 
  11. Anonymous
    Thomas,

    I have implemented this in a BSP however I have run into one slight problem. My scenario is that I have an application that has to have the ability to download about 20 different tables.
    For each table I have added the download extension.

    The problem is that the windows popup for saving or opening the file seems to be displayed for every extension that is on my BSP page regardless of which one I select.  I have set break points within my controller class however it never goes back into the methods.  All of the extensions have different ids and I have logic to handle each event in my controller class.

    Any thoughts on what could be causing this?

    Thanks in advance for you help.
    Chris Hanshew

    (0) 
    1. Thomas Jung
      I have used multiple instances of this extensions within a single page before just like you describe.  The key is to make sure that each one has a unique ID and onDownload attribute.  That way the inner elements are all unique and the event that is raised will be unique. 

      I suspect from your description that you are using the same onDownload attribute value for all the elements.

      The only other problem might be in the use of the display_url attribute.  You really need to have separate input variables for each display_url attribute.  If this attribute has any value in it, it will generate the iFrame coding that calls the given URL. 

      (0) 
  12. Arunava Das
    Hi Thomas,
      This blog is really a fantastic one.
    I have created that extension and element as mentioned. I have tried in my page(with flow logic). And the following is the code which i have included in my OnInputProcessing Event Handler.

    DATA: event TYPE REF TO if_htmlb_data .
    event = cl_htmlb_manager=>get_event_ex(
                               request ).
    IF event IS NOT INITIAL AND
        event->event_id = ‘DOWNLOAD’.
             DATA : itab type ref to data .
             get reference of itab1 into itab.
             display_url = ZCL_ES_BSP_ELMNT_DWN_TBL_EXCL=>handle_event(
                 htmlb_event_ex = event
                 runtime        = runtime
                 itab           = itab
                 i_filename     = ‘D:\CHATHIA\DYL1’).
         navigation->set_parameter(
                      name = ‘display_url’
                      value = display_url ) .
       ENDIF.

        Am getting the popupmenu but not the IFrame. I just tried in debugging mode, the
    ipopup->selected_id ,
    ipopup->selected_string and
    ipopup->selected_text is initial.
      I have the TEXT and _TEXT attribute inherited as you mentioned in the blog.
      I tried checking the display_url each time and it is getting changed each time the page is refreshed, but still am not getting the IFrame.
      Hope you can help me out. Thanks again for this wonderful blog.

    (0) 
    1. Thomas Jung Post author
      Well the Iframe is only generated if the display_url is passed back into the element on the next rendering pass.  Are you sure that display_url is populated inside the layout (I would set a breakpoint in the layout just before the rendering of the custom element)? You can also set a breakpoint inside the element handler class and see if the display_url value is making it that far and if the iFrame logic is being rendered out.
      (0) 
  13. Oliver Huppert
    Hi all,

    a message for those, who have the same problem than I had.
    After pressing the download button and selecting the HTML or XML option and choosing show over the Browserpopup, the page will be shown in the same page/view as the application runs.
    In the “do_at_beginning” method you can modify the Iframe in a “window.open” like this:

    * CONCATENATE html
    * ``
    * INTO html.
    concatenate html ‘‘ into html.

    Now everytime a new browserwindow is openned.

    Regards
    Olli

    (0) 
  14. Oliver Huppert
    Hi Thomas,

    I implemented your solution and it works great. But in one table I want to export is a field, that can be editted over a text edit control by the user. Therefore the user can also enter returns.

    When I now export this data, the return within the field results in a new line in Excel and not in a new line within the same cell.
    So I thought I can replace the cr_lf within the value to be exported with an other hex value, but the value within the excelsheet for the return within a cell is ‘A0’ instead of ‘A0D0’ for cr_lf. But a replacement of ‘A0D0’ with ‘A0’ doesn’t work.

    Do you have an idea?

    Regards
    Olli

    (0) 
    1. Thomas Jung Post author
      If you are just seeing a A0 then this must be a newline in the string instead of a Carrage Return Line Feed.  CL_ABAP_CHAR_UTILITIES has a second attribute called NEWLINE that should work in a replace for this occurance as well.
      (0) 
    2. Oliver Huppert
      Hi all,

      for those who have the same problem:

      In the method process_xls_download within the loop over the data table (ca. line 55) at the point where the concatenation of the content is done (“concatenate r_string s cl_abap_char_utilities=>horizontal_tab
                        into r_string. “)

      add before and after s a ” like this:
            concatenate r_string
                        ‘”‘ s ‘”‘ cl_abap_char_utilities=>horizontal_tab
                        into r_string.

      Additionally add a replace command before this to replace the cr_lf into a newline like thomas described:
      replace all occurrences of cl_abap_char_utilities=>cr_lf in s with cl_abap_char_utilities=>newline.

      Regards
      Olli

      (0) 
      1. Michael Luther
        you have just made me a happy man, Olli!

        Also thanks to Thomas, of course, for keeping on sharing. These blog entries and video casts you produce are great.

        Cheers,
        Michael

        (0) 
  15. karthick s
    Hi Thomas,

    This blog is very good and will be useful for many people. I am new to BSP. When i tried to copy the code of DO_HANDLE_EVENT, i am getting syntax error.

    What is the type of htmlb_event, Where i need to declare this variable. And in this method you declared data model type ref to zcl_bsp_m_mxref_query. i am getting error Object ‘zcl_bsp_m_mxref_query’ doesnot exist. similarly for the object ‘ZCL_EM_BSP_APPL_MAT_XREF’.

    Correct me if i am doing anything wrong.

    Regards,
    Karthick

    (0) 
    1. Thomas Jung Post author
      The DO_HANDL_EVENT is really just an example implementation taken right out of a real application.  You shouldn’t concern yourself with the model or application class as these are just parts of the larger application.  The only thing that really matters is the following code:
      appl->display_url = zcl_es_bsp_elmnt_dwn_tbl_excl=>handle_event(
                                                       htmlb_event_ex = htmlb_event_ex
                                                       runtime        = runtime
                                                       itab           = itab ).

      This is the code that passes the event into the specific handler for the download.  This coding will format the output, place it into the ICM cache and pass back a URL to this cached content.

      (0) 
      1. karthick s
        HI Thomas,

        Thanks for the reply. Now it is working fine. One more clarification. How to use ‘Disabled’ option in the tag ZKEG. I need all the option for downloading should be disabled when there is no data in table.

        Regards,
        Karthick

        (0) 
        1. karthick s
          Hi Thomas,

          I had found the solution. Instead of giving ‘TRUE’, i gave ‘NO’. That is why it is not working for me previously. I had corrected it now.

          Regards,
          Karthick

          (0) 
  16. Anonymous
    Hi Thomas,

    great blog! I’ve used the download in several BSP applications!

    However, I’m facing a problem and yet don’t know what’s the reason for: I tried to download a table 10521×835, i.e. > 10.000 rows and 835 chars wide. The download to XLS works, however, only ~ 8.500 rows appear in XLS. Is there any restriction on how much data your solution is able to process?

    Thanks for any input & regards
    Wolfgang

    (0) 
    1. Thomas Jung Post author
      I can’t say that I have ran into this problem and no there shouldn’t be any kind of limitation.  Have your tried looking at the downloaded file in a text editor to see if all the rows are there?  Perhaps something in Excel is not picking up all the rows.  I know Excel has a limit on the number of rows, but it should be much higher than that.  Did you try setting a breakpoint after the conversion to make sure all the data from your internal table is in output string?  Even such a large file, shouldn’t be too huge on a Megabyte scale.  I doubt that you are filling up your ICM cache unless its size is set very small on your system. 
      (0) 
      1. Anonymous

        Hi Thomas,<br/><br/>the problem was caused by leading double quotes (“) in the cell value, e.g. cell value = “TEST.<br/>I’ve added a statement (marked with > below) in method PROCESS_XLS_DOWNLOAD of class ZCL_ES_BSP_ELMNT_DWN_TBL_EXCL to deal with this issue.<br/><br/>Regards<br/>Wolfgang<br/><br/>****Use the BSP Page – to string Method to output any data type as a string<br/>        s = l_page->if_bsp_page~to_string( value = <f> ).<br/>>     SHIFT s LEFT DELETING LEADING ‘”‘.<br/>      ENDIF.<br/>      CONCATENATE r_string<br/>                  s<br/>cl_abap_char_utilities=>horizontal_tab<br/>                  INTO r_string.<br/>

        (0) 
  17. karthick s
    Hi Thomas,

    All thing are working fine for me now. One small issue.

    When i tried to download table data in HTML format, it is asking for ‘open’ or ‘save’ option. When i press ‘open’, it is opening in same window with all the table data. How to open in new window with all the table data.

    Please guide me regaring this.

    Regards,
    Karthick

    (0) 
    1. Thomas Jung Post author
      Oliver Huppert posed an alternative approach in the comments of this weblog that avoids this situation by using JavaScript to open a new window instead of the iFrame:

      a message for those, who have the same problem than I had.
      After pressing the download button and selecting the HTML or XML option and choosing show over the Browserpopup, the page will be shown in the same page/view as the application runs.
      In the “do_at_beginning” method you can modify the Iframe in a “window.open” like this:

      * CONCATENATE html
      * ``
      * INTO html.
      concatenate html ‘‘ into html.

      (0) 
  18. Steffen Froehlich
    Hi Thomas,

    nice Blog for this amazing download function.

    I have implement all your code to my BSP (flow)-application, but I cannnot compile the ZCL_ES_BSP_ELMNT_DWN_TBL_EXCL class. I get an “Field ‘Prozess_xls_download’ is unknown” error. Is there a trick to create methods? I postet my error in the SDN-Forum: cannot compile a class, field is unknown

    thanks a lot, Steffen

    (0) 
    1. Thomas Jung Post author
      No there isn’t any particular trick.  There isn’t anything in this sample that reads PROZESS_XLS_DOWNLOAD. So unless you named the method in the class different than in example, this might just be a typo.

      The syntax error is telling you have referenced something that doesn’t exist.  You either haven’t created the method in question, or you have an error in the code calling this method, or you have a mistype in the either the calling name or the description name of the method.  You would have to post the code lines that generated this error it have more details about what is occuring.  However it seems very likely that you have a mistake somewhere and a careful comparison to the source in the blog should reveil the problem.

      (0) 
      1. Steffen Froehlich
        Sorry I typed it in this post wrong, but in my program its called “process_xls_download”…

        method creation:

        -rightclick on the class ZCL_ES_BSP_ELMNT_DWN_TBL_EXCL -> Create -> Method

        now there is a dialog:
        -insert methodname “process_xls_download”
        -insert description “xls download processing”
        -insert the two parameters “ITAB” and “R_XSTRING”
        -attributes: “public” and “static” (but I already tried “instance”)
        -no abstract, no final, no event handler, no modeled
        -no entries in “exceptions”
        -save changes to ZCL_ES_BSP…

        and voila I can see my new method. I double click on it and paste your code in it.
        CTRL+F2 gives me “no syntax errors found”
        CTRL+F3 gives me “Method “PROCESS_XLS_DOWNLOAD” is not declared or inherited in class”

        So I am not able to compile the class, cause “Field “PROCESS_XLS_DOWNLOAD” is unknown. It is neither in one of the specified tables nor defined by a “DATA” statement.”

        so what did I wrong? Thanks a lot for any reply.
        Regards.

        (0) 
        1. Thomas Jung Post author
          Sorry for the late reply, I have been away on Vacation.  I posted a message into your forum thread – let’s continue the discussion there instead of the comments of the blog.  Thanks.
          (0) 
          1. Steffen Froehlich
            OK thanks for your helpful answers to my forum post.

            To finalise this post here: I made the mistake to compress the linelength, by writing:
            “(ITAB=ITAB).” in the handle_event method
            I had to do so, because I the option “Default Line Length (72)” in my User-Specific Settings was on.
            It only works with this coding:
            “( ITAB = ITAB ).”

            (0) 
  19. Thomas Kalbermatten

    dear thomas<br/><br/>i tried to use your bsp on our system. now i get the error when the prog jump into<br/><br/>method IF_BSP_ELEMENTRUNTIME_IS_VALID .<br/><br/>****Call the Inherited Method – Verify Design<br/>  call method super->if_bsp_elementruntime_is_valid<br/>    exporting<br/>      runtime_parms = runtime_parms.<br/><br/><br/>then it is on the line <br/><br/>  WHEN ‘phtmlb’.<br/>      IF me->mc_content->design <> CL_HTMLB_CONTENT=>CO_DESIGN_2003.<br/>        me->RAISE_ERROR( msg = ‘BSP-Elemente der BSP-Extension <phtmlb:*> werden nur für das DESIGN2003 unterstützt.'(002) ).<br/>      ENDIF.<br/><br/>what could i do, or otherwise what do i need to solve this error, the code is active and without errors.<br/><br/>thanks a lot<br/>thomas<br/>

    (0) 
    1. Thomas Jung Post author
      You didn’t really say what error you are getting, but based on the section I assume it is the RAISE_ERROR for phtmlb elements used outside DESIGN2003.  You see the download uses other BSP Extensions inside of itself.  The popup menu is from phtmlb which requires you to use DESIGN2003.  I assume that you page you are trying to use this element within is not set to DESIGN2003.  Please switch to using DESIGN2003.
      (0) 
      1. Thomas Kalbermatten
        hi thomas

        yes that was my first idea, i’m new in bsp’s so, how can i change to DESIGN2003? we use an own mvc.

        our classes inherits the usable if_bsp_element class and others.

        (0) 
        1. Thomas Jung Post author
          This setting is made in the page or view that hosts the BSP Extension. One of the first extension elements used on the page is htmlb:content.  This element has an attribute called Design.  This is where you can specific one of the three designs – CLASSIC, DESIGN2002, or DESIGN2003. DESIGN2003 is the latest design and supports all the Extension libraries.  It also has the broadest browser support.  It should be used whenever possible.
          (0) 
                1. Thomas Jung Post author
                  It sounds like you aren’t haveing a problem with the custom extension, but instead with the inner phtmlb:popupMenu.  This is a standard SAP element.  You should first check to see if it works on its own in your system.  Use the sample application SBSPEXT_PHTMLB.  In much older support package levels, I remember some problems with this particular element.  Perhaps there are some OSS notes or patches that must be applied.

                  Also you might consider chaning the element if you are stuck with a broken PHTMLB:popupMenu.  I know that some other people didn’t want the dependency on DESIGN2003 (brought in by the use of the PHTMLB library).  So they changed the solution to use radiobuttons for the download type instead of the popupMenu.  It isn’t quite as attractive or slick as the popupMenu, but it is functional. 

                  (0) 
      2. Thomas Kalbermatten

        yes i see, i had to add the <br/><br/><%@extension name=”htmlb” prefix=”htmlb” %><br/><br/>and then the <br/><br/><htmlb:content design=”design2003″><br/><br/>hop it works…<br/>thanks..

        (0) 
  20. Rafael Llabres
    Hi, Thomas

    It’s been great this. I’m just beginning and your blogs are a really great help

    In mi case, I’ve created everything and I’ve put it in a flow-logic which does not use any ‘standard’ tags, everything is done by javascript.

    So I’m getting the image and the text, but it’s not working the list.
    Should I need any previous tags to make this work?

    Thanks

    (0) 
    1. Rafael Llabres
      I answer myself.

      Just after writing these lines, I’ve found the solution: there was no tag for htmlb:form nor for htmlb:page. (I’ve been a whole day looking for and I’ve found it right after writing!!).

      Anyway, now it’s almost working.

      I see the list, I debug it and it goes through xls_download and so, but I’m not getting the excel back.

      Could you please help me?

      Thanks (again)

      (0) 
      1. Rafael Llabres
        Ehhh

        One more thing while I’m trying to figure out why it’s not asking to save all times.

        Is it possible to automatize this? In my case: I need to save 3 tables, but I don’t want the user to be asked 3 times.

        Thanks

        (0) 
        1. Thomas Jung Post author
          >Is it possible to automatize this? In my case: I need to save 3 tables, but I don’t want the user to be asked 3 times.

          You have to remember that the browser is used for a lot of things.  This is the same tool people use to view sites of ‘questionable’ ethics.  You wouldn’t want just any site to be able to push files to your PC now would you.

          If though I’m sure you trust your BSP application with your life (you do – don’t you), it must abide by the same rules – no pushing.  It must follow the same request/response cycle. 

          That said what you describe is somewhat possible taking a different approach.  The approach I like is to bundle the separate XLS files together into one ZIP file.  Use the class CL_ABAP_ZIP to create a nicely formatted ZIP file with multiple inner contents.  This solution obviously deviates from this example since it would take multiple tables as input – but you would follow very much the same approach.

          (0) 
      2. Thomas Jung Post author
        >I see the list, I debug it and it goes through xls_download and so, but I’m not getting the excel back.

        It is very hard to say exactly what is going on in your system from where I sit. 😉 

        There are two things to check.  First make sure the content is getting placed into the ICM cache.  You can can increase the timeout if necessary:
          cached_response->server_cache_expire_rel( expires_rel = 3660 ).

        Then go to transaction SMICM and Goto->HTTP Server Cache->Display.  Your entry should be in there.  I supose there could be a problem with the cache settings (much too small, too much activity so items are flushed right away, etc) but this is rare.

        The next thing to check is did you grap the URL that returned from the call of the eventhandler for the element.  The URL points to the spreadsheet in the cache and must be passed on to the element again in the layout rendering.  This is usually where people go wrong.  They don’t capture the URL or don’t get it back to the view. 

        (0) 
  21. Arun Reddy Thummala
    I have created BSP extension for Downloading Table, it is working fine with less data, but when I try to download huge data around 20 mb it is strucking up at the statement cl_http_server=>server_cache_upload. Please let me know how to export into excel in case of huge data. Is there any limitation in the size?

    Regards,
    Arun

    (0) 
    1. Thomas Jung Post author
      Theoretically there is no direct size limit to the solution.  I have use this same approach of loading data into the server cache for decent size image and ZIP files. 

      If you are getting stuck on the server cache upload – then you will want to look at your ICM settings (SMICM).  Do you have  server cache that is large enough?  You could be hitting some error within the ICM due to the size.  View the ICM log and server cache statistics for more details.

      (0) 
  22. Lionel Lacotte
    Hello Thomas,

    Your extension is great but I use it for downloading a tableview. My problem is :

    I use the filter or sort with tableview and when I want to download the tableview after to have  sorting or filtering, the extension downloads all the data of the tableview. I don’t understand.

    Can you help please. Thanks in advance.
    Regards.
    Lionel

    (0) 
    1. Thomas Jung Post author
      Well that’s a pretty easy one, this sample extension simple doesn’t support the these features. 

      It is feed an orignal copy of the same internal table, but doesn’t necessarily know what happend to it during the processing within the tableView element itself. 

      You would have to perform the same sort and filter manipulations on the internal table (or a copy of it I would suggest) that the tableView performs internally.

      (0) 
  23. Jamie Rocco
    Hi Thomas,

    I tried your bsp extension and it works great.  However, when I tried to download a table of type RCF_T_WL_CONTENT which is a table within a table.

    I get the following error message :

    An exception of type CX_SY_REF_IS_INITIAL occurred but neither was treated locally, nor declared by a clause RAISING.
    Method: IF_BSP_PAGE~TO_STRING

    I noticed that in the method ‘Get_table_structure’, itab is of TYPE REF data and the table that I want to download is of type RCF_T_WL_CONTENT.  So I passed a reference of my table to the itab variable and received the above error message when I ran my test.

    What do you suggest I do to make it work?

    Thank you.

    (0) 
    1. Thomas Jung Post author
      >What do you suggest I do to make it work?
      Don’t use a nested structure. 🙂

      It doesn’t matter how you declare the table reference type, the inner workings of the element must dynamically process each column of the table – and that logic can’t handle a nested table structure.  That would be incredibly complex.

      (0) 
  24. Nicolas Verhelst
    Hi Thomas
    I have used your extension already a couple of times and this worked wonderfully. Until now…. The problem now came up at a customer that has Netweaver 04 SAP ABA 22 (recently upgraded) and from that moment the popu-up menu is still rendered but without the BSP theme in it. Before we had a good popup menu where the background was white , but now the text comes rather bisarre. It there somewhere a parameter that needs to be set on .
    Niver
    (0) 
    1. Thomas Jung Post author
      The pop-up menu is a standard SAP supplied PHTMLB popupMenu element.  It is used as normally as if you used it in a standard BSP page.  There is nothing special that has to be done to it in order to use it in this element. 

      I would test with the standard sample SBSPEXT_PHTMLB and see if the same happens there.  I would suspect that you introduced a bug in the element during the support package application and need to research OSS for a fix note.  However it if works fine in the sample application, we will have to look elsewhere.  I just tested and it still works fine in NetWeaver 7.0 SPS15.

      (0) 
  25. Ricky Orea
    Hi Thomas,

    I’m having problem when trying to download the table to excel, when the popup appears whether to open/save the file, the page behind that window is distorted, all the javascript stops working, I read that the reason for this is because the request to display the excel file does not return the control to the page, is there a way to get around this problem?

    Thanks,
    Ricky

    (0) 
    1. Thomas Jung Post author
      I’ve never encountered the problem you describe.  If you follow the solution as described in this blog, the control of the page is never lost, because it is pushed to the client via a 1×1 pixel iFrame.  I can’t really say why the page would become distroted and JavaScript stopped working.
      (0) 
  26. Larry Bailey
    First, I would like to thank you for the information that you have provided since I am new to the BSP world and I would not have known even how to begin with this development. My knowledge of ABAP objects is also very limited, so my question is probably a very basic one.  When I am trying to activate the methods that I have added for handling the event, I am getting the error shown below.  Would you have any advice that would help me resolve this error?  Thanks and best regards.

    Class ZCL_ES_BSP_ELMNT_DWN_TBL_EXCL,Method PROCESS_HTM_DOWNLOAD

    Method “PROCESS_HTM_DOWNLOAD” is not declared or inherited in class “ZCL_ES_BSP_ELMNT_DWN_TBL_EXCL” –          
              

    (0) 
    1. Thomas Jung Post author
      I have to assume by the error message that you haven’t actually created the method PROCESS_HTM_DOWNLOAD.  You must just be calling the method in the code, but it doesn’t exist in the class itself.  If you are sure you created the method, then check and make sure that you have mispelled the name of the method.
      (0) 
      1. Larry Bailey
        Thank you, Thomas, for such a speedy response…certainly much faster that I was expecting. 🙂  I have created the method by copying the code from your text box.  The method itself shows to be free of syntax errors, but the error occurs during the activation. This same error also occurs when I try to activate the other methods that I have also copied (PROCESS_XML_DOWNLOAD, PROCESS_XLS_DOWNLOAD, and GET_TABLE_STRUCTURE).  I created the methods in SE24 by adding the method name to the list of methods and then using the “code” button to add the code.  I’m wondering if I did something incorrectly in this process. I created them as static, private.   Thanks again for your help.
        (0) 
        1. Thomas Jung Post author
          In general the process sounds correct.  However the methods in my copy of the class are static Protected, not private.

          Since it might be easier, you can download a SAPlink version of my class from here:
          http://abap-sdn-examples-tpj.googlecode.com/files/CLAS_ZCL_ES_BSP_ELMNT_DWN_TBL_EXCL.slnk

          I don’t know if it is exactly the same as the version from this blog however as I have made enhancements to this functionality over the years (which were included in the SAP Press book Advanced BSP Programming).

          (0) 
          1. Larry Bailey
            Thanks again, Thomas.  I believe my problem was the result of my not activating my objects in the correct order.  Reviewing your class helped me to recognize this.  However, now I am having a problem with the CONSTRUCTOR method for class ZCL_ES_SERIALIZABLE_ERROR. I’m getting the message “field ERROR is unknown”.  I attempted to resolve this on my own but again was unsuccessful. Any suggestions?  Maybe posting an SAPlink of this class might also help.   Thanks.
            (0) 
              1. Larry Bailey
                Thomas, I just successfully downloaded my first file!  You have made me a happy man today!  Thanks for all of your help.  By the way, I just ordered your “Advanced BSP Programming” book from SAP Press.  If it’s as informative as this blog, it will be a great addition to our Technical Library.  Thanks again and best regards.
                (0) 
  27. Keane Development Team
    Hello Thomas,

    Could you please let us know if it is possible to download an excel with formatting options as well. Say, suppose few rows in the tableview output have grey or blue background. When we download the same, we would like to retain the coloring option too.

    Could you please let us know if this option would be possible through BSP.

    Thanks.

    Warm Regards,
    Kishore NK

    (0) 
    1. Thomas Jung Post author
      Not possible with the text tab delimited file formatted used in this solution.  The Text Tab Delimited File Format simply doesn’t have any way for Excel to be able to read such formatting.  You would have to switch to using Excel’s XML format for export.  This way you can retain formatting.  However the building of the XML document is quite a bit more complicated than building a text tab delimited file.
      (0) 
  28. Ricky Orea

    Hi Thomas, thanks for this excellent article, I’m still using this as the way to download table into Excel, however, recently we implemented our support packs for the year and now I’m having issues when trying to download the table to excel, everytime we tried to do it, we get this error message:

     

    MIME Type: application/xls

    Description: UnKnown

    Windows does not recognize this MIME type

    I was wondering if you’ve encountered this problem before..

    Thanks in advance.

    Ricky

    (0) 
    1. Thomas Jung Post author

      “Windows does not recognize this MIME type” – that sounds like something coming from the frontend not the server side. Did you make configuration changes to the Windows desktop as well?  Does this machine have Excel installed? Its odd that application/xls wouldn’t be recogizned on the client side any longer. 

      (0) 
      1. Ricky Orea

        Hi Thomas, I agree it’s odd, we have been using this BSP extension since 2010 and this is the first time I encountered this problem. We have Windows 7/MS Office 2010 installed.

        (0) 
        1. Thomas Jung Post author

          I strongly suspect this is a Windows Desktop error. I’m not sure what to tell you to do to fix it however.  Does the error message look like its coming from the browser/OS?  It isn’t coming from the backend, right?

          (0) 
          1. Ricky Orea

            Not sure, I tested it using Windows 7/MS Office 2010 and on Windows XP/MS Office 2007, I got the same result.

            I’ll try doing the same thing on our PROD system, since it has not been updated to the latest patch and see what happens, will let you know later…thanks…

            (0) 
            1. Thomas Jung Post author

              Perhaps you could post a link to a screenshot of the error. That would help me determine if it is coming from the frontend or backend.

              (0) 

Leave a Reply