java pdf model-view-controller pdf-generation itext

java - ¿Cómo puedo entregar un PDF a un navegador sin almacenar un archivo en el lado del servidor?



model-view-controller pdf-generation (4)

Tengo dos métodos Uno que genera un PDF en el lado del servidor y otro que descarga el PDF en el lado del cliente.

¿Cómo puedo hacer esto sin almacenarlo en el lado del servidor y permitir que el lado del cliente lo descargue directamente?

Los siguientes son los dos métodos:

public void downloadPDF(HttpServletRequest request, HttpServletResponse response) throws IOException{ response.setContentType("application/pdf"); response.setHeader("Content-disposition","attachment;filename="+ "testPDF.pdf"); FileInputStream fis = null; DataOutputStream os = null; try { File f = new File("C://New folder//itext3.pdf"); response.setHeader("Content-Length",String.valueOf(f.length())); fis = new FileInputStream(f); os = new DataOutputStream(response.getOutputStream()); byte[] buffer = new byte[1024]; int len = 0; while ((len = fis.read(buffer)) >= 0) { os.write(buffer, 0, len); } } catch (Exception e) { e.printStackTrace(); } finally { fis.close(); os.flush(); os.close(); } response.setHeader("X-Frame-Options", "SAMEORIGIN"); }

Y:

public Document generatePDF() { Document doc = new Document(); try { File file = new File("C://New folder//itext_Test2.pdf"); FileOutputStream pdfFileout = new FileOutputStream(file); PdfWriter.getInstance(doc, pdfFileout); doc.addAuthor("TestABC"); doc.addTitle("Aircraft Details"); doc.open(); Anchor anchor = new Anchor("Aircraft Report"); anchor.setName("Aircraft Report"); Chapter catPart = new Chapter(new Paragraph(anchor), 1); Paragraph para1 = new Paragraph(); Section subCatPart = catPart.addSection(para1); para1.add("This is paragraph 1"); Paragraph para2 = new Paragraph(); para2.add("This is paragraph 2"); doc.add(catPart); doc.close(); } catch (Exception e) { e.printStackTrace(); } return doc; }


Está creando un FileOutputStream para generar pdf. Pero lo que puede hacer es utilizar la secuencia que está presente en HttpServletResponse en el método del lado del servidor y escribir el archivo directamente en él.


Las personas que le aconsejan que use response.getOutputStream() lugar de crear un FileOutputStream tienen razón. Vea, por ejemplo, el Hello Servlet del Capítulo 9 de mi libro:

public class Hello extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/pdf"); try { // step 1 Document document = new Document(); // step 2 PdfWriter.getInstance(document, response.getOutputStream()); // step 3 document.open(); // step 4 document.add(new Paragraph("Hello World")); document.add(new Paragraph(new Date().toString())); // step 5 document.close(); } catch (DocumentException de) { throw new IOException(de.getMessage()); } } }

Sin embargo, algunos navegadores experimentan problemas cuando envía bytes directamente como este. Es más seguro crear el archivo en la memoria usando un ByteArrayOutputStream y decirle al navegador cuántos bytes puede esperar en el encabezado de contenido:

public class PdfServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { // 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."; } // 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(String.format( "You have submitted the following text using the %s method:", request.getMethod()))); document.add(new Paragraph(text)); // step 5 document.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(); } catch(DocumentException e) { throw new IOException(e.getMessage()); } } }

Para el código fuente completo, vea PdfServlet . Puede probar el código aquí: http://demo.itextsupport.com/book/


Puede recibir un OutputStream en su método generatePDF . Si pasa el response.getOutputStream() al método de generación, el PDF se escribirá directamente en la respuesta.


Simplemente llame a este método adecuadamente desde downloadPDF() ; p.ej:

generatePDF(response.getOutputStream());

que llama a este método:

public void generatePDF(OutputStream pdfOutputStream) { Document doc = new Document(); try { PdfWriter.getInstance(doc, pdfOutputStream); doc.addAuthor("TestABC"); doc.addTitle("Aircraft Details"); doc.open(); Anchor anchor = new Anchor("Aircraft Report"); anchor.setName("Aircraft Report"); Chapter catPart = new Chapter(new Paragraph(anchor), 1); Paragraph para1 = new Paragraph(); Section subCatPart = catPart.addSection(para1); para1.add("This is paragraph 1"); Paragraph para2 = new Paragraph(); para2.add("This is paragraph 2"); doc.add(catPart); doc.close(); } catch (Exception e) { e.printStackTrace(); } }