当我尝试使用 iText 创建 PDF 文件并希望之后立即下载时,我遇到了问题。首先我使用 iText 库创建一个 PDF 文件,该文件被写入服务器上的 TEMP 文件夹,这一切都正常。但之后我打电话给下载屏幕,将 PDF 文件从 TEMP 文件夹下载到客户端,这里出了点问题。下载屏幕显示 Firefox(浏览器)图标而不是 Acrobat 图标。当我下载文件时,我只能看到空白的 PDF 页面,但页面数量是正确的。 E.g。我有一个 4 页的 PDF 文件,因此我得到 4 个空白页,没有内容。然而,TEMP 文件夹中的 PDF 文件是正确的,它有 4 页,内容正确。
这是我的 java 代码,它是在用户点击 h:commandLink 时执行
public <E> String createPDF(E type, boolean print) throws Exception {
Document document = new Document();
// create a File name for the document
getPdfNaam(type);
try {
//create a PDF writer
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(TEMP + naam + ".pdf"));
//open the PDF document
document.open();
} catch (Exception e) {
e.printStackTrace();
}
//build the PDF file using iText
buildPDFContent(document, type);
//close the PDF document
close(document);
String downloadFile = TEMP + naam + ".pdf";
//call Servlet for download screen in the browser
ServletContext context = (ServletContext) ContextProvider.getFacesContext().getExternalContext().getContext();
HttpServletResponse response = (HttpServletResponse) ContextProvider.getFacesContext().getExternalContext().getResponse();
response.setContentType("application/force-download");
downloadFile = TEMP + naam + ".pdf";
byte[] buf = new byte[1024];
try {
File file = new File(downloadFile);
long length = file.length();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
ServletOutputStream out = response.getOutputStream();
response.setContentLength((int) length);
while ((in != null) && ((length = in.read(buf)) != -1)) {
out.write(buf, 0, (int) length);
}
in.close();
out.close();
} catch (Exception exc) {
exc.printStackTrace();
}
response.addHeader("Content-Disposition", "attachment; filename=\"" + naam + ".pdf" + "\"");
return null;
}
我找到了在这个网站上调用下载屏幕的代码http://www.winstonprakash.com/articles/jsf/file_download_link.htm我搜索了 Google 和 Stack Overflow,但我找不到任何相关问题。我正在使用 JSF 2.0 任何帮助将不胜感激!
2 回答
内容类型应设置为
application/pdf
,并且在将任何字节写入响应之前应设置内容处置标头,否则设置它为时已晚。此外,您还可以立即将 PDF 写入响应的输出流。总而言之,该方法可以简化如下:
还要确保您正在调用FacesContext 的#responseComplete()来向 JSF 发出信号,告知您已经掌握了响应处理,以便它知道它不需要导航到某个视图。
你可以让输出流立即响应。以下是我的代码: