【发布时间】:2023-03-05 02:28:01
【问题描述】:
我正在尝试使用 p:media 显示 pdf 文件,但什么也没显示(在对话框中显示 pdf 预览器)。该代码可直接在浏览器上显示,也可用于下载文件。单击预览链接时没有错误返回。下面是代码:
<h:form enctype="multipart/form-data">
<p:dataTable id="files" var="file" value="#{viewBacking.getFileList()}">
<p:column headerText="File">
<h:outputText value="#{file.name}" />
</p:column>
<p:column style="width:5%">
<p:commandLink id="downloadLink" value="download" title="Download File" ajax="false" actionListener="#{viewBacking.getFileSelected(file, 1)}" >
<p:fileDownload value="#{viewBacking.file}" />
</p:commandLink>
</p:column>
<p:column style="width:5%">
<p:commandLink id="previewLink" value="preview" title="Preview File" ajax="false" actionListener="#{viewBacking.getFileSelected(file, 2)}" onclick="dialogPdf.show()">
</p:commandLink>
</p:column>
</p:dataTable>
<p:dialog header="Images" widgetVar="dialogPdf" modal="true" draggable="false" resizable="false" width="1040" height="500">
<p:media value="#{viewBacking.file}" width="100%" height="300px">
</p:media>
</p:dialog>
</h:form>
这是支持 bean:
public class ViewBacking {
private StreamedContent file;
public StreamedContent getFile() {
return file;
}
public StreamedContent getFileSelected(final StreamedContent doc, int mode) throws Exception {
//Mode: 1-download, 2-preview
try {
File localfile = new File(getPath(doc.getName()));
FileInputStream fis = new FileInputStream(localfile);
//If mode preview and extension <> `pdf`, convert to `pdf`
if (mode == 2 && !(doc.getName().substring(doc.getName().lastIndexOf(".") + 1)).matches("pdf")) {
localfile = DocumentConversionUtil.convert(doc.getName(), fis, doc.getName().substring(doc.getName().lastIndexOf(".") + 1), "pdf");
fis = new FileInputStream(localfile.getPath());
}
if (localfile.exists()) {
try {
PortletResponse portletResponse = (PortletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
HttpServletResponse res = PortalUtil.getHttpServletResponse(portletResponse);
if (mode == 1) res.setHeader("Content-Disposition", "attachment; filename=\"" + doc.getName() + "\"");
else if (mode == 2) res.setHeader("Content-Disposition", "inline; filename=\"" + doc.getName().substring(0, doc.getName().lastIndexOf(".")) + ".pdf\"");
res.setHeader("Content-Transfer-Encoding", "binary");
res.setContentType(getMimeType(localfile.getName().substring(localfile.getName().lastIndexOf(".") + 1)));
res.flushBuffer();
OutputStream out = res.getOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
buffer = new byte[4096];
}
file = new DefaultStreamedContent(fis, "application/pdf", "file.pdf"); //--> I tried to add this line to return the file StreamedContent
out.flush();
out.close();
out = null;
} catch (IOException e) {
e.printStackTrace();
} finally {
fis.close();
fis = null;
System.gc();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
如果您需要更多信息,请随时问我。谢谢。
【问题讨论】:
-
交付像 PDF 这样的二进制资源的最佳方式是使用 JSF 2 ResourceHandler。它将在 webapp 和 portlet 环境中工作。我建议您查看jsf2-export-pdf-portlet 演示的源代码以了解如何操作。
-
@NeilGriffin:谢谢,但我只需要将生成的pdf显示到对话框中,而不是从头开始如何生成pdf文件。
-
PrimeFaces MediaRenderer.java 类的源代码表明 p:media 的 value 属性可以是 StreamedContent 的实例(如您所见)或基于字符串的 URL。
标签: java pdf primefaces liferay media