How can I serve a PDF to a browser without storing a file on the server side?
How can I serve the PDF file to the client without storing the file on the server side and allow the client side to directly download the file that is generated?
I have two methods. One that generates a PDF at the server side and another that serves the PDF to the client side:
public void generatePDF() throws Exception { Document doc = new Document(); File file = new File("C://New folder//itext_Test.pdf"); FileOutputStream pdfFileout = new FileOutputStream(file); PdfWriter.getInstance(doc, pdfFileout); doc.open(); Paragraph para = new Paragraph("Test"); doc.add(catPart); doc.close(); } public void downloadPDF(HttpServletRequest request, HttpServletResponse response) throws IOException{ response.setContentType("application/pdf"); response.setHeader("Content-disposition","attachment;filename="+ "testPDF.pdf"); try { File f = new File("C://New folder//itext_Test.pdf"); FileInputStream fis = new FileInputStream(f); DataOutputStream os = new DataOutputStream(response.getOutputStream()) response.setHeader("Content-Length",String.valueOf(f.length())); byte[] buffer = new byte[1024]; int len = 0; while ((len = fis.read(buffer)) >= 0) { os.write(buffer, 0, len); } } catch (Exception e) { e.printStackTrace(); } }
Posted on StackOverflow on May 26, 2015 by Mishal Harish
You can use any OutputStream
when creating a PDF file, so in theory, you could use a response.getOutputStream()
. See for instance the Hello Servlet from Chapter 9 of "iText in Action - Second Edition":
public class Listing_09_01_Hello extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/pdf");
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(response.getOutputStream()));
Document doc = new Document(pdfDoc);
doc.add(new Paragraph("Hello World"));
doc.add(new Paragraph(new Date().toString()));
doc.close();
}
}
However, some browsers experience problems when you send bytes directly like this. It's safer to create the file in memory using a ByteArrayOutputStream
and to tell the browser how many bytes it can expect in the content header:
public class Listing_09_03_PdfServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Get the text that will be added to the PDF
String text = request.getParameter("text");
if (text == null || text.trim().length() == 0) {
text = "You didn't enter any text.";
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(baos));
Document doc = new Document(pdfDoc);
doc.add(new Paragraph(String.format(
"You have submitted the following text using the %s method:",
request.getMethod())));
doc.add(new Paragraph(text));
doc.close();
// 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();
}
}
For the full source code, see PdfServlet.
Click this link if you want to see how to answer this question in iText 5.