JasperReportでの日本語フォント、外字の利用

JasperReportsでのPDF出力で、日本語フォントや外字を利用する方法を紹介します。
# 前提条件
* JasperReport 6.x.x

# やりたいこと
* PDFを開く環境によって、使用されるフォントが変わるとレイアウト崩れや異なる字形で表示される等の問題が起きるので、PDFにフォントを埋め込みたい
 * 今回使用するフォントは[IPAフォント](https://ipafont.ipa.go.jp/)
     * ipaexg.ttf (IPAexゴシック)
     * ipaexm.ttf (IPAex明朝)
 * ただし、フォントが埋め込まれたPDFファイルのサイズは、そうでないものに比べ大きくなる
* 外字もPDFに出力したい
    * 外字がインストールされていない端末やプリンターでも表示できるよう、外字もPDFに埋め込む。 

# 準備
Mavenプロジェクトを作成し、dependencyにjasperreportsを追加します。

```xml
<dependency>
    <groupId>net.sf.jasperreports</groupId>
    <artifactId>jasperreports</artifactId>
    <version>6.10.0</version>
</dependency>
```

# 日本語フォントの利用
## 使用するフォントをclasspathに配置する
プロジェクトの`src/main/resources/fonts`へフォントファイル(*.ttf)を配置します。これにより、jar(やwar)にフォントファイルが含まれますので、実際に動作するサーバーにフォントファイルを導入する必要はありません。

## fontFamily定義xmlを作成
`src/main/resources/fonts/fontsfamily-ipa.xml`を作成し、以下の定義を記載します。フォントファイルのパスはclasspathからのパスを記載します。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
  <fontFamily name="IPAexゴシック">
    <normal><![CDATA[fonts/ipaexg.ttf]]></normal>
    <pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
    <pdfEmbedded><![CDATA[true]]></pdfEmbedded>
  </fontFamily>
  <fontFamily name="IPAex明朝">
    <normal><![CDATA[fonts/ipaexm.ttf]]></normal>
    <pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
    <pdfEmbedded><![CDATA[true]]></pdfEmbedded>
  </fontFamily>
</fontFamilies>
```
※ `<pdfEncoding>`の`Identity-H`は横書きを示す。縦書きは`Identity-V`。
※ `<pdfEmbedded>`に`true`を設定することで、PDFにフォントを埋め込まれる。

## fontFamily定義xmlを読み込むよう設定
JasperReportsの拡張定義ファイルsrc/main/resources/jasperreports_extension.properties`を作成し、下記の定義を記載します。このファイルのパスや名前は固定(JasperReportsの仕様)です。


```properties
net.sf.jasperreports.extension.registry.factory.fonts=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.ipafonts=fonts/fontsfamily-ipa.xml
```

## レイアウト定義ファイルにフォントを指定する
fontFamily定義xmlに定義したフォント名(fontFamilyのname)をText FieldやStatic Textに指定します。

# 外字の使用
## 外字用フォントをクラスパスに配置する
IPAフォントと同様にプロジェクトの`src/main/resources/fonts`へ外字のフォントファイルを配置します。外字フォントファイルは通常`EUDC.tte`という名前ですが、JasperReportsが認識してくれるよう拡張子を`.ttf`に変更(rename)します。
※ `EUDC.euf`というファイルもありますが、こちらは外字エディタが編集用に利用しているファイルですので、classpathに入れる必要はありません。

## fontFamily定義xmlに外字を追加
先に定義したfontFamily定義xmlに外字を示すfontFamilyを追加します

```xml
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
  ...
  <fontFamily name="_EUDC">
    <normal><![CDATA[fonts/EUDC.ttf]]></normal>
    <pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
    <pdfEmbedded><![CDATA[true]]></pdfEmbedded>
  </fontFamily>
</fontFamilies>
```

## IPAフォントと合わせて使用できるようにする
このままでは、外字のみのフォントが定義されただけですが、実際には通常の文章の中に外字が登場します。従って、他のフォントを同時に利用できるように定義する必要があります。
ここでは、フォントに`IPAexゴシック`や`IPAex明朝`が指定されたときに、外字も合わせて表示されるようにfontFamily定義xmlに`fontSet`を定義し、元の`fontFamily`のnameを変更します。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
  <fontFamily name="_IPAexゴシック"> <!-- nameに_を追加 -->
    <normal><![CDATA[fonts/ipaexg.ttf]]></normal>
    <pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
    <pdfEmbedded><![CDATA[true]]></pdfEmbedded>
  </fontFamily>
  <fontFamily name="_IPAex明朝">
    <normal><![CDATA[fonts/ipaexm.ttf]]></normal>
    <pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
    <pdfEmbedded><![CDATA[true]]></pdfEmbedded>
  </fontFamily>
  <fontFamily name="_EUDC">
    <normal><![CDATA[fonts/EUDC.ttf]]></normal>
    <pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
    <pdfEmbedded><![CDATA[true]]></pdfEmbedded>
  </fontFamily>

  <fontSet name="IPAexゴシック">
    <family familyName="_IPAexゴシック" primary="true" />
    <family familyName="_EUDC" />
  </fontSet>
  <fontSet name="IPAex明朝">
    <family familyName="_IPAex明朝" primary="true" />
    <family familyName="_EUDC" />
  </fontSet>
</fontFamilies>
```

これで、IPAフォントで表示できない文字は外字フォントを使用するようになります。