cancel
Showing results for 
Search instead for 
Did you mean: 

Converting to pdf format using MVC

Former Member
0 Kudos
108

Hi,

I have written a code to create a PDF file from a HTML document using the Convert_OTF function module and then send that PDF file as an attachment in the e-mail to a recipient. Now I need to display the PDF file, before sending it as an attachment, in a new window using MVC and not Page flow logic.

How can I achieve this ?

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Vaibhav,

Write the following code in the Do_REQUEST of your controller

IF REQUEST->GET_FORM_FIELD( NAME = 'showpdf' ) ne space.

CALL FUNCTION 'CONVERT_OTF'

EXPORTING

FORMAT = 'PDF'

IMPORTING

BIN_FILESIZE = L_PDF_LEN

BIN_FILE = L_PDF_XSTRING " binary file

TABLES

OTF = T_OTFDATA

LINES = T_LINES.

RESPONSE->SET_HEADER_FIELD( NAME = 'content-type'

VALUE = 'application/pdf' ).

RESPONSE->SET_HEADER_FIELD(

NAME = 'cache-control'

VALUE = 'max-age=0' ).

L_PDF_LEN = XSTRLEN( L_PDF_XSTRING ).

RESPONSE->SET_DATA( DATA = L_PDF_XSTRING

LENGTH = L_PDF_LEN ).

NAVIGATION->RESPONSE_COMPLETE( ).

ENDIF.

Regards,

Alwyn

Former Member
0 Kudos

Thanks For the help Alwyn. This code was really helpful.

But the PDF document opens in the same window and not in a different window. Can you help me with this ?

The customer needs the PDF document to be opened in a new window.

maximilian_schaufler
Active Contributor
0 Kudos

If creating this PDF is the only action that should take place when the user clicks somewhere, then you could change the target for your link to be opened in a new window

(see the target attribute for htmlb:link)

Former Member
0 Kudos

Hi Maxmilian,

2 actions are should haapen on a button click.

1. open the PDF document in a new window

2. send the mail to the address specified in the text

field.

I am sending the mail as well as opening the PDF document but I want it to open in a new window

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

If you want the PDF to open in another window; I usually do this using a Cached Response Object.

It is a similar process to what has been described. However the content is placed directly into the ICM cache instead of in the response object. Then when your View reloads, you take the URL that points to the Cached Object and place it in a 1x1 pixel IFrame. This will cause the PDF to open in a new window without disrupting the flow of the rest of your application.

You can find a code example for this in:

/people/thomas.jung3/blog/2004/09/02/creating-a-bsp-extension-for-downloading-a-table

I am downloading XML, XLS, and HTM files here, but the process is the same. The heart of the code is the following:

****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.

****set the data and the headers
  cached_response->set_data( l_xstring ).
  cached_response->set_header_field( name  = if_http_header_fields=>content_type
                                     value = app_type ).

****Set the filename into the response header
  cached_response->set_header_field( name  = 'Content-Disposition'
                              value = value ).

****Set the Response Status
  cached_response->set_status( code = 200 reason = 'OK' ).

****Set the Cache Timeout - 60 seconds - we only need this in the cache
****long enough to build the page and allow the IFrame on the Client to request it.
  cached_response->server_cache_expire_rel( expires_rel = 60 ).

****Create a unique URL for the object
  data: guid type guid_32.
  call function 'GUID_CREATE'
    importing
      ev_guid_32 = guid.
  concatenate runtime->application_url '/' guid into url.

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

Former Member
0 Kudos

data display_url type string.

data guid type guid_32.

RESPONSE->SET_HEADER_FIELD( NAME = 'content-type'

VALUE = 'application/pdf' ).

RESPONSE->SET_HEADER_FIELD(

NAME = 'cache-control'

VALUE = 'max-age=0' ).

L_PDF_LEN = XSTRLEN( L_PDF_XSTRING ).

RESPONSE->SET_DATA( DATA = L_PDF_XSTRING

LENGTH = L_PDF_LEN ).

response->set_status( code = 200 reason = 'OK' ).

response->server_cache_expire_rel( expires_rel = 180 ).

CALL FUNCTION 'GUID_CREATE'

IMPORTING

ev_guid_32 = guid.

CONCATENATE runtime->application_url '/' guid '.pdf' INTO

display_url.

cl_http_server=>server_cache_upload( url = display_url

response = response ).

NAVIGATION->RESPONSE_COMPLETE( ).

Above is the code that I have written in my do_request method . The PDF doument opens in the same window and not in a new window . Is there something missing ?

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

I think what you are missing is the content-disposition:

****Build the filename from the BSP Application Name or the supplied value
      data: value type string.
      if i_filename is not initial.
        concatenate 'attachment; filename='
                    i_filename
                    extension
                    into value.
      else.
        concatenate 'attachment; filename='
                    runtime->application_name
                    extension
                    into value.
      endif.

****Set the filename into the response header
  cached_response->set_header_field( name  = 'Content-Disposition'
                              value = value ).

Former Member
0 Kudos

Thanks Thomas the problem is solved.

Former Member
0 Kudos

Thomas -

I have used similar code to create an excel document from mvc. The report is created without any issues. However, the calling mvc browser seems to lock. The calling MVC is SAP's ERecruit system. Have you come up against this?

any ideas on a possible cause to the mvc locking up?

CODE:

RESPONSE->SET_HEADER_FIELD( NAME = 'Content-Disposition'

VALUE = 'attachment; filename=list.xls' ).

RESPONSE->SET_HEADER_FIELD( NAME = 'content-type'

VALUE = 'application/pdf' ).

RESPONSE->SET_HEADER_FIELD( NAME = 'cache-control'

VALUE = 'max-age=0' ).

L_LEN = XSTRLEN( L_XSTRING ).

RESPONSE->SET_DATA( DATA = L_XSTRING

LENGTH = L_LEN ).

response->set_status( code = 200 reason = 'OK' ).

response->server_cache_expire_rel( expires_rel = 180 ).

CALL FUNCTION 'GUID_CREATE'

IMPORTING

ev_guid_32 = guid.

CONCATENATE runtime->application_url '/' guid '.pdf' INTO

display_url.

cl_http_server=>server_cache_upload( url = display_url

response = response ).

NAVIGATION->RESPONSE_COMPLETE( ).

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

I have done this with PDF before (my code looks very similar) without any problems. Locking up - you mean your browser locks up? If so this sounds like the client is having a problem opening the application to display the document. Do this problem occur on more than one PC?

Also I notice yoru Content-Disposition file name ends in XLS. This doesn't seem like it should be a problem since the browser should use the Content-Type, but you might might to eliminate this as a possibility.

Also your Content-Type is in lower case: content-type. This also might not be a problem - but you never know. I perfer to use the SAP constants from the interface if_http_header_fields.

  cached_response->set_header_field( name  = if_http_header_fields=>content_type
                                     value = 'APPLICATION/PDF' ).

Also is this coding inside your controller? You are using RESPONSE. There is already an attribute called RESPONSE that should be the main response object. You really need to create a new response object to place this download content into:

****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.

Former Member
0 Kudos

thanks for the response Thomas.

the code was in the controller so I created a new cached_response. I was still getting the same result.

It was a browser issue. I resolved the problem by a bit of a work around. I opened an external bsp application and ran the logic to generate an axcel file outside fo the parent bsp. I fire a client side event to close the new window on generate excel. I am left with the new excel file and parent bsp application.

Answers (1)

Answers (1)

Former Member
0 Kudos

Welcome to SDN!!

and please go through SDN Contributor Recognition Program at https://www.sdn.sap.com/sdn/index.sdn?page=crp_help.htm

Former Member
0 Kudos

Also check this weblog for more in depth info:

/people/sap.user72/blog/2004/11/10/bsphowto-generate-pdf-output-from-a-bsp