servlet 创建的 PDF 文件未正确加载
Pdf file not loading properly created by the servlet
朋友们,我已经实现了一个 jsp 表单,它接受 pdf 文件的标题、描述和内容等输入。当提交 jsp 表单时,将在名为 'pdfGenServlet.java'.
的 servlet 的帮助下使用 itext 创建 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 手动打开时,它会正确打开。
请帮忙
您在本地磁盘上创建了一个 PDF,并设置了一些 header 发送到浏览器的文件。您不会向浏览器发送任何字节,因此您不应期望在浏览器中看到任何内容。这与您描述的行为一致。
在另一个答案中,有人告诉您将 PDF 字节写入 HttpServletResponse
。最简单的方法是遵循 the book I wrote about iText, more specifically, the 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。如您所见,我们现在首先在内存中创建文件。我们这样做,以便我们可以为内容长度设置 header(某些浏览器需要这样做)。我还设置了其他一些可能不是必需的 headers,但多年来根据成千上万 iText 用户的反馈将其添加到我的示例中。
朋友们,我已经实现了一个 jsp 表单,它接受 pdf 文件的标题、描述和内容等输入。当提交 jsp 表单时,将在名为 'pdfGenServlet.java'.
的 servlet 的帮助下使用 itext 创建 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 手动打开时,它会正确打开。 请帮忙
您在本地磁盘上创建了一个 PDF,并设置了一些 header 发送到浏览器的文件。您不会向浏览器发送任何字节,因此您不应期望在浏览器中看到任何内容。这与您描述的行为一致。
在另一个答案中,有人告诉您将 PDF 字节写入 HttpServletResponse
。最简单的方法是遵循 the book I wrote about iText, more specifically, the 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。如您所见,我们现在首先在内存中创建文件。我们这样做,以便我们可以为内容长度设置 header(某些浏览器需要这样做)。我还设置了其他一些可能不是必需的 headers,但多年来根据成千上万 iText 用户的反馈将其添加到我的示例中。