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

时间:2011-05-11 17:40:48

标签: java servlets itext

下面的代码抓取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。有没有我遗漏的东西基本上取代了PdfStamper在iText ???

3 个答案:

答案 0 :(得分:3)

当您使用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();

        }
    } 

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

    }
}