Java 在jsp中显示pdf
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16232916/
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
Displaying pdf in jsp
提问by user1989615
I have written a jsp page to display contents of pdf, but end up with ascii codes in jsp. I want to display the contents of pdf in jsp. Whats the part that I have missed. When I try to write the read content in pdf it shows only ascii values and not in readable format
我写了一个jsp页面来显示pdf的内容,但最终在jsp中得到了ascii代码。我想在jsp中显示pdf的内容。什么是我错过的部分。当我尝试以 pdf 格式写入读取内容时,它仅显示 ascii 值而不是可读格式
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=${encoding}"></head>
<%@page import="java.io.File"%>
<%@page import="java.io.*"%>
<%@page import="javax.servlet.*"%>
<%@page import="com.itextpdf.text.Image"%>
<%@page import="com.itextpdf.text.Document"%>
<%@page import="com.itextpdf.text.DocumentException"%>
<%@page import="com.itextpdf.text.pdf.PdfReader"%>
<%@page import="com.itextpdf.text.pdf.PdfImportedPage"%>
<%@page import="com.itextpdf.text.pdf.PdfWriter"%>
<%@page import="com.itextpdf.text.pdf.PdfContentByte"%>
<%@ page language="java" contentType="application/pdf; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
response.reset();
response.setContentType("application/pdf");
File file = new File("D:\TNWRD_Documents\CHAPTER_II.pdf");
response.setHeader("Content-Type", "application/pdf");
response.setHeader("Content-Disposition",
"inline;filename=Saba_PhBill.pdf");
response.setContentLength((int) file.length());
response.setHeader("Content-Type",
getServletContext().getMimeType(file.getName()));
response.setHeader("Content-Length", String.valueOf(file.length()));
//OPen an input stream to the file and post the file contents thru the
//servlet output stream to the browser
FileInputStream in = new FileInputStream(file);
ServletOutputStream outs = response.getOutputStream();
response.setContentLength(in.available());
byte[] buf = new byte[8192];
int c = 0;
try {
while ((c = in.read(buf, 0, buf.length)) > 0) {
//System.out.println("size:"+c);
outs.write(buf, 0, c);
out.write(outs.toString());
}
} catch (IOException ioe) {
ioe.printStackTrace(System.out);
} finally {
outs.flush();
outs.close();
in.close();
}
%>
</html>
回答by david a.
I could see multiple problems:
我可以看到多个问题:
- There are extra html tags at the top and bottom of your JSP. You do not want them there - you only want to have the pdf contents in your response output.
- The code sets content type is multiple times. That is probably not the root cause, however make sure you do it only once (set it to
application/pdf
) In the while loop, data are first written to the response output stream, then a
toString()
is written to the out (which is actually a Writer instance opened on the response output stream - the one inouts
). Only use the response stream in the loop, aswhile ((c = in.read(buf, 0, buf.length)) > 0) { outs.write(buf, 0, c);
}
- 在 JSP 的顶部和底部有额外的 html 标签。您不希望它们在那里 - 您只想在响应输出中包含 pdf 内容。
- 代码集内容类型是多次。这可能不是根本原因,但是请确保您只执行一次(将其设置为
application/pdf
) 在 while 循环中,数据首先写入响应输出流,然后将 a
toString()
写入 out(实际上是在响应输出流上打开的 Writer 实例 - 那个 inouts
)。仅在循环中使用响应流,如while ((c = in.read(buf, 0, buf.length)) > 0) { outs.write(buf, 0, c);
}
回答by BalusC
JSP is the wrong tool for the job of serving a file download. JSP is designed as a view technology with the intent to easily produce HTML output with taglibs and EL. Basically, with your JSP approach, your PDF file is cluttered with <!DOCTYPE>
, <html>
etc tags and therefore corrupted and not recognizable as a valid PDF file. This is by the way one of the reasons why using scriptletsis a bad practice. It has namely completely confused you as to how stuff is supposed to work. In this particular case, that is using a normal Java class for the file download job.
JSP 是提供文件下载服务的错误工具。JSP 被设计为一种视图技术,旨在使用 taglibs 和 EL 轻松生成 HTML 输出。基本上,使用您的 JSP 方法,您的 PDF 文件中充斥着<!DOCTYPE>
, <html>
etc 标签,因此已损坏且无法识别为有效的 PDF 文件。顺便说一下,这也是为什么使用scriptlet是一种不好的做法的原因之一。它让你完全混淆了东西应该如何工作。在这种特殊情况下,即使用普通 Java 类进行文件下载作业。
You should be using a servletinstead. Here's a kickoff example, assuming that Servlet 3.0 and Java 7 is available:
您应该改用servlet。这是一个启动示例,假设 Servlet 3.0 和 Java 7 可用:
@WebServlet("/foo.pdf")
public class PdfServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
File file = new File("/absolute/path/to/foo.pdf");
response.setHeader("Content-Type", getServletContext().getMimeType(file.getName()));
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "inline; filename=\"foo.pdf\"");
Files.copy(file.toPath(), response.getOutputStream());
}
}
(if Servlet 3.0 is not available, then map it in web.xml
the usual way, if Java 7 is not available, then use a read/write loop the usual way)
(如果 Servlet 3.0 不可用,web.xml
则以通常方式映射它,如果 Java 7 不可用,则以通常方式使用读/写循环)
Just copypaste this class in its entirety into your project and open the desired PDF file by /contextpath/Saba_PhBill.pdf
instead of /contextpath/youroriginal.jsp
(after having organized it in a package and autocompleted the necessary imports in the class, of course).
只需将这个类全部复制粘贴到您的项目中,然后打开所需的 PDF 文件,/contextpath/Saba_PhBill.pdf
而不是/contextpath/youroriginal.jsp
(当然,在将它组织到一个包中并在类中自动完成必要的导入之后)。
E.g. as follows in a JSP where you'd like to show the PDF inline:
例如,在您希望内联显示 PDF 的 JSP 中,如下所示:
<object data="${pageContext.request.contextPath}/Saba_PhBill.pdf" type="application/pdf" width="500" height="300">
<a href="${pageContext.request.contextPath}/Saba_PhBill.pdf">Download file.pdf</a>
</object>
(the <a>
link is meant as graceful degradation when the browser being used doesn't support inlining application/pdf
content in a HTML document, i.e. when it doesn't have Adobe Reader plugin installed)
(<a>
当所使用的浏览器不支持application/pdf
在 HTML 文档中内联内容时,即当它没有安装 Adobe Reader 插件时,该链接意味着优雅降级)
See also:
也可以看看:
回答by Ollie Bennett
Supposing we completely ignore the advice against using a JSP (and as BalusC says - there are BETTER WAYS), here's an uglyand shamefullittle bodge that worked okay for me. It doesn't even set all the right headers, but here goes:
假设我们完全忽略了反对使用 JSP 的建议(正如 BalusC 所说 - 有更好的方法),这里有一个丑陋和可耻的小bodge,对我来说还可以。它甚至没有设置所有正确的标题,但这里是:
<%@ page import="java.io.File" %><%@ page import="org.apache.commons.io.FileUtils" %><%
File pdfFile = (File) request.getAttribute("pdf");
byte[] pdfByteArray = FileUtils.readFileToByteArray(pdfFile);
response.setContentType("application/pdf");
response.getOutputStream().write(pdfByteArray);
response.getOutputStream().flush();
%>
It's important ensure there are no new-lines (or other whitespace) outside the scriptlet tags.
确保 scriptlet 标签外没有换行符(或其他空格)很重要。
They made me do it, okay?!
他们让我这样做,好吗?!