【问题标题】:Imposible to render StreamedContent into media using primefaces无法使用 primefaces 将 StreamedContent 渲染到媒体中
【发布时间】:2018-02-06 08:36:24
【问题描述】:

我已经尝试了数千种方法来尝试在网络浏览器中显示 pdf,这是我的 xhtml 文件的一部分:

<p:media value="registerController.showFile" width="300" height="450" player="pdf" />

还有控制器:

@ManagedBean
@SessionScoped
public class RegisterController implements Serializable {

private static final long serialVersionUID = 1L;
StreamedContent showFile;

public StreamedContent getShowFile() {

    Path pdfPath = Paths.get("path\\to\\image");
    byte[] pdf = null;

    try {
        pdf = Files.readAllBytes(pdfPath);
    } catch (Exception e) {}

    ByteArrayInputStream b = new ByteArrayInputStream(pdf);
    DefaultStreamedContent d = new DefaultStreamedContent(b, "application/pdf");
    return d;
}

public void setPintaArchivo(StreamedContent showFile) {
    this.showFile = showFile;
    }
}

在控制台的浏览器中出现 404 错误,以下是一些我没有成功的建议:

【问题讨论】:

    标签: jsf primefaces


    【解决方案1】:

    如果你有一个完整路径(从资源文件夹)到已经生成的 PDF 文件,你可以在你的 xhtml 中加载:

    <object id="pdf_document" type="application/pdf" data="#{youBean.documentPath}?pfdrid_c=true" width="100%" height="500px">Your browser does not support this feature!</object>
    

    好吧,如果你想从 webservice 返回的字节流中显示 pdf 内容,你可以使用 primefaces-extensions 的 documentViewer 组件(使用 PDF.js)

    所以你需要在你的bean中加载一个字节流并生成一个StreamedContent

    @ManagedBean
    @SessionScoped
    public class StreamBean implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private StreamedContent pdfContent;
    
        public void load() {
            try {
                // Simulate getting byte[] from external source, like webservice
                ClassLoader classloader = Thread.currentThread().getContextClassLoader();
                InputStream inputStream = classloader.getResourceAsStream("file-sample.pdf");
    
                int byteReaded = 0;
                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                byte[] data = new byte[1024];
    
                while ((byteReaded = inputStream.read(data, 0, data.length)) != -1)
                    buffer.write(data, 0, byteReaded);
                buffer.flush();
                byte[] pdfBytes = buffer.toByteArray();
    
                // Create the StreamedContent with readed pdf file
                pdfContent = new DefaultStreamedContent(new ByteArrayInputStream(pdfBytes), "application/pdf");
    
            } catch (IOException e) {
                // Manage your exception here
                e.printStackTrace();
            }
        }
    
        public StreamedContent getPdfContent() {
            return pdfContent;
        }
    }
    

    重要提示:不要把@PostConstruct放在load()方法上,它会在preRender事件中被调用:

    <ui:composition template="/your-template.xhtml" ... xmlns:pe="http://primefaces.org/ui/extensions">
    
        <ui:define name="pageBody">
    
            <f:metadata>
                <f:event type="preRenderView" listener="#{streamBean.load()}" />
            </f:metadata>                   
    
            <pe:documentViewer height="450" value="#{streamBean.pdfContent}" download="file-sample.pdf" />  
    
        </ui:define>
    
    </ui:composition>
    

    注意:要小心 primefaces 和 primefaces-extensions 版本,在这种情况下我使用过:

    <dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>6.1</version>
    </dependency>
    <dependency>
        <groupId>org.primefaces.extensions</groupId>
        <artifactId>primefaces-extensions</artifactId>
        <version>6.1.0</version>
    </dependency>
    

    【讨论】:

    • 没错,我需要使用一个返回包含 pdf 文档的字节数组的 Web 服务
    • @OliverSoria 好的,但是您需要在问题中指定来源(不是文件)。希望答案更新对你有所帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    相关资源
    最近更新 更多