【问题标题】:Pdf file not loading properly created by the servletservlet 创建的 Pdf 文件未正确加载
【发布时间】:2015-05-16 21:02:06
【问题描述】:

朋友们,我已经实现了一个 jsp 表单,它接受 pdf 文件的标题、描述和内容等输入。当提交 jsp 表单时,使用 itext 在名为 'pdfGenServlet.java' 的 servlet 的帮助下创建 pdf。

我的jsp表单是

<form action="pdfGenServlet1" method="get" enctype="application/x-www-form-urlencoded">
                <!-- input notes title-->
                <div class="form-group">
                    <div class="input-group">
                        <input type="text" class="form-control" placeholder="Title of the notes" name="title">
                    </div>
                </div>
                <!-- input notes description-->
                <div class="form-group">
                    <div class="input-group">
                        <input type="text" class="form-control" placeholder="Enter short description" name="description">
                    </div>
                </div>

                <div class="form-group">
                  <textarea name="content" id="myEditor"></textarea>

                 <div id="button-panel" class="panel panel-default">
                      <p>
                          <button type="submit" class="btn btn-primary "><span class="glyphicon glyphicon-plus"></span><strong> Create Note</strong></button>
                          <button class="btn btn-primary" type="reset"><strong>Reset</strong></button>
                      </p><!-- buttons -->
                 </div><!-- panel Button -->

                </div>

            </form> 

servlet 'pdfGenServlet.java'

//imports for itext
import java.io.FileOutputStream;
import java.io.StringReader;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.html.simpleparser.HTMLWorker; // deprecated
import com.itextpdf.text.pdf.PdfWriter;

//servlet imports
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//File handling and java util
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.Date;


@WebServlet("/pdfGenServlet1")
public class pdfGenServlet1 extends HttpServlet {
    private static final long serialVersionUID = 1L;

/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    try {

        //Font for using with itext
        Font bfBold18 = new Font(FontFamily.TIMES_ROMAN, 18, Font.BOLD, new BaseColor(0, 0, 0)); 
        Font bfBold12 = new Font(FontFamily.TIMES_ROMAN, 12, Font.BOLD, new BaseColor(0, 0, 0)); 

        String title = request.getParameter("title");
        String description = request.getParameter("description");
        String notes_content = request.getParameter("content");
        Date date = new Date();

        Document document = new Document(PageSize.A4);
        PdfWriter.getInstance(document, new FileOutputStream("C://BEProject//PreparedNotes//testpdf1.pdf"));
        HTMLWorker htmlWorker = new HTMLWorker(document);
        document.open();

        document.addAuthor("Real Gagnon");
        document.addCreator("Real's HowTo");
        document.addSubject("Thanks for your support");
        document.addCreationDate();
        document.addTitle("Please read this");

        //
        document.addCreationDate();
        document.add(new Paragraph("TITLE: ", bfBold18));
        document.add(new Paragraph(title,bfBold12));
        document.add(new Paragraph("\n"));
        document.add(new Paragraph(String.format("Created on: " + date.toString())));
        document.add(new Paragraph("DESCRIPTION: ", bfBold18));
        document.add(new Paragraph(description,bfBold12));
        document.add(new Paragraph("\n"));

        htmlWorker.parse(new StringReader(notes_content));
        // step 5
        document.close();

        response.setHeader("Content-disposition", "attachment; filename= testpdf1.pdf");

        response.setContentType("application/pdf");

    } catch (DocumentException e) {

        e.printStackTrace();
    }




}

} 请自己尝试代码。您会看到 pdf 文件自动创建下载,但打开时显示正在加载,但不会像这样加载

当在 'C://BEProject//PreparedNotes//testpdf1.pdf' 的 pdfGenServlet 中显示的目录中制作相同的文件时。 手动打开 testpdf1.pdf 时,它会正确打开。 请帮忙

【问题讨论】:

    标签: java jsp servlets pdf itext


    【解决方案1】:

    您在本地磁盘上创建了一个 PDF,并设置了一些发送到浏览器的标题。您不会向浏览器发送任何字节,因此您不应期望在浏览器中看到任何内容。这与您描述的行为一致。

    在另一个答案中,有人告诉您将 PDF 字节写入HttpServletResponse。最简单的方法是遵循the book I wrote about iText 中的示例,更具体地说,是Hello 示例:

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

    你可以试试这个例子here

    在理想情况下,这适用于所有浏览器。不幸的是,并非所有的浏览器都是一样的,因此您可能希望按照PdfServlet 示例以更具防御性的方式编写代码:

    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();
            // if you also want to write these bytes to a file, add:
            OutputStream fos = new FileOutputStream(pathToFile);
            baos.writeTo(fos);
            fos.flush();
            fos.close();
        }
        catch(DocumentException e) {
            throw new IOException(e.getMessage());
        }
    }
    

    你可以试试这个 servlet here。如您所见,我们现在首先在内存中创建文件。我们这样做,以便我们可以设置内容长度的标头(某些浏览器需要这样做)。我还设置了一些其他可能不需要的标题,但多年来根据成千上万 iText 用户的反馈添加到我的示例中。

    【讨论】:

    • 先生,我希望在浏览器中显示文件以及在目录中创建文件...我该如何完成?
    • 作为一名开发人员,您可能已经学会了如何将字节写入文件。好吧,在我的第二个示例中,ByteArrayOutputStream 中有字节。将这些写入文件,然后您的文件就在磁盘上。我已经更新了我的答案。
    • 作为替代方案,您可以将文件写入服务器上可从 WWW 访问的目录,并使用 response.sendRedirect("/public/unique12345.pdf") 之类的内容将用户重定向到生成的 PDF。但是:在这种情况下,PDF 将是公开的,拥有正确 URL 的每个人都可以看到它。这可能不是您(您的雇主)想要的。
    • 谢谢...它按照您的建议工作。非常感谢你。
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    相关资源
    最近更新 更多