【发布时间】:2011-08-24 00:39:54
【问题描述】:
我只是想问一下是否有使用 ServletOutputStream 在网页中输出 PDF 的方法?例如,如果没有安装 Adobe 插件或未使用 Chrome,我想让 PDF 仍然显示。
【问题讨论】:
我只是想问一下是否有使用 ServletOutputStream 在网页中输出 PDF 的方法?例如,如果没有安装 Adobe 插件或未使用 Chrome,我想让 PDF 仍然显示。
【问题讨论】:
用户将必须在其 PC 上安装某种类型的 PDF 查看器来打开/阅读 PDF 文件,无论是 Adobe Reader 还是其他软件。您可以通过发送正确的 HTTP 标头向用户发送 PDF 文件,以便在浏览器中打开或下载(另存为附件)。具体来说:
Content-type: application/pdf
Content-Disposition: attachment; filename=downloaded.pdf
Content-Length: XXX
Content-Transfer-Encoding: base64
Content-Disposition 标头是建议下载与“在浏览器中打开”的标头。一旦您
已发送标头,发送一个空行,然后写出您的数据(通常为 base64 编码)。
【讨论】:
你的 servlet 可以输出它想要的任何类型的文档;但是,浏览器只会显示它知道如何显示的文档,无论是本机(例如 HTML、文本、GIF、PNG、JPG 等)还是通过插件(PDF、SWF 等)。
如果您的 servlet 输出一个有效的 PDF 文档,而浏览器无法在本地显示它(如 Chrome 可以)或无法加载插件来呈现它(如 Adobe),那么它可能会要求用户保存它或选择一个可以显示它的程序。
【讨论】:
+1 因为是一个有效的问题。
客户端
您可以使用 pdf.js 来自 mozilla 的 javascript 库将 pdf 显示为图像
服务器端
如果您的 pdf 位于文件系统 modified from here
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String pdfFileName = "pdf-test.pdf";
String contextPath = getServletContext().getRealPath(File.separator);
File pdfFile = new File(contextPath + pdfFileName);
response.setContentType("application/pdf");
response.addHeader("Content-Disposition", "inline; filename=" + pdfFileName)
response.setContentLength((int) pdfFile.length());
FileInputStream fileInputStream = new FileInputStream(pdfFile);
OutputStream responseOutputStream = response.getOutputStream();
int bytes;
while ((bytes = fileInputStream.read()) != -1) {
responseOutputStream.write(bytes);
}
}
如果您使用 pdfbox 之类的库在内存中生成 pdf
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int marginTop = 30;
String title = "HELLO WORLD";
final PDFont fontData = PDType1Font.HELVETICA;
final int fontSize = 8;
//java8 color issue
System.setProperty("sun.java2d.cmm", "sun.java2d.cmm.kcms.KcmsServiceProvider");
final PDPage page = new PDPage();
final PDFont fontLabel = PDType1Font.HELVETICA_BOLD;
final int titleFontSize = 12;
float heightLabelText = fontLabel.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize;
try (final PDDocument pdf = new PDDocument())
{
pdf.addPage(page);
try (PDPageContentStream stream = new PDPageContentStream(pdf, page)) {
float top = page.getMediaBox().getHeight() - marginTop;
float titleWidth = fontLabel.getStringWidth(title) / 1000 * titleFontSize;
stream.setFont(fontLabel, titleFontSize);
stream.beginText();
stream.newLineAtOffset((page.getMediaBox().getWidth() - titleWidth) / 2, top - 25);
stream.showText(title);
stream.endText();
}
try(ByteArrayOutputStream output = new ByteArrayOutputStream()) {
pdf.save(output);
resp.setContentType("application/pdf");
resp.addHeader("Content-Disposition", "inline; filename=\"yourFile" + "-" + new Random().nextInt() + ".pdf" + "\"");
byte[] bytes = output.toByteArray();
resp.getOutputStream().write(bytes);
resp.setContentLength((int) bytes.length);
}
}
}
【讨论】: