Reputation: 105
I have multi module maven project, in that there is a process of request generation and in this process there are some upload component of vaadin in these we are uploading some documents that must be only png, jpgs, pdf and bmp. Now at last of this process i am merging all the document types into one pdf and then downloading it with file downloader.
The function i am calling on a button click event is:
/**
* This function is responsible for getting
* all documents from request and merge
* them in a single pdf file for
* download purposes
* @throws Exception
*/
protected void downloadMergedDocument() throws Exception {
// Calling create pdf function for merged pdf
createPDF();
// Setting the merged file as a resource for file downloader
Resource myResource = new FileResource(new File (mergedReportPath +request.getWebProtocol()+ ".pdf"));
FileDownloader fileDownloader = new FileDownloader(myResource);
// Extending the download button for download
fileDownloader.extend(downloadButton);
}
/**
* This function is responsible for providing
* the PDF related to a particular request that
* contains all the documents merged inside it
* @throws Exception
*/
private void createPDF() throws Exception {
try{
// Getting the current request
request = evaluationRequestUI.getRequest();
// Fetching all documents of the request
Collection<DocumentBean> docCollection = request.getDocuments();
// Initializing Document of using itext library
Document doc = new Document();
// Setting PdfWriter for getting the merged images file
PdfWriter.getInstance(doc, new FileOutputStream(mergedReportPath+ "/mergedImages_" + request.getWebProtocol()+ ".pdf"));
// Opening document
l_doc.open();
/**
* Here iterating on document collection for the images type
* document for merging them into one pdf
*/
for (DocumentBean documentBean : docCollection) {
byte[] documents = documentBean.getByteArray();
if(documentBean.getFilename().toLowerCase().contains("png") ||
documentBean.getFilename().toLowerCase().contains("jpeg") ||
documentBean.getFilename().toLowerCase().contains("jpg") ||
documentBean.getFilename().toLowerCase().contains("bmp")){
Image img = Image.getInstance(documents);
doc.setPageSize(img);
doc.newPage();
img.setAbsolutePosition(0, 0);
doc.add(img);
}
}
// Closing the document
doc.close();
/**
* Here we get all the images type documents merged into
* one pdf, now moving to pdfbox for searching the pdf related
* document types in the request and merging the above resultant
* pdf and the pdf document in the request into one pdf
*/
PDFMergerUtility utility = new PDFMergerUtility();
// Adding the above resultant pdf as a source
utility.addSource(new File(mergedReportPath+ "/mergedImages_" + request.getWebProtocol()+ ".pdf"));
// Iterating for the pdf document types in the collection
for (DocumentBean documentBean : docCollection) {
byte[] documents = documentBean.getByteArray();
if(documentBean.getFilename().toLowerCase().contains("pdf")){
utility.addSource(new ByteArrayInputStream(documents));
}
}
// Here setting the final pdf name
utility.setDestinationFileName(mergedReportPath +request.getWebProtocol()+ ".pdf");
// Here final merging and then result
utility.mergeDocuments();
}catch(Exception e){
m_logger.error("CATCH", e);
throw e;
}
}
Note: mergedReportPath is a path defined for pdf files to be stored and then
retreive from there for download purposes.
Now, i have two problems in that:
Upvotes: 0
Views: 2258
Reputation: 18851
In the 2.0 version of PDFBox, you can set an output stream with setDestinationStream()
. Thus, you just call
response.setContentType("application/pdf");
OutputStream os = response.getOutputStream();
utility.setDestinationStream(os);
utility.mergeDocuments();
os.flush();
os.close();
You can't set the response size this way; if you have to, use ByteArrayOutputStream
like in Bruno's answer or this one.
Upvotes: 2
Reputation: 77528
In the comment section of your question, you have clarified that you don't need the file on disk, but that you want to send the PDF to the browser. You want to know how to achieve this. This is explained in the official documentation: How can I serve a PDF to a browser without storing a file on the server side?
This is how you create a PDF in memory:
// step 1
Document document = new Document();
// step 2
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baos);
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello"));
// step 5
document.close();
Merging PDFs is done with PdfCopy
: How to merge documents correctly?
You need to apply the same principle as above to those examples: replace the FileOutputStream
by a ByteArrayOutputStream
.
Now you have PDF bytes that are stored in the baos
object. We can send it to the browser like this:
// setting some response headers
response.setHeader("Expires", "0");
response.setHeader("Cache-Control",
"must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
// setting the content type
response.setContentType("application/pdf");
// the contentlength
response.setContentLength(baos.size());
// write ByteArrayOutputStream to the ServletOutputStream
OutputStream os = response.getOutputStream();
baos.writeTo(os);
os.flush();
os.close();
Make sure to read the documentation if you have further questions.
Upvotes: 0