I have an xml file already being created and rendered as a PDF sent over a servlet:
TraxInputHandler input = new TraxInputHandler(
new File(XML_LOCATION+xmlFile+".xml"),
new File(XSLT_LOCATION)
);
ByteArrayOutputStream out = new ByteArrayOutputStream();
//driver is just `new Driver()`
synchronized (driver) {
driver.reset();
driver.setRenderer(Driver.RENDER_PDF);
driver.setOutputStream(out);
input.run(driver);
}
//response is HttpServletResponse
byte[] content = out.toByteArray();
response.setContentType("application/pdf");
response.setContentLength(content.length);
response.getOutputStream().write(content);
response.getOutputStream().flush();
This is all working perfectly fine.
However, I now have another PDF file that I need to include in the output. This is just a totally separate .pdf file that I was given. Is there any way that I can append this file either to the response, the driver, out, or anything else to include it in the response to the client? Will that even work? Or is there something else I need to do?
We also use FOP to generate some documents, and we accept uploaded documents, all of which we eventually combine into a single PDF.
You can't just send them sequentially out the stream, because the combined result needs a proper PDF file header, metadata, etc.
We use the iText library to combine the files, starting off with
PdfReader reader = new PdfReader(/*String*/fileName);
reader.consolidateNamedDestinations();
We later loop through adding pages from each pdf to the new combined destination pdf, adjusting the bookmark / page numbers as we go.
AFAIK, FOP doesn't provide this sort of functionality.
Related
I am using Grails.
I have a sample code to download an excel file:
XSSFWorkbook workbook = new XSSFWorkbook()
....
FileOutputStream out = new FileOutputStream(new File("C:\\excel.xlsx"))
workbook.write(out)
out.close()
Here the excel file will be downloaded automatically. I would want system to prompt the user to download the file in the browser window.
I tried using the below code:
response.setHeader("Cache-Control", "public")
response.setContentType("application/vnd.ms-excel")
response.setHeader('Content-Disposition', 'Attachment;Filename="excel.xlsx"')
ServletOutputStream outputStream = response.getOutputStream()
workbook.write(outputStream)
outputStream.flush()
outputStream.close()
Which doesn't work. How to achieve this?
Thanks in advance.
Quoted form W3C
Parameter values are normally case sensitive, but certain parameters are interpreted to be case- insensitive, depending on the intended use. (For example, multipart boundaries are case-sensitive, but the "access- type" for message/External-body is not case-sensitive.)
There for, try changing
response.setHeader('Content-Disposition', 'Attachment;Filename="excel.xlsx"')
to
response.setHeader('Content-Disposition', 'attachment;filename="excel.xlsx"')
I want to create a ZipOutputStream filled with PDF-As. I'm using iText (Version 5.5.7). For more than 1000 pdf entries I get an OutOfMemory-exception on doc.close() and can't find the leak.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(baos));
zos.setEncoding("Cp850");
for (MyObject o : objects) {
try {
String pdfFilename = o.getName() + ".pdf";
zos.putNextEntry(new ZipEntry(pdfFilename));
pdfBuilder.buildPdfADocument(zos);
zos.closeEntry();
} ...
PdfBuilder
public void buildPdfADocument(org.apache.tools.zip.ZipOutputStream zos){
Document doc = new Document(PageSize.A4);
PdfAWriter writer = PdfAWriter.getInstance(doc, zos, PdfAConformanceLevel.PDF_A_1B);
writer.setCloseStream(false); // to not close my zos
writer.setViewerPreferences(PdfWriter.ALLOW_PRINTING | PdfWriter.PageLayoutSinglePage);
writer.createXmpMetadata();
doc.open();
// adding Element's to doc
// with flushContent() on PdfPTables
InputStream sRGBprofile = servletContext.getResourceAsStream("/WEB-INF/conf/AdobeRGB1998.icc");
ICC_Profile icc = ICC_Profile.getInstance(sRGBprofile);
writer.setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);
//try to close/flush everything possible
doc.close();
writer.setXmpMetadata(null);
writer.flush();
writer.close();
if(sRGBprofile != null){
sRGBprofile.close();
}
}
Any suggestions how can I fix it? Am I forgetting something?
I've already tried to use java ZipOutputStream but it makes any difference.
Thx for ur answers! I understand the issue with the ByteOutputStream, but I am not sure what's the best approach in my case. It's a web application and I need to pack the zip in a database blob somehow.
What I am doing now is creating the PDFs directly into the ZipOutputStream with iText and saving byte array of the corresponding ByteArrayOutputSteam to blob. Options that I see are:
Split my data in 500 object packages, save first 500 PDFs to the database and then open the zip and add the next 500 ones and so on... But I assume that this creates me the same situation as I have now, namely too big stream opened in the memory.
Try to save the PDFs on the server (not sure if there's enough space), create temporary zip file and then submit the bytes to the blob...
Any suggestions/ideas?
It's because your ZipOutputStream is backed by a ByteArrayOutputStream, so even closing the entries keeps the full ZIP contents in memory.
You need to use another approach to do it with this number of arguments (1000+ files).
You are loading all the PDF files in memory on your example, you will need to do this in blocks of documents to minimize the effect of this 'memory load'.
Another approach is serialize your PDFs on filesystem, and then create your zip file.
I have searched for a solution but so far nothing gives me the answer i want. My question is how to convert an existing jsp page to pdf using itext possibly after clicking a button. Can someone give me a proper exaple.
All i can find is methods like this.
public String createHtmlSnippet(Movie movie) {
StringBuffer buf = new StringBuffer("\t<span class=\"title\">");
buf.append(movie.getMovieTitle());
buf.append("</span><br />\n");
buf.append("\t<ul>\n");
for (Country country : movie.getCountries()) {
buf.append("\t\t<li class=\"country\">");
buf.append(country.getCountry());
buf.append("</li>\n");
}
buf.append("\t</ul>\n");
buf.append("\tYear: <i>");
buf.append(movie.getYear());
buf.append(" minutes</i><br />\n");
buf.append("\tDuration: <i>");
buf.append(movie.getDuration());
buf.append(" minutes</i><br />\n");
buf.append("\t<ul>\n");
for (Director director : movie.getDirectors()) {
buf.append("\t\t<li><span class=\"director\">");
buf.append(director.getName());
buf.append(", ");
buf.append(director.getGivenName());
buf.append("</span></li>\n");
}
buf.append("\t</ul>\n");
return buf.toString();
}
I want to give the url and generate and download the pdf.
You can call a servlet on the button click. And in the servlet the you can use PDF Renderer. It converts HTML to PDF directly. although it has certain Restrictions like all tags should be closed like doing this <input/> wont work .
You would have to do <input></input>. But the output is amazing and fast and since it HTML you can change it easily. It internally uses iText. If you use iText directly then it would be a tedious process.
And your question should be HTML to PDF not JSP to PDf cause the JSP will get execute to produce some HTML in the end anyways
You entire HTML should be in the StringBuffer or String format.
Download from here
Update Code:
// First create a temporry file
File file = File.createTempFile("temp","pdf");
String html= "<HMTL><BODY>Hello</BODY></HTML>"; // HTML content
/* in your case it would be File f = new File("URL OF PAGE");
* */
// Write the contents intot he file.
PrintWriter printWriter = new PrintWriter(file);
printWriter.print(html); // Write String in Temp file
printWriter.close();
String s ="YourFile.pdf"; // Name of Actual PDf file
PDFRenderer.renderToPDF(file,s);// Second parameter is the actual PDF file
// The PDF is now created in the default location of you web application
// Now just read it and send it in the response.
File finalPDf = new File(s); // Reference to the newly created PDF file
PrintWriter out = response.getWriter();
response.setContentType("application/pdf");
IOUtils.copy(new InputStreamReader(new FileInputStream(s)), out);
// The above method just reads from the PDF file and puts the data in the response object
// IOUtils fully qualified name: org.apache.commons.io.IOUtils
// PDF Renderer fully qualified name: org.xhtmlrenderer.simple.PDFRenderer
I had same requirement Docx4j worked for me.It has lot of helpers docx4j documentation
My goal is to display the appropriate file, when the user clicks on a pdf or xls link.
The contents of a pdf or xlsfile are stored as a blob in a table. A stored procedure takes the file id as an input parameter and returns the blob as output.
I want to be able to display the file and am not sure how to go about it. On doing some reading it looks like i could use itest.
Is there a way to convert the blob to a pdf(or xls), using itext. Is this possible?
I was unable to find any examples that use a blob datatype.
(can't comment on David solution due to low reputation)
If the content on the BLOB record is a PDF binary data, you actually don't need to do anything with iText.
If you are not saving the BLOB to disk before and want (acording to your description) to just display, you could set the content type on the HTTP Response to indicate the browser how to deal with it:
response.setContentType("application/pdf"); // for PDF
response.setContentType("application/vnd.ms-excel"); // For BIFF .xls files
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // For Excel2007 and above .xlsx files
The IOUtils class in the Apache Commons IO library has a method copy which will copy all the bytes from an InputStream to an OutputStream. See the Javadoc.
So once you've got your blob and your HTTP response, you can just write
OutputStream httpOutputStream = httpResponse.getOutputStream();
InputStream blobInputStream = theBlob.getBinaryStream();
IOUtils.copy(blobInputStream, httpOutputStream);
blobInputStream.close();
httpOutputStream.close();
to copy the data. Or you might want to put the two close() calls in a finally block.
If you're not already using Apache Commons, don't forget to download the jar and add it to your classpath.
I am doing a JSP site,using hibernate
where I need to display PDF files,doc files etc . I have byte array of PDF/doc file by webservice and I need to display that byte array as PDF file/doc in HTML.i convet this into pdf by using the following code and its correctly shows in html page
byte[] pdf = new byte[] {}; // Load PDF byte[] into here
if (pdf != null) {
// set pdf content
response.setContentType("application/pdf");
// write the content to the output stream
BufferedOutputStream fos1 = new BufferedOutputStream(
response.getOutputStream());
fos1.write(ba1);
fos1.flush();
fos1.close();
}
for doc file i change the response.ContentType from
response.setContentType("application/pdf");
to
response.setContentType( "application/msword" );
but instead of displaying its is showing a down load window.how can i resolve this issue
Try this:
01 response.setContentLength(pdf.length);
Any proxy or antivirus or firewall may guess the download is completed. So inform the browser how many bytes you wish to transfer.