on ‎2012 Jun 27 1:24 PM
HI All,
First off I know nothing about BSP, just thought I would get that one out the way.
With that said I have tried to follow this wiki :- http://wiki.sdn.sap.com/wiki/display/BSP/Handling+Binary+Data with some success.
Now what I am trying to achieve is simply reproduce this small piece of php code :-
<?php
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"my-data.csv\"");
$data=stripcslashes($_REQUEST['csv_text']);
echo $data;
?>
in a BSP application.
I have tried the following in the layout tab and in the Event OnInitialization:-
<%
IF request->get_form_field( 'csv_text' ) IS NOT INITIAL.
response->set_header_field( name = 'Content-Type' value = 'application/octetstream' ).
response->set_header_field( name = 'Content-Disposition' value = 'attachment; filename=csv_text.csv' ).
response->set_header_field( name = 'Connection' value = 'close' ).
DATA: file_content TYPE string. file_content = request->get_form_field( 'csv_text' ).
response->set_header_field( name = 'Expires' value = '0' ).
response->set_header_field( name = 'Pragma' value = 'no-cache' ).
response->set_header_field( name = 'Cache-Control' value = 'max-age=0' ).
REPLACE ALL OCCURRENCES OF ' ' IN file_content WITH ''.
response->set_cdata( file_content ).
RETURN.
ENDIF.
%>
The only problem is that I get the desired download dialog box but I am directed to a blank BSP screen with "Your request is being processed" message instead of simply leaving me on my current page and showing a download dialog like with PHP.
I am POSTING some CSV data from a table page in SAP BW to this BSP application that I want to download as a CSV text file.
I can't simply use the export to CSV function of SAP BW because of the modifications I have made in javascript to change the tables.
I am utilising this piece http://www.kunalbabre.com/projects/table2CSV.php of jQuery utility to get what I require from the client side. Option 3.1 is what I am trying to achieve.
Any help please?
Thanks
Craig
Request clarification before answering.
Hi Craig,
by looking at the code, I don't see an obvious error.
My only concern is about the field Content-Type. I am not sure whether this won't be overwritten by the ICF if you set it with the general set_header_field method. There is a special method set_content_type for it, which I would prefer.
If it still doesn't work: Did you switch on the "Network log" in Firebug (or in MSIE: <F12>), and compared the response headers with your expectations? Which header field values were actually sent in the response?
Regards,
Rüdiger
BTW: Did you know there is an interface IF_HTTP_HEADER_FIELDS containing constants for all specified header field names? Using these constants (like IF_HTTP_HEADER_FIELDS=>CACHE_CONTROL ) instead of literal values may be helpful for avoiding mistyping.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for the response. I changed the BSP to use set_header_field but have same problem.
Below is the response headers :-
Response Headers
Content-Length 27183
Content-Type text/html; charset=iso-8859-1
Server SAP NetWeaver Application Server / ABAP 701
Request Headersview source
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-gb,en;q=0.5
Connection keep-alive
Cookie sap-usercontext=sap-language=EN; MYSAPSSO2=AjExMDABAAxBUk1TVEVDICAgICACAAMyMDADAAhCV0QgICAgIAQADDIwMTIwNzAyMTMyOAUABAAAAAgGAAFYCQABRf8A9DCB8QYJKoZIhvcNAQcCoIHjMIHgAgEBMQswCQYFKw4DAhoFADALBgkqhkiG9w0BBwExgcAwgb0CAQEwEzAOMQwwCgYDVQQDEwNCV0QCAQAwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTEyMDcwMjEzMjg1N1owIwYJKoZIhvcNAQkEMRYEFKHKk9CO4BE7BO07gr6jG1tal2mBMAkGByqGSM44BAMELjAsAhQPuFOoGUSIqlIrxSFJconeraYWyQIUCawlv5WI48vy06f%2fMrbjnJPL%2f9o%3d
Host xxxx:8008
User-Agent Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/20100101 Firefox/13.0.1
Response Headers From Cache
Content-Length 27183
Content-Type text/html; charset=iso-8859-1
Server SAP NetWeaver Application Server / ABAP 701
Request Headers From Upload Stream
Content-Length 24185
Content-Type application/x-www-form-urlencoded
Any further suggestions?
Thanks
Craig
Well, it's difficult to analyze from remote.
But where is the content-type 'application/octet-stream' that you had set?
BTW, shouldn't it be "application/octet-stream" with a hyphen ? In your BSP code, you write 'application/octetstream' without hyphen.
I don't see the MIME type that you had set in the header field list that you had sent (which is a mix of request and response header fields, anyway).
Did you put a break-point on the ->set_content_type( ... ) statement? Does it reach that statement at all?
Lol yes you are correct my mistake I had forgotten the hyphen, but it didn't help anyway.
I have just put a break point on the ->set_content_type but the page is already generated at this point!
It does go through the motions and sets the headers correctly that's when I get the download dialog.
But the page is already generated at this point with the data in it with a form :-
<html>
<head>
<style type="text/css">.middle { vertical-align:middle; }</style>
</head>
<body onload="document.forms[0].submit()">
<form method="post" action="/sap(bD1lbiZjPTIwMA==)/bc/bsp/sap/zsavecsv/savefile.bsp">
<input type="hidden" name="csv_text" value="&nbsp;,"No Applicable Data Found."
&nbsp;,"No Applicable Data Found."
&nbsp;,"&nbsp;"
&nbsp;,"No Applicable Data Found."
&nbsp;,"&nbsp;">
</form>
<table border="0" width="100%" height="100%">
<tr>
<td align="center" class="middle">Your request is being processed</td>
</tr>
</table>
</body>
</html>
So it would seem my page already has a generated html page before my code even kicks in!
Maybe it's because you are in a page, not in a controller. Probably, the MIME type proposed in the page properties (see screenshot below) will finally be set from the framework.
The more natural approach would be to use a controller or even an SICF request handler for your task. But if you set the MIME type for your page in the page attributes, I don't see why it sholdn't work in your way.
Regards,
Rüdiger
So you use the same page for two purposes? The download and the form?
Wouldn't it be better to handle the download with a separate item? In particular, since you have different MIME types for the form and the download.
With the "action" attribute of the form page you can specify the controller or page that should take care of the download.
We once had a similar thing (but for uploads), and we realized it with a separate controller. It came out that the controller even was reusable for other cases later on, for which we had no idea when the first app had been implemented.
Thanks for the response, but the form I didn't create. There is nothing else in my page other than what I posted. Something else is generating this. If a controller is required how to go about creating that?
Edit
I've just checked and the MIME type for the page is set to application/octet-stream
Thanks
Craig
Hi Craig,
I just created a page with flow logic with the following sole content:
<%
response->set_header_field( name = 'Content-Type' value = 'application/octet-stream' ).
response->set_header_field( name = 'Content-Disposition' value = 'attachment; filename=csv_text.csv' ).
response->set_header_field( name = 'Connection' value = 'close' ).
response->set_header_field( name = 'Expires' value = '0' ).
response->set_header_field( name = 'Pragma' value = 'no-cache' ).
response->set_header_field( name = 'Cache-Control' value = 'max-age=0' ).
response->set_cdata( 'a;b;c' ).
%>
It behaves as expected: When I call it, Firefox asks me whether I want to open the csv file with MS Excel, or simply save the file. When I choose "open", excel is started, with the first three cells of the sheet filled with 'a', 'b', 'c'.
Could you try to reduce your code this way and see whether it behaves the same way?
This could give you a hint on what's going wrong.
Rüdiger.
Hi Craig,
never mind 🙂
If I understand you correctly, the problem was outside of the code you displayed to us, in a HTML form in a previous stage of the app.
Just to finish this discussion: I am curious if you could explain the root cause of the problem in a few words? request->get_form_field( ) works just the same for GET as well as for POST requests. So what was the problem?
Rüdiger
Ok here goes.
I had this form in a BW Web template :-
<FORM method="post" action="/sap/bc/bsp/sap/zsavecsv/savefile.bsp">
<input type="hidden" name="csv_text" id="csv_text"><input type="submit" value="Get CSV File" onclick="getCSVData()">
</FORM>
The getCSVData() javascript function (extension of jQuery) was simply this:-
function getCSVData(){
var csv_value=$('#TABLE_1').table2CSV({delivery:'value'});
$("#csv_text").val(csv_value);
}
The BSP page within the layout tab was/is :-
<%
IF request->get_form_field( 'csv_text' ) IS NOT INITIAL.
DATA: output TYPE string ,
app_type TYPE string ,
l_xstring TYPE xstring.
DATA: file_content TYPE string. file_content = request->get_form_field( 'csv_text' ).
REPLACE ALL OCCURRENCES OF ' ' IN file_content WITH ''.
response->set_header_field( name = 'Content-Type' value = 'application/octet-stream' ).
response->set_header_field( name = 'Content-Disposition' value = 'attachment; filename=csv_text.csv' ).
response->set_header_field( name = 'Connection' value = 'close' ).
response->set_header_field( name = 'Expires' value = '0' ).
response->set_header_field( name = 'Pragma' value = 'no-cache' ).
response->set_header_field( name = 'Cache-Control' value = 'max-age=0' ).
response->set_cdata( file_content ).
ENDIF.
%>
The problem: with the form method set to POST, the BSP page had generated by the system (nothing to do with me) a form that submitted to itself with the content of the POSTED field csv_text (plain csv data), then prompted to save the content with a download dialog box. Leaving you with essentially a blank page.
Simply changing the form method to GET the pre-generated form page doesn't get generated and you simply get what I wanted in the first place, a download dialog.
Hope this makes sense! Well it doesn't really, since I can't understand why the form page get generated in the first place.
Cheers
Craig
OK now I am annoyed, just when you think you have cracked it.
This works in firefox but IE refuses to play ball.
Opens a page with this in the URL :-
/sap/bc/bsp/sap/zsavecsv/savefile.bsp?csv_text=%26nbsp%3B%2C%22No+Applicable+Data+Found.%22%0D%0A%26nbsp%3B%2C%22No+Applicable+Data+Found.%22%0D%0A%26nbsp%3B%2C%22%26nbsp%3B%22%0D%0A%26nbsp%3B%2C%22No+Applicable+Data+Found.%22%0D%0A%26nbsp%3B%2C%22%26nbsp%3B%22%0D%0A%22Channel%22%2C%22%26nbsp%3B%22
But with a lot more on the end which I assume is simply the csv data and refuses to open saying "Internet Explorer cannot display the webpage"
I assume there is an upper limit to a URL string!
Any idea?
Cheers
Craig
OK I know why IE doesn't work, according to this http://support.microsoft.com/kb/208427 Maximum URL length is 2,083 characters in Internet Explorer.
So I need to get the POST method working since name/value pairs are transferred in the header and not in the URL.
Help! 😞
Craig,
I have the suspect that BEx (or something in the calling app) is producing the intermediate self-submitting form, it's not, as you think, the BSP framework.
Proof: I created a second BSP page submit.htm with the following content
<html>
<head>
<title>Test submit download</title>
</head>
<body>
<h1>Test Submit Download</h1>
<form method="post" action="download.htm">
<input type="text" name="csv_data" value="a;b;c">
<input type="submit" value="Submit">
</form>
</body>
</html>
When calling submit.htm and hitting the button, the download page is called, which I changed like this:
<% data: lv_csv type string.
lv_csv = request->get_form_field('csv_data').
if lv_csv is not initial.
response->set_header_field( name = 'Content-Type' value = 'application/octet-stream' ).
response->set_header_field( name = 'Content-Disposition' value = 'attachment; filename=csv_text.csv' ).
response->set_header_field( name = 'Connection' value = 'close' ).
response->set_header_field( name = 'Content-Lentgh' value = '0' ).
response->set_header_field( name = 'Expires' value = '0' ).
response->set_header_field( name = 'Pragma' value = 'no-cache' ).
response->set_header_field( name = 'Cache-Control' value = 'max-age=0' ).
response->set_cdata( lv_csv ).
endif.%>
The page behaves as before, as expected.
This proves that BSP receives the form parameter csv_data without any problems.
Regards,
Rüdiger
| User | Count |
|---|---|
| 8 | |
| 5 | |
| 4 | |
| 4 | |
| 3 | |
| 3 | |
| 2 | |
| 2 | |
| 2 | |
| 2 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.