仕様の中にPDFファイル操作が幾つかあって、検証のため以下試してみました。
- 画面の一部に埋め込み表示する
- 別ウィンドウで表示する
- ファイルとしてダウンロードする
画面の一部に埋め込み表示する
PrimeFacesにはMediaコンポーネントがあって、これを利用すると簡単に実装できました。
xhtmlは以下をbody,formの中に置くだけです。
<p:media value="/pdf/primefaces_users_guide_3_5.pdf" width="500" height="400" />
PDFはPrimeFacesがなんらか特殊なエンジンを設けてるのかな?と思っていましたが、Adobe Readerで開いてるっぽいですね。IEでみたら
と出ていました。
別ウィンドウで表示する
これはhtmlと同じノリで単純にtargetでblankを指定できました。
<h:commandLink value="PDF 別ウィンドウ" action="/pdf/primefaces_users_guide_3_5.pdf" target="_blank"/>
リンクをクリックすると、別タブが起動して
となりました。
2013/4/10追記
この方法でもChromeだとタブが起動したままフリーズしてしまいました(Chromeのバージョン 26.0.1410.43)
とりあえず、以下手順で起動するようになりました。
設定から「詳細設定を表示」を選んで
「コンテンツの設定」を選びます
プラグインを個別に無効にするを選択して
Chrome PDF Viewerを無効にして、Adobe PDF Plug-Inを有効に
これならば動きました。うーむ。。
ファイルとしてダウンロードする
最初、PrimeFacesのFileDownloadコンポーネントが楽そうだと思って、ほぼサンプルの通りに実装してみたのですが、以下エラーで上手くいきませんでした。
java.lang.IllegalStateException: PWC3991: getOutputStream() has already been called for this response
読込処理のStream周りが問題なんだろうなと色々試してみたのですが、そもそもfiledownloadコンポを置いただけでもエラーが出たので違う問題なような気が…うーむ。
これは別途検証するとして、なんかないかなーと探してみた所、OmniFacesを使うと簡単にできるとのこと。
pomに以下を追加して
<dependency>
<groupId>org.omnifaces</groupId>
<artifactId>omnifaces</artifactId>
<version>1.4.1</version>
</dependency>
Backing Beanに以下のようなメソッドを試しに定義して
public void download() throws IOException {
Faces.sendFile(new File("C:\\\\temp\\\\primefaces_users_guide_3_5.pdf"), true);
}
JSFと紐づけると
<h:commandLink value="PDF ダウンロード" actionListener="#{pdfDownloadBean.download()}" />
おお、動いた(^^)
ちなみにOmniFacesはStackoverflowでJava EE回答の常連者であるbaluscさんが作成したライブラリで、PrimeFacesやICEFaces,RichFacesなどと競合するものではなく、足りない部分を補うためのライブラリ、とのことで、PrimeFacesと一緒に使っても問題なさそう(^^;かな
もう少し色々検証してみないとなぁ。。