Similar to this question, we are developing a Web app where the client clicks a button to receive a PDF from the server. Right now we're using the .ajax() method with jQuery to POST the data the backend needs to generate the PDF (we're sending XML) when the button is pressed, and then the backend is generating the PDF entirely in-memory and sending it back as application/pdf in the HTTP response.
One answer to that question requires the server-side save the PDF to disk so it can give back a URL for the client to GET. But I don't want the backend caching content at all.
The other answer suggests the use of a jQuery plugin, but when you look at its code, it's actually generating a form
element and then submitting the form
. That method will not work for us since we are sending XML data in the body of the HTTP request.
Is there a way to have the b开发者_Python百科rowser open up the PDF without caching the PDF server-side, and without requiring us to throw out our send-data-to-the-server-using-XML solution?
(I'd like the browser to behave like it does when a form
element is submitted -- a POST is made and then the browser looks at the Content-type
header to determine what to do next, like load the PDF in the browser window, a la Safari)
I see some solutions :
1) submit it to a simple servlet, stream the file through an xslt processor (e.g. saxon) which convert it to xsl-fo (a kind of xml page description language) which can be turned into PDF using FOP or RenderX.
2) submit to a servlet, parse the xml in bean arrays or whatever suitably structured data model which can be handled by a reporting engine, then pass that to a reporting engine (e.g Birt, JasperReports, ...) which support PDF rendering as a standard output format. If the XML is small, you could maybe just pass it completely to the reporting engine servlet and do the processing inside the report itself. I know one of them has a Javascript Data Source which can do the transformations.
3) Use iText to generate PDF from the parsed xml in a servlet, but I never used that before, so I have no idea how that would work.
Here is a sample form that allows you to input some text, and a PDF appears in the browser. Well, it does for me. And all I do is create the PDF in memory, set the response body to the PDF, and the response header to application/pdf. And that's it.
See http://129.33.194.254:8080/makepdf.rsp for the working example.
If it doesn't work for you, trace the http transaction using wireshark.
<html>
<body>
<%
either none? text: select request/content 'data [
%>
<strong> PDF Test </strong>
<form method="post">
Enter some text:
<input type="text" name="data" value="">
<input type="submit" value="Submit">
</form>
<%
][
if not exists? %pdf-maker.r [
write %pdf-maker.r read http://www.colellachiara.com/soft/Misc/pdf-maker.r
]
if not value? 'layout-pdf [
*do %pdf-maker.r
]
response/buffer: layout-pdf compose/deep [[textbox [(dehex text)]]]
response/set-header 'Content-type "application/pdf"
]
%>
</body>
</html>
Just create the appropriate content headers and write the PDF back in the response. You don't need to cache the PDF you created in the same way you don't need to cache dynamically generated html or images.
I had exact the same problem, the only difference was: I used JSON to post the data to the server. My solution was:
Create a hidden form (#printform) on your page with an input field (#printdata) and submit the parameters as string:
$("#printdata").val(JSON.stringify(my_json_data_object));
$("#printform").submit();
In my_json_data_object i stored all the necessary data for the pdf creation. On the server I had to parse the parameters back to a JSON object with JSON.parse(...). With this solution I can create and stream pdf files to the client, without saving them on the server. Do not forget setting the following headers on the response:
content-type: application/json
content-disposition: attachment; filename="output.pdf"
精彩评论