外字不要のPDF帳票作成サーバー

# PDF帳票作成サーバー　py3o

PDF帳票作成サーバー [py3o](https://github.com/jp-one/py3o-whl) を使って、異体字を含んだPDF帳票を作成することができます。

**PDF帳票の例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/334a988a-d113-2930-1ed7-f0a193df1c79.png)

:::note info
**PDF出力時の付加機能**
1. **フォントの埋め込み**
1. PDFフォーム
1. PDF/Aドキュメント
1. 透かし入りのPDFドキュメント
1. パスワードで保護された PDF ドキュメント

- **本記事では、py3oで作成されるPDF帳票に `IPAmj明朝` フォントが埋め込まれ、異体字が正しい字形で表現されることを確認します。**

:::

## IVS対応

 [py3o](https://apps.odoo.com/apps/modules/16.0/report_py3o_fusion_server/) は、IVSに対応していますので、`IPAmj明朝` フォントの異体字を正しい字形で表現できます。PDF形式ファイルには、使用されているフォントが埋め込まれますので、`IPAmj明朝` フォントがインストールされて**いない**パソコンでも、正しい字形での表示や印刷が可能です。

**参考：[IVD/IVSとは (文字情報技術促進協議会)](https://moji.or.jp/mojikiban/aboutivs/)**

:::note
[IPAmj明朝フォント - https://moji.or.jp/mojikiban/font/](https://moji.or.jp/mojikiban/font/)

IPAmj明朝フォントは、人名の表記等で、細かな字形の差異を特別に使い分ける必要のある業務等での活用を想定したフォントです。また、同フォントを十分に活用するためには、対応したアプリケーションソフトが必要となります。
:::

## Webサービス

py3oは、Webサービスですので、様々なシステムからの連携が可能です。

```plantuml
@startuml
' Archimate図 - https://plantuml.com/ja/archimate-diagram

rectangle ひな形ファイル as tmpl
rectangle データ as data
rectangle フォント as font

rectangle PDF帳票作成サーバー as eng

rectangle PDF帳票 as pdf

!include <archimate/Archimate>

Rel_Flow_Down(data, eng, 入力)

Rel_Serving_Right(tmpl, eng, 読み込み)
Rel_Serving_Left(font, eng, 埋め込み)

Rel_Flow_Down(eng, pdf, 出力)

@enduml
```

1. PDF帳票の **データ** 項目を設計します。
1. LibreOfficeの文書(Writer)で **ひな形ファイル** を作成します。
1. **データ** と **ひな形ファイル** をPDF帳票作成サーバーに送信します(POST)。
1. **データ** と **フォント** とが埋め込まれた **PDF帳票** が送信元に返されます。

|分類|項目|説明|
|----|----|----|
|入力|ひな形ファイル|LibreOfficeの文書ファイル(ODT形式)|
|入力|フォント|帳票で使用するフォント|
|入力|データ|帳票に差し込むデータ|
|**処理**|**PDF帳票作成サーバー**|PDF形式ファイルの生成|
|出力|PDF帳票|PDF形式ファイル|

:::note info
**py3oについて**
py3oはERPであるodooのPDF帳票エンジンとして開発されました
- [odooについて - https://www.odoo.com/](https://www.odoo.com/)
- [Py3o Report Engine - Fusion server support (v16.0)](https://apps.odoo.com/apps/modules/16.0/report_py3o_fusion_server/)

Webサービス(POSTメソッド)として実装されていますので、odooに限らず、様々なシステムからの連携が可能です。
:::

# インストールと起動

Dockerファイルが用意されていますので、PDF帳票作成サーバーをインストールし、起動します。

:::note warn
**動作環境（バージョン）**
- Ubuntu 18.04.6 LTS
- Python 2.7.17
- LibreOffice 6.0.7.3 00m0(Build:3)
- openjdk version "1.8.0_362"
- OpenJDK Runtime Environment (build 1.8.0_362-8u372-ga~us1-0ubuntu1~18.04-b09)
- OpenJDK 64-Bit Server VM (build 25.362-b09, mixed mode)
:::

## 本家

次のリポジトリで、本家のDockerファイルが公開されています。

https://orus.io/xcg/docker/py3o

次の `docker` コマンドで、Dockerイメージを起動することができます。

```bash:Docker - xcgd/py3o
docker run --network host xcgd/py3o:1.0.0
```

## 派生 - IPAmj明朝フォント

異体字を含むPDF帳票を作成するために、 `IPAmj明朝` フォントがインストールされるDockerファイルを利用します。

https://github.com/jp-one/py3o-whl

**ツール（アプリ）のインストール**

- [Docker](https://www.docker.com/get-started/)
- [git](https://git-scm.com/downloads)
- [Visual Studio Code](https://code.visualstudio.com/Download)
- [Visual Studio Code Dev Containers (拡張機能)](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)

**ソースコードの取得（Dockerファイル）**

```
git clone --depth=1 https://github.com/jp-one/py3o-whl.git
```

**VSCodeで開く**

取得した **`py3o-whl` フォルダ** をVisual Studio Codeで開きます。

**Containerを起動**

[Visual Studio Code Dev Containers (拡張機能)](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) がインストールされていれば、 `Reopen in Container` が表示されますので、それを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/4be8b554-4dfd-af22-a516-960cd79e68db.png)

もしくは、左下のアイコン(`><`)をクリックするとメニューが表示されますので、その中から `Reopen in Container` を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/e68ade2e-7c09-76ac-7402-e624b1ff5039.png)

**フォントの確認**

Visual Studio Code で、新しいターミナルを開いて、 `fc-list` コマンドを実行するとサーバーにインストールされているフォントの一覧が表示されます。

```bash:ターミナル
fc-list
```

<details><summary>コマンド実行例</summary>

```bash:フォント一覧
root@1234a56789cd:~# fc-list
/usr/share/fonts/truetype/msttcorefonts/comicbd.ttf: Comic Sans MS:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf: DejaVu Sans Mono:style=Book
/usr/share/fonts/truetype/msttcorefonts/comic.ttf: Comic Sans MS:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/opentype/noto/NotoSerifCJK-Bold.ttc: Noto Serif CJK SC:style=Bold
/usr/share/fonts/opentype/noto/NotoSerifCJK-Bold.ttc: Noto Serif CJK TC:style=Bold
/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman.ttf: Times New Roman:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,thường,Arrunta
/usr/share/fonts/truetype/msttcorefonts/courbi.ttf: Courier New:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,Lodi etzana
/usr/share/fonts/truetype/msttcorefonts/Courier_New_Italic.ttf: Courier New:style=Italic,Cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,nghiêng,Etzana
/usr/share/fonts/truetype/msttcorefonts/Verdana_Italic.ttf: Verdana:style=Italic,Cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,Etzana
/usr/share/fonts/truetype/msttcorefonts/Arial_Italic.ttf: Arial:style=Italic,Cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,nghiêng,Etzana
/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf: DejaVu Sans:style=Book
/usr/share/fonts/truetype/ipaexfont00401/IPAexfont00401/ipaexg.ttf: IPAexGothic,IPAexゴシック:style=Regular
/usr/share/fonts/truetype/msttcorefonts/ariblk.ttf: Arial Black:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/truetype/msttcorefonts/Arial.ttf: Arial:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,thường,Arrunta
/usr/share/fonts/truetype/msttcorefonts/couri.ttf: Courier New:style=Italic,Cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,nghiêng,Etzana
/usr/share/fonts/opentype/noto/NotoSerifCJK-Bold.ttc: Noto Serif CJK JP:style=Bold
/usr/share/fonts/opentype/noto/NotoSerifCJK-Bold.ttc: Noto Serif CJK KR:style=Bold
/usr/share/fonts/truetype/msttcorefonts/Georgia_Bold.ttf: Georgia:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK JP:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK HK:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK KR:style=Regular
/usr/share/fonts/truetype/msttcorefonts/Courier_New.ttf: Courier New:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,thường,Arrunta
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK SC:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK TC:style=Regular
/usr/share/fonts/truetype/msttcorefonts/trebucit.ttf: Trebuchet MS:style=Italic,Cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,Etzana
/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Bold_Italic.ttf: Trebuchet MS:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,Lodi etzana
/usr/share/fonts/truetype/msttcorefonts/arialbd.ttf: Arial:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,đậm,Lodia
/usr/share/fonts/truetype/msttcorefonts/Verdana_Bold.ttf: Verdana:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/usr/share/fonts/truetype/msttcorefonts/georgiab.ttf: Georgia:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/usr/share/fonts/truetype/ipafont00303/IPAfont00303/ipamp.ttf: IPAPMincho,IPA P明朝:style=Regular
/usr/share/fonts/truetype/msttcorefonts/Georgia_Bold_Italic.ttf: Georgia:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,Lodi etzana
/usr/share/fonts/truetype/msttcorefonts/trebuc.ttf: Trebuchet MS:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/truetype/ipafont00303/IPAfont00303/ipag.ttf: IPAGothic,IPAゴシック:style=Regular
/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc: Noto Serif CJK SC:style=Regular
/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc: Noto Serif CJK TC:style=Regular
/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Italic.ttf: Times New Roman:style=Italic,cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,kursywa,Itálico,Курсив,İtalik,Poševno,nghiêng,Etzana
/usr/share/fonts/truetype/msttcorefonts/georgiaz.ttf: Georgia:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,Lodi etzana
/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf: DejaVu Sans:style=Bold
/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf: Comic Sans MS:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/truetype/msttcorefonts/Georgia_Italic.ttf: Georgia:style=Italic,Cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,Etzana
/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc: Noto Serif CJK JP:style=Regular
/usr/share/fonts/truetype/msttcorefonts/Arial_Bold_Italic.ttf: Arial:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,nghiêng đậm,Lodi etzana
/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc: Noto Serif CJK KR:style=Regular
/usr/share/fonts/truetype/msttcorefonts/timesbd.ttf: Times New Roman:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiona,Negrito,Полужирный,Fet,Kalın,Krepko,đậm,Lodia
/usr/share/fonts/truetype/ancient-scripts/Symbola_hint.ttf: Symbola:style=Regular
/usr/share/fonts/truetype/msttcorefonts/Webdings.ttf: Webdings:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/truetype/msttcorefonts/Verdana.ttf: Verdana:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/truetype/ipamjm0601/ipamjm.ttf: IPAmjMincho,IPAmj明朝:style=Regular
/usr/share/fonts/truetype/msttcorefonts/Georgia.ttf: Georgia:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/truetype/ipaexfont00401/IPAexfont00401/ipaexm.ttf: IPAexMincho,IPAex明朝:style=Regular
/usr/share/fonts/truetype/msttcorefonts/trebucbd.ttf: Trebuchet MS:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/usr/share/fonts/truetype/msttcorefonts/cour.ttf: Courier New:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,thường,Arrunta
/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Italic.ttf: Trebuchet MS:style=Italic,Cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,Etzana
/usr/share/fonts/truetype/ipafont00303/IPAfont00303/ipam.ttf: IPAMincho,IPA明朝:style=Regular
/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf: DejaVu Sans Mono:style=Bold
/usr/share/fonts/truetype/ipafont00303/IPAfont00303/ipagp.ttf: IPAPGothic,IPA Pゴシック:style=Regular
/usr/share/fonts/truetype/msttcorefonts/georgiai.ttf: Georgia:style=Italic,Cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,Etzana
/usr/share/fonts/truetype/msttcorefonts/verdanai.ttf: Verdana:style=Italic,Cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,Etzana
/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Bold_Italic.ttf: Times New Roman:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,nghiêng đậm,Lodi etzana
/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Bold.ttf: Trebuchet MS:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/usr/share/fonts/truetype/msttcorefonts/arialbi.ttf: Arial:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,nghiêng đậm,Lodi etzana
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans Mono CJK TC:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans Mono CJK SC:style=Bold
/usr/share/fonts/truetype/msttcorefonts/courbd.ttf: Courier New:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,đậm,Lodia
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans Mono CJK KR:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans Mono CJK HK:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans Mono CJK JP:style=Bold
/usr/share/fonts/truetype/msttcorefonts/Impact.ttf: Impact:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/truetype/msttcorefonts/verdanab.ttf: Verdana:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold.ttf: Courier New:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,đậm,Lodia
/usr/share/fonts/truetype/openoffice/opens___.ttf: OpenSymbol:style=Regular
/usr/share/fonts/truetype/msttcorefonts/verdanaz.ttf: Verdana:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,Lodi etzana
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans Mono CJK SC:style=Regular
/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Bold.ttf: Times New Roman:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiona,Negrito,Полужирный,Fet,Kalın,Krepko,đậm,Lodia
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans Mono CJK TC:style=Regular
/usr/share/fonts/truetype/msttcorefonts/Verdana_Bold_Italic.ttf: Verdana:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,Lodi etzana
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans Mono CJK HK:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans Mono CJK KR:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans Mono CJK JP:style=Regular
/usr/share/fonts/truetype/msttcorefonts/Arial_Black.ttf: Arial Black:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans CJK JP:style=Bold
/usr/share/fonts/truetype/msttcorefonts/Andale_Mono.ttf: Andale Mono:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans CJK KR:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans CJK HK:style=Bold
/usr/share/fonts/truetype/msttcorefonts/trebucbi.ttf: Trebuchet MS:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,Lodi etzana
/usr/share/fonts/truetype/msttcorefonts/timesi.ttf: Times New Roman:style=Italic,cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,kursywa,Itálico,Курсив,İtalik,Poševno,nghiêng,Etzana
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans CJK TC:style=Bold
/usr/share/fonts/truetype/msttcorefonts/andalemo.ttf: Andale Mono:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans CJK SC:style=Bold
/usr/share/fonts/truetype/msttcorefonts/Arial_Bold.ttf: Arial:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,đậm,Lodia
/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold_Italic.ttf: Courier New:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,Lodi etzana
/usr/share/fonts/truetype/msttcorefonts/timesbi.ttf: Times New Roman:style=Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Negrita Cursiva,Lihavoitu Kursivoi,Gras Italique,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,nghiêng đậm,Lodi etzana
/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf: DejaVu Serif:style=Book
/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS_Bold.ttf: Comic Sans MS:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/usr/share/fonts/truetype/msttcorefonts/times.ttf: Times New Roman:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,thường,Arrunta
/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS.ttf: Trebuchet MS:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/truetype/msttcorefonts/ariali.ttf: Arial:style=Italic,Cursiva,kurzíva,kursiv,Πλάγια,Kursivoitu,Italique,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,nghiêng,Etzana

```

</details>

:::note info
**フォントの追加方法**
さらに別のフォントを追加するには、`/usr/share/fonts/` ディレクトリの配下に **フォントファイル** をコピーし、 `fc-cache -vf` コマンドで登録を完了します。
または、（ubuntu 18.04 向けに用意された）そのフォントのインストーラーを使ってインストールします。
:::


### IPAフォントの確認

次のコマンドで、インストールされているフォンを絞り込むことができます。

```bash:ipaで絞り込み
fc-list | grep ipa
```

```bash:実行例
root@1234a56789cd:~# fc-list | grep ipa
/usr/share/fonts/truetype/ipaexfont00401/IPAexfont00401/ipaexg.ttf: IPAexGothic,IPAexゴシック:style=Regular
/usr/share/fonts/truetype/ipafont00303/IPAfont00303/ipamp.ttf: IPAPMincho,IPA P明朝:style=Regular
/usr/share/fonts/truetype/ipafont00303/IPAfont00303/ipag.ttf: IPAGothic,IPAゴシック:style=Regular
/usr/share/fonts/truetype/ipamjm0601/ipamjm.ttf: IPAmjMincho,IPAmj明朝:style=Regular
/usr/share/fonts/truetype/ipaexfont00401/IPAexfont00401/ipaexm.ttf: IPAexMincho,IPAex明朝:style=Regular
/usr/share/fonts/truetype/ipafont00303/IPAfont00303/ipam.ttf: IPAMincho,IPA明朝:style=Regular
/usr/share/fonts/truetype/ipafont00303/IPAfont00303/ipagp.ttf: IPAPGothic,IPA Pゴシック:style=Regular
```

`IPAmj明朝` フォントがインストールされていることを確認できます。
→ `ipamjm.ttf: IPAmjMincho,IPAmj明朝:style=Regular`

# 動作確認

Webブラウザーから [**8765ポート**](http://localhost:8765/) へアクセスすると、 **py3o.fusion** サーバーのページが開きます。
リンク: http://localhost:8765/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/909af26a-fb74-bdb1-296c-00d43baa071e.png)

## 使い方 - Features

[**Features** ページ](http://localhost:8765/features) を開くと、 **特徴** が説明されており、 **Python** による Webサービスの使い方のサンプルコードが紹介されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/996dbc6f-e109-4a9b-25dc-b1fa48041b88.png)

**Webサービスの概要**

|項目|内容|備考|
|----|----|----|
|HTTPメソッド|POST||
|エンドポイント|http://localhost:8765/form|`/form`|
|データ|`targetformat`:出力形式<br>`datadict`:差し込みデータ(辞書)<br>`image_mapping`:固定画像対応付け|（任意）<br>`ignore_undefined_variables`:変数定義エラーの無視<br>`escape_false`:空文字列のFalse化|
|ファイル|ひな形ファイル(`tmpl_file`)と固定画像ファイル(任意)||
|レスポンス|出力ファイルデータ(stream)|エラー情報(400)|

また、サンプルとなるひな形ファイル(ODT形式ファイル)やPDF形式ファイルを起動しているサーバー(`http://localhost:8765/`)からダウンロードできます。

**サンプル１**
- [ひな形ファイル - simple.odt](http://localhost:8765/static/examples/templates/simple.odt)
- [出力結果 - simple.pdf](http://localhost:8765/static/examples/templates/simple.pdf)

**サンプル２**
- [ひな形ファイル - fusion2pdf.odt](http://localhost:8765/static/examples/templates/fusion2pdf.odt)
- [出力結果 - fusion2pdf.pdf](http://localhost:8765/static/examples/templates/fusion2pdf.pdf)

## 動作確認フォーム - Test form

[**Test form** ページ](http://localhost:8765/form) で、PDF帳票の作成ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/9d6382d4-e326-076b-5398-ea2875e158be.png)

### サンプル１

[**Features** ページ](http://localhost:8765/features) の１つ目のサンプルを試します。
このサンプルは、単にODT形式ファイルをPDF形式ファイルに変換するだけのものです。

[**Test form** ページ](http://localhost:8765/form) で、次のとおりに各項目に内容を入力し、 `Submit` ボタンをクリックすると、変換されたPDF形式ファイルがダウンロードされます。

**入力内容**
|項目|内容|備考|
|----|----|----|
|Target Format|pdf||
|Data dictionary|{}|空の辞書|
|Image Mapping|{}|空の辞書|
|Image1|(なし)||
|Template|simple.odt|[ダウンロード - simple.odt](http://localhost:8765/static/examples/templates/simple.odt)|

### サンプル２

[**Features** ページ](http://localhost:8765/features) の２つ目のサンプルを試します。
このサンプルは、ひな形ファイルと差し込みデータからPDF形式ファイルを作成するものです。

[**Test form** ページ](http://localhost:8765/form) で、次のとおりに各項目に内容を入力し、 `Submit` ボタンをクリックすると、データが差し込まれたPDF形式ファイルがダウンロードされます。

**入力内容**
|項目|内容|備考|
|----|----|----|
|Target Format|pdf||
|Data dictionary|{"document": {"person_name": "Aide", "person_surname": "Florent", "person_company": "XCG Consulting", "person_url": "http://www.xcg-consulting.fr"}}||
|Image Mapping|{}|空の辞書|
|Image1|(なし)||
|Template|fusion2pdf.odt|[ダウンロード - fusion2pdf.odt](http://localhost:8765/static/examples/templates/fusion2pdf.odt)|

# IPAmj明朝フォントの活用

py3oと　`IPAmj明朝` フォントを活用して、住所や氏名等に含まれる異体字を正しい字形でPDF帳票として出力することができます。

## インストール

ひな形ファイルを作成するパソコンに **LibreOffice** と **IPAmj明朝フォント** をインストールします。

- [LibreOffice](https://ja.libreoffice.org/)
[→ インストール手順](https://ja.libreoffice.org/get-help/install-howto/)
[→ ダウンロード](https://ja.libreoffice.org/download/download/)
- [IPAmj明朝フォント](https://moji.or.jp/mojikiban/font/)
[→ フォントのインストール方法](https://moji.or.jp/ipafont/installation/)
[→ IPAmj明朝 (Ver.006.01)を窓の杜からダウンロードする](https://forest.watch.impress.co.jp/library/software/ipamjfont/)

:::note warn
**ひな形ファイルを作成するパソコンにのみ必要**
 **LibreOffice** と **IPAmj明朝フォント** のインストールは、 **ひな形ファイルを作成するパソコンにのみ必要** です。
Test formページ等から**PDF帳票サーバーへアクセスするパソコン**へのインストールは **不要** です。
:::

## データ項目の設計

住所１と住所２のデータを用意し、それをひな形ファイルに差し込み出力できるようにします。

|項目|内容|備考|
|----|----|----|
|addr1|住所１|東京都の区|
|addr2|住所２|奈良県の市|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/5745cff0-3628-0161-419d-10b6c1d0923e.png)

[**Test form** ページ](http://localhost:8765/form)  の `Data dictionary` 項目へは、次の内容を入力します。

```json:Data dictionary
{"addr1":"東京都葛飾区","addr2":"奈良県\u845B\uDB40\uDD02城市"}
```

:::note info
**異体字の入力方法とunicodeエスケープシーケンス**
「奈良県葛城市」の「葛」の文字は、多くの日本語入力変換機能では、入力できません（未対応）。その為、[文字情報基盤検索システムで検索した文字（MJ022335）](https://moji.or.jp/mojikibansearch/info?MJ%E6%96%87%E5%AD%97%E5%9B%B3%E5%BD%A2%E5%90%8D=MJ022335)の**コピーフィールドからコピーした文字をペーストして入力**します。
また、「葛」（MJ022335）の文字は、 **unicodeエスケープシーケンス** を使って `\u845B\uDB40\uDD02` と表されますので、ここでは、この文字列を文字情報として入力しています。試しに、`\u845B\uDB40\uDD02` の文字列を、 **コピーフィールドからコピーした文字に置換(ペースト)** しても、作成されるPDF帳票では、正しい字形が表示されます。
:::

## ひな形ファイルの作成

LibreOfficeの文書(Writer)で、ひな形ファイルを作成します。ひな形ファイルは、LibreOfficeの通常の文書ドキュメント(ODT形式ファイル)です。
py3oでは、フィールドのユーザー欄（変数）を使って、データが文書に差し込まれます。

:::note info
**ひな形ファイルの作成方法**

ひな形ファイルの作成方法等については、 [Templating with LibreOffice (英語/フランス語)](https://py3otemplate.readthedocs.io/en/latest/templating.html) にて文書化されています。

:::

### 文書ドキュメントの新規作成

LibreOfficeの文書(Writer)で、文書ドキュメントを新規作成し、固定の文言やレイアウト、罫線を編集します。

### フィールドのユーザー欄（変数）の定義

次の手順で、データ項目の `addr1` と `addr2` のフィールドを定義します。

1. LibreOffice Writer のメニューから `[挿入]` > `[フィールド]` > `[他のフィールド...]` を選択し、開いた **フィールド** のタブで `[変数]` を選びます。
1. `フィールドタイプ` で **ユーザー欄** を選択します。
1. `名前` 欄に **差込データへのアクセス式** を記述し、`値` 欄に **差込データの説明** を記述します。
1. `✓マーク` ボタンで、入力を確定します(`✕マーク` ボタンで削除)。
1. `[閉じる]` ボタンで **フィールド** を一旦閉じます。


**定義する内容**
|#|名前|値|
|--|----|----|
|1|py3o.addr1|addr1|
|2|py3o.addr2|addr2|

**フィールドの定義例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/dd50369f-d393-42fd-aed0-4e187c3c0ba5.png)

**フィールドの挿入**

次の手順で、データ項目の `addr1` と `addr2` の値を差し込みたい箇所に、定義したフィールドを挿入します。

1. 文書の挿入したい箇所に入力カーソルを合わせます。
1. LibreOffice Writer のメニューから `[挿入]` > `[フィールド]` > `[他のフィールド...]` を選択し、開いた **フィールド** のタブで `[変数]` を選びます。
1. `フィールドタイプ` で **ユーザー欄** を選択します。
1. `選択` 欄で挿入したい定義済みの名前を選択し、 `書式` 欄で **テキスト** を選択します。
1. `[挿入]` ボタンで選択している **ユーザー欄（変数）** をフィールドとして挿入します。
1. `[閉じる]` ボタンで **フィールド** を閉じます。

### フォントの指定

挿入したフィールドのフォントを `IPAmj明朝` フォントに指定します。通常、 **アジア諸言語** が **有効** になっていますので、  **アジア諸言語用フォント** も漏れなく指定します。

**フォントの指定例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/7497fc90-6888-b882-19d4-a580c26b432c.png)

:::note warn
**アジア諸言語用フォント**

LibreOfficeは、多言語に対応しており、 **アジア諸言語用フォント** を別に指定することが可能です。日本語の文字列をLibreOfficeがアジア諸国言語と判断して、 **アジア諸言語用フォント** で指定されたフォントを適用します。
日本語の文字列が期待するフォントで表示されない場合は、この **アジア諸言語用フォント** が正しく指定されていることを確認してください。

:::

### ひな形ファイルの保存

作成したひな形ファイルは、通常の文書ドキュメント(ODT形式ファイル)として、保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/31d6ac3e-8e84-98ed-91cd-782b58ae5319.png)

## PDF帳票の作成

[**Test form** ページ](http://localhost:8765/form) で、次のとおりに各項目に内容を入力し、 `Submit` ボタンをクリックすると、データが差し込まれたPDF形式ファイルがダウンロードされます。

**入力内容**
|項目|内容|備考|
|----|----|----|
|Target Format|pdf||
|Data dictionary|{"addr1":"東京都葛飾区","addr2":"奈良県\u845B\uDB40\uDD02城市"}||
|Image Mapping|{}|空の辞書|
|Image1|(なし)||
|Template|py3o_addr.odt|作成したひな形ファイル|

```json:Data dictionary
{"addr1":"東京都葛飾区","addr2":"奈良県\u845B\uDB40\uDD02城市"}
```

**PDF形式ファイルの表示と確認**

さくせいされたPDF形式ファイルを表示すると、「葛」の異体字が正しい字形で表現されていることを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/334a988a-d113-2930-1ed7-f0a193df1c79.png)

### 使用されているフォント

作成されたPDF形式ファイルをAcrobat Reader等のPDFビューワーで開き、そのプロパティを確認すると、使用されているフォントが埋め込まれていることを確認できます(**埋め込みサブセット**)。

そのため、 `IPAmj明朝` フォントがインストールされていないパソコンでPDF帳票を開いても、正しい字形で表示・印刷することが可能です。また、PDF帳票作成は、サーバー側で処理される為、 `IPAmj明朝` フォントがインストールされていないパソコンで、[**Test form** ページ](http://localhost:8765/form) からPDF帳票を作成しても、正しい字形で表示・印刷することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/602f9508-8827-8d86-2e8b-b05c3bbca2d0.png)

# 補足事項 - odoo連携

Odoo Apps Store に登録されている[次のodoo拡張モジュール](https://apps.odoo.com/apps/modules/16.0/report_py3o_fusion_server/)をodooにインストールすれば、odooからのPDF帳票作成サーバーとして連携することができます。

https://apps.odoo.com/apps/modules/16.0/report_py3o_fusion_server/

py3oのサンプル拡張モジュールである [Sample py3o sale reports (sale_report_py3o)](https://github.com/akretion/odoo-py3o-report-templates/tree/16.0/sale_report_py3o) を例にすると、 `sale_report_py3o/report.xml` でpy3oサーバーを参照するように編集します。

```xml:report.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="local_py3o_server" model="py3o.server">
    <!--
    <field name="url">http://localhost:8765/form</field>
    -->
    <field name="url">http://py3o:8765/form</field>
</record>

<record id="sale.action_report_saleorder" model="ir.actions.report">
    <field name="report_type">py3o</field>
    <!--
    <field name="py3o_filetype">odt</field>
    -->
    <field name="module">sale_report_py3o</field>
    <field name="py3o_template_fallback">sale_order.odt</field>
    
    <field name="py3o_server_id" ref="local_py3o_server"/>
    <field name="py3o_filetype">pdf</field>
    <field name="print_report_name">object.name + '-' + object.date_order.strftime('%Y-%m-%d') + '-' + object.commercial_partner_id.name.replace(' ', '_') + '.pdf'</field>
    
</record>


...

</odoo>
```

[Sample py3o sale reports (sale_report_py3o)](https://github.com/akretion/odoo-py3o-report-templates/tree/16.0/sale_report_py3o) をインストールするには、[次の記事の「Py3o帳票テンプレートのサンプル」の章](https://qiita.com/jp-96/items/2acd34f5783e12747b72#py3o%E5%B8%B3%E7%A5%A8%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB
)を参照してください。

**[「Py3o帳票テンプレートのサンプル」](https://qiita.com/jp-96/items/2acd34f5783e12747b72#py3o%E5%B8%B3%E7%A5%A8%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB
)**

https://qiita.com/jp-96/items/2acd34f5783e12747b72#py3o%E5%B8%B3%E7%A5%A8%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB

# おわりに

本記事では、PDF帳票作成サーバーpy3oを使って、異体字を含んだPDF帳票を作成しました。

- PDF帳票作成サーバー py3o をDockerで起動しました。
- IPAmj明朝フォント等がPDF帳票サーバーにインストールされていることを確認しました。
- Test formページで２つのサンプルPDF帳票を出力しました。
- IPAmj明朝フォントを使ったひな形ファイルを作成しました。
- 出力されたPDF帳票の異体字が正しい字形で表現されることを確認しました。
- PDF帳票にIPAmj明朝フォントが埋め込みサブセットとして使用されていることを確認しました。

**PDF帳票作成サーバーpy3o** と **IPAmj明朝フォント** を活用すれば、文字情報基盤で同定された約6万文字において、 **外字が不要** です。