PDFに関する背景
今までの案件で2種類のPDF機能をよく利用してきました。一つは、WEB画面をPDFに変換する機能。もう一つは、PDFテンプレートのフォーム項目を穴埋めする機能。いままではwkhtmltopdfとpdf-libを利用して実現していました。
wkhtmltopdfはhtml5とjavaScriptをサポートして一般ブラウザー機能をほぼ全部実現しています。ただし、cssとjavaScriptの進化に追いつかない状態で、2023年からarchivedされました。また、javaと連携する際コマンドラインで行うので、スピード的によろしくないです。
pdf-libはjavaScriptのライブラリで、ブラウザー利用はオフィシャル的です。V8エンジンのラッパー機能のjavetと連携して、Efwフレームワークに穴埋めPDF機能を実現しました。ただし、javetはマルチスレッドではないので、ウェブサーバで大量アクセスした時はメモリリークに要注意です。また、V8内でエラーが発生したら、上位側のjavaプログラムはそれをキャッチできず、いきなりTomcatがダウンしてしまう問題を発見しました。
これなら、純粋なjavaのPDFライブラリが欲しくなります。探してみたところ、OpenPDFという使いやすいフリーライブラリを発見しました。PdfクラスとしてEfwに取り込みました。
環境
OpenPDFの2.2.4は、JDK21以上が必要です。必要なライブラリは以下です。
<!-- https://mvnrepository.com/artifact/com.github.librepdf/openpdf -->
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
<version>2.2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.librepdf/openpdf-fonts-extra -->
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf-fonts-extra</artifactId>
<version>2.2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.librepdf/openpdf-html -->
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf-html</artifactId>
<version>2.2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.librepdf/openpdf-renderer -->
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf-renderer</artifactId>
<version>2.2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.17</version>
<scope>test</scope>
</dependency>
Efwはこちらを利用してください。
<!-- https://mvnrepository.com/artifact/io.github.efwgrp/efw -->
<dependency>
<groupId>io.github.efwgrp</groupId>
<artifactId>efw</artifactId>
<version>5.00.000</version>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<version>24.2.2</version>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js</artifactId>
<version>24.2.2</version>
<type>pom</type>
</dependency>
穴埋め機能
テンプレートを準備する
Adobe Acrobatを利用して、PDFテンプレートを作成します。
チェックボックスの場合バリュー値で設定するので、取り扱いが便利なバリュー値を設定します。ラジオボタンとドロップダウンも同じく分かり易いバリュー値を設定します。
フォントを特定する
PDFのフォントの話は深いので、今回はwindowsで取り扱い便利なMSゴシックを利用してテストします。
テストプログラム
var helloPdf_fillFeild={};
helloPdf_fillFeild.paramsFormat={
};
helloPdf_fillFeild.fire=function(params){
var pdf=new Pdf("pdf_field_test.pdf");
pdf.setField("text_field","あい1212森森");
pdf.setField("text_field_multi","あいうえおあいうえおあいうえおあいうえおあいうえおあいうえお");
pdf.setField("check_box","1");
pdf.setField("radio_group","2");
pdf.setField("dropdown_list","2");
pdf.setField("date_field","2025/01/02");
pdf.save("ccccc.pdf");
return new Result().preview("ccccc.pdf");
}
結果
html変換機能
フォントを確保する
windows/Fontsフォルダからmsgothic.ttcをコピーして、プロジェクトのstorage/fontsフォルダにコピーします。
警告
msgothic.ttcなどのwindowフォントファイルはlinux環境にコピーして使うとライセンス違反です。別途サーバライセンスを購入する必要です。詳細は以下のリンクをご参考ください。
https://industry.ricoh.com/font/server
プログラム
var helloPdf_html2pdf={};
helloPdf_html2pdf.paramsFormat={};
helloPdf_html2pdf.fire=function(params){
Pdf.getFontNames("fonts").debug("****fonts****");
var vl1="あいうえお";
var vl2="森森森森森";
Pdf.html2pdf(
`
<html>
<head>
<link type="text/css" rel="stylesheet" href="./jquery-ui/jquery-ui.structure.min.css?v=4.08.000" />
<link type="text/css" rel="stylesheet" href="./jquery-ui/themes/base/theme.css?v=4.08.000" />
<link type="text/css" rel="stylesheet" href="./efw/efw.css?v=4.08.000" />
<style>
@page {
size: A4 landscape;
}
*{
font-family:MS Gothic;
}
</style>
</head>
<body>
<input type="text" value="${vl1}" style="width:200px;height:40px;" class="efw_input_error"/>
<input type="text" value="${vl2}" style="width:200px;height:40px;"/>
<table border="1" style="width:100%">
<tr style="background-color:yellow"><th>あいうえお</th><th>あいうえお</th></tr>
<tr><td>あいうえお</td><td>あいうえお</td></tr>
</table>
<img src="a.jpg" width="10%" style="position:absolute;top:60px;left:700px;" />
</body>
</html>
`,
"http://localhost:8080/helloworld/","hhhhh.pdf","fonts");
return new Result().preview("hhhhh.pdf");
}
効果
- 外付けのcssファイルを利用できる
- テキストの入力枠を利用できる
- Boldを利用できる
- 画像を表示できる
- 絶対位置などのcss特徴を利用できる
などなどの長所が見えますが、javaScriptを利用できない短所をよく覚えてください。