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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5968328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:44:43  来源:igfitidea点击:

Question on Java Servlet to open a PDF file using iText

javaservletsitext

提问by Catfish

The code below grabs a PDF file and displays it in the browser.

下面的代码抓取一个 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();

    }
} 

If I change it to this code, it doesn't return the file. The only difference are the lines that deal with PdfStamper are removed.

如果我将其更改为此代码,则不会返回该文件。唯一的区别是删除了处理 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();

        }
    } 

Why does this only work with PdfStamper? I don't want to do any stamping, I just want to display the PDF in the browser. Is there something I'm missing that basically takes the place of PdfStamper in iText???

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

回答by Femi

When you use PdfStamperit is reading in the file from the disk and writing it to baos. When you removed the PdfStamper, baosNEVER GETS WRITTEN TO. So of course, baosis empty, so never actually returns anything.

当您使用PdfStamper它时从磁盘读取文件并将其写入baos. 当您删除 时PdfStamperbaos永远不会被写入。所以当然baos是空的,所以实际上永远不会返回任何东西。

EDIT: you want to actually do this (the PdfReader is only necessary if you want to modify the PDF):

编辑:你想真正做到这一点(只有在你想修改 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();

        }
    } 

回答by user179437

If the PDF file is already exists, then you don't have to use itext. You just read data from the file and write it into OutputStream of response.

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

Here is some code

这是一些代码

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

    }
} 

回答by abalogh

You aren't using the reader in the second example. I'm not familiar with PdfStamper but I'd guess it uses the reader and thus the contents of your file will be in baos, but not in the second case.

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