cancel
Showing results for 
Search instead for 
Did you mean: 

Download a file to the client in background

frank_stdle
Participant
0 Kudos
174

HI all,

in my web dynpro application I programtically create an HTML/JavaScript page and store it in a table, and then I need to download the table to a file on a temorary directory on the client (C::\temp). The HTML page on disk will be embedded in an IFrame in one of the views of my application.

Can anybody tell me how to download the HTML page (table) to a file on the client in the background, i.e without a file download dialog? I have tried using CL_GUI_FRONTEND_SERVICES=>GUI_DOWNLOAD, but this fails, I think because I don't really have access to the frontend GUI from my web dynpro application.

thanks!

View Entire Topic
thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

There really isn't a way to write directly to a client machine from the background. In the background you have no connection to the client - either through the browser or the SAPGUI. The only exception is that if the client machine has the directory shared on the network and that network share can be accessed via the ABAP server Operating System. If this is the case, you can use the ABAP DATASET commands to write to the network share. This works if you have a public file share that is access by all the clients, but isn't really reasonable to expose all of your client machines with a file share.

frank_stdle
Participant
0 Kudos

Thank you for that, Thomas, can you suggest any other way I can dynamically create an HTML page and tranfer to the cllient, all from the context of my WD application?

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

Yes I can, althought it involves using the deprecated iFrame (which I think your solution does as well). At least it is deprecated in 7.0 and 7.01 - its back again to full support in 7.02.

You can generate the HTML as you have been, but then place the content into the ICM Cache instead of downloading to the PC. This will place the content in to the ICM temporarily and give you a temporary/dynamic URL.

Here is an example:

data lo_el_text type ref to if_wd_context_element.
  data lv_html_text type wd_this->element_text-html_text.
  data lv_iframe_url type wd_this->element_context-iframe_url.

  lo_el_text = wd_context->get_child_node( name = wd_this->wdctx_text )->get_element( ).
  lo_el_text->get_attribute(
    exporting
      name =  `HTML_TEXT`
    importing
      value = lv_html_text ).

****Create the cached response object that we will insert our content into
  data: cached_response type ref to if_http_response.
  create object cached_response
    type
      cl_http_response
    exporting
      add_c_msg        = 1.
*  cached_response->set_compression( options = cached_response->IF_HTTP_ENTITY~CO_COMPRESS_IN_ALL_CASES ).
  try. " ignore, if compression can not be switched on
      call method cached_response->set_compression
        exporting
          options = cached_response->co_compress_based_on_mime_type
        exceptions
          others  = 1.
    catch cx_root.
  endtry.
****set the data and the headers
  data: l_app_type type string.

      cached_response->set_cdata( lv_html_text ).
      l_app_type = 'text/html'.

 cached_response->set_header_field( name  = if_http_header_fields=>content_type
                                     value = l_app_type ).

  cached_response->set_status( code = 200 reason = 'OK' ).
  cached_response->server_cache_expire_rel( expires_rel = 60 ).
  data: guid type guid_32.
  call function 'GUID_CREATE'
    importing
      ev_guid_32 = guid.
  concatenate '/sap/public' '/' guid '.' 'html' into lv_iframe_url.

****Cache the URL
  cl_http_server=>server_cache_upload( url      = lv_iframe_url
                                       response = cached_response ).

  wd_context->get_element( )->set_attribute(
    name =  `IFRAME_URL`
    value = lv_iframe_url ).

frank_stdle
Participant
0 Kudos

Thanks, your solution is spot on, and I was already thinking that I might want to use a variant of your solution; I have already created a node in ICF (with an attached handler class) to handle incoming data from my web page -- I guess I can also let my IFrame in web dynpro refer to the URL of that node, and then create my web page in the ICF handler class upon request.

My only problem then is communicating between the ICF handler and the WD application, but I can solve that by just passing data through a database table.

Is there perhaps some other way I can communicate synchrounously between the ICF handler class and the WD application whenever data is posted from the web page to the ICF node, some kind of eventing or other?

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

>Is there perhaps some other way I can communicate synchrounously between the ICF handler class and the WD application whenever data is posted from the web page to the ICF node, some kind of eventing or other?

No. The ICF Handler and the WDA are in separate sessions - perhaps even running on separate application servers.

I do something similiar with the FlashIslands upload example. The FlashIsland uploads to a ICF handler class which write the data into a temporary DB table. The FlashIsland from the client side can then raise an event to the WDA to let it know the data is uploaded and to go get it. Without that connection on the client side, however, there would be no communication between the ICF handler and the WDA application.

frank_stdle
Participant
0 Kudos

Ok, if I understand you correctly the ICF handler cannot trigger an event in the WDA. I will however make do with the temporary table; my IFrame is contained in a separate view, and I will simply read the temporary table when exiting the view to see if any data has been passed from the web page to the table via the ICF handler.

Thank you for a very enlightening discussion!