【问题标题】:Question on Java Servlet to open a PDF file using iTextJava Servlet 使用 iText 打开 PDF 文件的问题
【发布时间】:2011-05-11 17:40:47
【问题描述】:

下面的代码抓取一个 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 吗???

【问题讨论】:

    标签: java servlets itext


    【解决方案1】:

    当您使用PdfStamper 时,它会从磁盘读取文件并将其写入baos。当您删除 PdfStamper 时,baos 永远不会被写入。所以当然,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();
    
            }
        } 
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 是否有必要将位从流内复制到外流?这就是 PdfStamper 在幕后所做的吗?
        • PdfStamper 的目的不是复制数据,最终是复制代码文件,但它的作用远不止于此。恕我直言,使用 PdfStamper 将一个流复制到另一个流中并不好(对于性能)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-18
        • 1970-01-01
        • 1970-01-01
        • 2013-04-04
        • 2012-03-06
        • 1970-01-01
        • 2014-05-01
        相关资源
        最近更新 更多