为什么不在java servlet中创建pdf文档?

我使用iText / Pdfbox创建PDF文档。 当我使用像这样的独立Java类创建PDF时,一切正常:

public static void main(String[] args){ ... ... ... } 

文档已正确创建。

但我需要从Servlet创建一个PDF文档。 我将代码粘贴到get或post方法中,在服务器上运行该servlet,但不创建PDF文档!

此代码作为独立应用程序运行:

在此处输入图像描述

此代码不起作用:

在此处输入图像描述

请阅读文档。 例如,问题的答案如何在不在服务器端存储文件的情况下将PDF提供给浏览器?

您当前正在文件系统上创建文件。 您没有使用response对象,这意味着您没有向浏览器发送任何字节。 这解释了为什么浏览器中没有任何反应。

这是一个简单的例子:

 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()); } } } 

但是,当您直接发送字节时,某些浏览器会遇到问题。 使用ByteArrayOutputStream在内存中创建文件更安全,并告诉浏览器在内容标题中可以预期多少字节:

 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()); } } } 

有关完整源代码,请参阅PdfServlet 。 你可以在这里试试代码: http : //demo.itextsupport.com/book/

你在评论中写道

该演示将PDF文件写入浏览器。 我想将PDF保存在硬盘上。

这个问题可以用两种不同的方式解释:

  1. 您希望将文件写入用户磁盘驱动器上的特定目录,而无需任何用户交互。 这是禁止的 ! 如果服务器可以强制将文件写入用户磁盘驱动器上的任何位置,那将是一个严重的安全隐患。
  2. 您希望显示一个对话框,以便用户可以将PDF保存在他选择的目录中的磁盘驱动器上,而不是仅在浏览器中显示PDF。 在这种情况下,请仔细查看文档。 你会看到这一行: response.setHeader("Content-disposition","attachment;filename="+ "testPDF.pdf"); 如果希望在浏览器中打开PDF,可以将Content-dispositioninline ,但在问题中, Content-disposition设置为attachment ,触发打开的对话框。

另请参见如何为iText生成的PDF显示“另存为”对话框?