Servlet で JasperReport を出力すると「フォントがない(Font is not available)」と怒られる

0
2732
views

JasperReport Studio で作ったテンプレートを元に、Servlet で出力するとフォントがないよと怒られることがあります。怒られた場合の解決方法をまとめます。

スローされる例外

今回の例では、”GenShinGothic-P-Bold” というフォントがないよ、と例外が投げられています。

情報: net.sf.jasperreports.engine.util.JRFontNotFoundException: Font "GenShinGothic-P-Bold" is not available to the JVM. See the Javadoc for more details. [日 12 10 11:47:18 JST 2017]

例外の原因

例外の原因は、Servlet 内で 必要なフォントの設定ができていないためです。では、どうすればいいのか。別途フォントの設定が必要になった背景から順に見ていきましょう。

例外の背景

テンプレート内のフォントの埋め込み

Servlet 側でフォントの設定が必要になったそもそもの原因は、テンプレート内でフォントを埋め込んだことに起因します。テンプレートに使用したフォントにどんな設定がされているかは、プロジェクトの設定を見れば分かります。

フォント設定の確認手順

フォントの設定を確認するには、Jaspersoft Studio で対象のプロジェクトを右クリックしメニューから [properties] を選択します。

プロパティ画面の左メニューから [fonts] を選択。下図の例ではすでに6つのフォントを設定しています。新たなフォントの追加は、画面の右側にある [Add] ボタンを押します。すでに登録済みのフォントの設定を見るには [Edit] ボタンを押します。

で、今回重要なのはこの [Add] ボタンや [Edit] ボタンを押した際に現れる、フォント設定画面での [Embed this font in PDF document] のチェックボックスです。下図のようにチェックボックスにチェックが入っていれば、PDF へのフォント埋め込み設定をしたことになります。

Embed this font in PDF document とは

[Embed this font in PDF document] とは、作成した PDF の利用者の PC 内に該当の種類のフォントがなくても、フォントを表示させる機能です。なので、テンプレート内に特別なフォント(利用者のPC内にないフォント)を埋め込んだ場合は、テンプレートを使った PDF の作成処理をする側である Servlet でもフォント設定を実施する必要があるわけです。

Servlet 側のフォント設定手順

Servlet 側のフォント設定手順は、次の2点を行うだけです。

  1. Jaspersoft Studio で フォントの jar ファイルをエクスポート
  2. Servlet のビルドパスにフォントの jar ファイルを配置

フォント jar のエクスポート

Servlet でフォント設定を行う簡単な方法は、Jaspersoft Studio のフォントエクスポート機能を利用して、フォント設定の jar ファイルを作成する方法です。

jar ファイルの作成

先ほど見た Jaspersoft Studio のフォント設定画面で対象のフォントを選択(複数可)して [Export] ボタンを押します。ボタンを押すと保存先を聞かれるので保存先を指定して、jar ファイルをローカルに保存します。

フォント jar の中身

ちなみにフォント jar を解凍すると(実際の作業にはフォント jar ファイルの解凍は必要ありません)、次の通りのフォルダ構成になっています。

フォント jar ファイルの中身
  │  jasperreports_extension.properties
  │
  └─fonts
      │  fontsfamily1512873782713.xml
      │
      ├─GenShinGothic_P_Bold
      │      GenShinGothic-P-Bold.ttf
      │
      ├─GenShinGothic_P_Light
      │      GenShinGothic-P-Light.ttf
      │
      └─GenShinGothic_P_Regular
              GenShinGothic-P-Regular.ttf

ttf はフォントそのもの(TrueType Font)ですが、他のそれぞれのファイル(xml, properties)の役割を以下に簡単にまとめます。

jasperreports_extension.properties

フォント設定の xml ファイルを指定します。ireportfamily1512873782713 は任意の名前(自動 uuid)です。

net.sf.jasperreports.extension.registry.factory.fonts=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.ireportfamily1512873782713=fonts/fontsfamily1512873782713.xml

fontsfamily1512873782713.xml

テンプレート内のフォント名(fontFamily name=)とフォントの Servlet 内の利用フォントの配置場所(fonts/GenShinGothic_P_Bold/GenShinGothic-P-Bold.ttf)を紐づけます。

<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
	<fontFamily name="GenShinGothic-P-Bold">
		<normal><![CDATA[fonts/GenShinGothic_P_Bold/GenShinGothic-P-Bold.ttf]]></normal>
		<pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
		<pdfEmbedded><![CDATA[true]]></pdfEmbedded>
		<exportFonts/>
	</fontFamily>
	<fontFamily name="GenShinGothic-P-Light">
		<normal><![CDATA[fonts/GenShinGothic_P_Light/GenShinGothic-P-Light.ttf]]></normal>
		<pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
		<pdfEmbedded><![CDATA[true]]></pdfEmbedded>
		<exportFonts/>
	</fontFamily>
	<fontFamily name="GenShinGothic-P-Regular">
		<normal><![CDATA[fonts/GenShinGothic_P_Regular/GenShinGothic-P-Regular.ttf]]></normal>
		<pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
		<pdfEmbedded><![CDATA[true]]></pdfEmbedded>
		<exportFonts/>
	</fontFamily>
</fontFamilies>

フォント jar の配置場所

フォント jar は Servlet のビルドパスに配置します。ビルドツールを利用しない標準的な jar ファイル(ライブラリ)の配置場所は次の場所です。

WebContent/WEB-INF/lib

フォント jar の配置ができたら、Servlet 側のフォント設定は完了です。この状態にして Servlet で JasperReports の作成を行えば、指定したフォントが PDF に埋め込まれた形で出力されます。

PDF 文書プロパティの確認

念のため指定のフォントが埋め込まれたかどうかは、PDF のメニューから [文書プロパティ] – [フォント] を選択します。