关于Java Servlet使用iText打开PDF文件的问题

下面的代码抓取PDF文件并在浏览器中显示。

import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; import com.lowagie.text.pdf.PdfStream; import com.lowagie.text.pdf.PdfWriter; public class WelcomeServlet extends HttpServlet { private static final String DOCUMENT_LOCATION = "H:\\testPDF.pdf"; // a test pdf on my PC @Override public void init(ServletConfig config) throws ServletException { super.init(config); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfReader reader = new PdfReader(DOCUMENT_LOCATION); PdfStamper stamper = null; try { stamper = new PdfStamper(reader, baos); } catch (DocumentException e) { e.printStackTrace(); } try { stamper.close(); } catch (DocumentException e) { System.out.println("Why is it making me do this?"); e.printStackTrace(); } // set some response headers response.setHeader("Expires", "0"); response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); response.setHeader("Pragma", "public"); response.setContentType("application/pdf"); response.setContentLength(baos.size()); OutputStream os = response.getOutputStream(); baos.writeTo(os); os.flush(); os.close(); } } 

如果我将其更改为此代码,则不会返回该文件。 唯一的区别是删除了处理PdfStamper的行。

 import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; import com.lowagie.text.pdf.PdfStream; import com.lowagie.text.pdf.PdfWriter; public class WelcomeServlet extends HttpServlet { private static final String DOCUMENT_LOCATION = "H:\\testPDF.pdf"; // a test pdf on my PC @Override public void init(ServletConfig config) throws ServletException { super.init(config); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfReader reader = new PdfReader(DOCUMENT_LOCATION); // set some response headers response.setHeader("Expires", "0"); response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); response.setHeader("Pragma", "public"); response.setContentType("application/pdf"); response.setContentLength(baos.size()); OutputStream os = response.getOutputStream(); baos.writeTo(os); os.flush(); os.close(); } } 

为什么这只适用于PdfStamper? 我不想做任何标记,我只想在浏览器中显示PDF。 有什么我想念的东西基本上取代了iText中的PdfStamper ???

当您使用PdfStamper它正在从磁盘读取文件并将其写入baos 。 当你删除了PdfStamperbaos从来没有PdfStamper 。 当然, baos是空的,所以从来没有真正返回任何东西。

编辑:您想要实际执行此操作(仅当您要修改PDF时才需要PdfReader):

 private static void copy(InputStream is, OutputStream os) throws IOException { byte buffer[] = new byte[8192]; int bytesRead, i; while ((bytesRead = is.read(buffer)) != -1) { os.write(buffer, 0, bytesRead); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { FileInputStream baos = new FileInputStream(DOCUMENT_LOCATION); // set some response headers response.setHeader("Expires", "0"); response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); response.setHeader("Pragma", "public"); response.setContentType("application/pdf"); response.setContentLength(new File(DOCUMENT_LOCATION).length()); OutputStream os = response.getOutputStream(); copy(baos, os); os.flush(); os.close(); } } 

您没有在第二个示例中使用阅读器。 我不熟悉PdfStamper,但我猜它会使用阅读器,因此你的文件内容将是baos,但不是第二种情况。

如果PDF文件已经存在,那么您不必使用itext。 您只需从文件中读取数据并将其写入响应的OutputStream。

这是一些代码

 public class WelcomeServlet extends HttpServlet { private static final String DOCUMENT_LOCATION = "H:\\testPDF.pdf"; // a test pdf on my PC @Override public void init(ServletConfig config) throws ServletException { super.init(config); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // set some response headers response.setHeader("Expires", "0"); response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); response.setHeader("Pragma", "public"); response.setContentType("application/pdf"); InputStream in = new FileInputStream(DOCUMENT_LOCATION); OutputStream out = response.getOutputStream(); // Copy the bits from instream to outstream byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } in.close(); } }