LibreOffice UNO APIは非常に高機能ですが、Javaから利用するにはインターフェースが多く、帳票処理のコードが複雑になりがちです。
lojはUNO APIを解析してJavaラッパーを自動生成し、さらに高水準APIを提供することで、帳票開発をシンプルに記述できるようにしたライブラリ群です。
Spring Bootによるサンプルアプリケーションを loj-sb-sample に用意しています。
lojリポジトリは、主に次の3つで構成されています。
- loj-proxy
- loj-util
- loj-sb-sample(高水準APIサンプル)
特徴
-
UNOラッパーの自動生成
UNOインターフェースをJava Reflectionで解析し、P_Doc、P_Sheet、P_Cell、P_Range などのラッパークラスを自動生成します(loj-proxy)。LibreOfficeのバージョンを更新したときも、再生成で追従できます。
P_*クラスのgetProxy()で素のUNO Objectを取り出せるので、ラッパーを通さない操作も可能です。 -
手書きの高水準API
Doc、Sheet、Cell、Range といった高水準APIにより、セルや範囲の取得、値の設定、書式設定、シートのコピー・インポート、チャート操作などを、普通のJavaコードに近い感覚で記述できます。 -
サーバーサイド向けの接続管理
LibreOfficeプロセスの起動・接続・再利用(接続プール)、Javaのストリームとの変換、一時ユーザーディレクトリによるプロファイル競合の回避など、Spring Bootなどのサーバーアプリから使うための仕組みを備えています(loj-util)。 -
帳票生成からPDF出力・直接印刷まで
LibreOffice Calcで作成したODSを帳票の原本として使い、Javaから値や書式を設定して、PDF出力やプリンターへの直接印刷まで行えます。
loj-proxyと高水準API
Calc操作の層は、次のような構造になっています。
Java / Spring Bootアプリケーション
↓
Doc / Sheet / Range / Cell
↓
自動生成された P_* クラス
↓
LibreOffice UNO API
↓
LibreOffice
特に独自性があるのが loj-proxy です。proxy.properties に指定されたUNOインターフェースをJava Reflectionで解析し、
UNOインターフェース
↓
loj-proxy
↓
P_Doc.java
P_Sheet.java
P_Cell.java
P_Range.java
...
のようにラッパーソースを生成します。
NOA-libreとの違い
LibreOfficeのUNO APIをJavaから扱いやすくするライブラリとして、NOA-libreもあります。
NOA-libreはLibreOfficeをJavaから扱うための汎用的なラッパーライブラリで、WriterやCalcの操作、JavaアプリケーションへのLibreOfficeの埋め込みなど、幅広い用途を対象としています。
lojもUNO APIを扱いやすくするという目的は共通していますが、アプローチが異なります。
NOA-libreでは手書きの高水準APIが用意されています。カバーされていない機能が必要になった場合、下層のUNO APIへアクセスします。
lojでは、UNOインターフェースをJava Reflectionで解析し、P_Doc、P_Sheet、P_Cell、P_Range などのラッパークラスを自動生成します。
NOA-libre
Javaアプリケーション
↓
NOA-libre API
↓
LibreOffice UNO API
↓
LibreOffice
lojでは次のようになります。
loj
Java / Spring Bootアプリケーション
↓
Doc / Sheet / Range / Cell
↓
自動生成された P_* クラス
↓
LibreOffice UNO API
↓
LibreOffice
つまりlojでは、膨大なUNO APIに対応するラッパーをすべて手作業で実装するのではなく、機械的に生成できる部分をloj-proxyで自動生成し、その上に帳票開発で使いやすい高水準APIを手書きする、という方針を採っています。
また、Doc、Sheet、Cell、Rangeなどの高水準APIはloj-sb-sampleのloj.myパッケージにサンプルとして含めています。利用者がコピーし、それぞれの帳票システムに必要な操作を追加して育てていくことを想定しています。
さらにlojは、LibreOfficeをJavaのサーバーサイド帳票エンジンとして利用することを主な用途の一つとしており、loj-utilにはLibreOfficeプロセスへの接続、接続プール、Java Streamとの変換、一時ユーザーディレクトリなどの仕組みがあります。
そのため、両者の方向性を簡単に表すと、
NOA-libre
LibreOfficeをJavaから扱うための汎用ラッパー
loj
UNOラッパーを自動生成し、
その上に用途別の高水準APIを構築する仕組み
+
JavaサーバーでLibreOfficeを
帳票エンジンとして利用するための基盤
という違いがあります。
NOA-libreとlojは「UNO APIをJavaから扱いやすくする」という目的では似ていますが、lojでは特にUNOラッパーの自動生成、利用者が育てられる高水準API、サーバーサイド帳票処理を重視しています。
| 項目 | NOA-libre | loj |
|---|---|---|
| ラッパー実装 | 手書き | 自動生成 |
| UNO直接アクセス | 可 | 可(getProxy) |
| 高水準API | 内蔵 | 利用者が拡張 |
| 主用途 | 汎用操作 | 帳票基盤 |
| サーバー運用機能 | 限定的 | 接続プール等あり |
loj-util
loj-util は LibreOfficeプロセスの起動・接続・入出力・再利用を担当します。
主な機能は次のとおりです。
- LibreOfficeへの接続
SocketConnector、PipeConnector などにより、SocketまたはNamed Pipe経由でLibreOfficeのUNO環境へ接続します。接続処理の共通部分は ConnectorBase にまとめられています。 - LibreOfficeプロセスの管理
LoServer などにより、Javaプログラムから利用するLibreOfficeプロセスを扱います。GUIアプリとしてではなく、文書処理エンジンとしてLibreOfficeを利用することを想定した構成です。 - 接続プール
PoolManager、ConnectorFactory などがあり、LibreOfficeへの接続を毎回作り直すのではなく再利用できます。Spring Bootなどのサーバーアプリケーションから継続的に文書処理を行う用途を意識した機能です。 - Java StreamとUNO Streamの変換
LoInputStream、LoOutputStream、LoStreamConverter により、Javaの InputStream / OutputStream とLibreOffice UNOのストリームを橋渡しします。これによってファイルだけでなく、メモリ上のデータをLibreOfficeへ渡したり、PDF等への変換結果をJavaの OutputStream で受け取ったりできます。 - 一時ユーザーディレクトリ
TempUserDirConnector、TempUserDirServer により、一時的なLibreOfficeユーザープロファイルを使用する仕組みがあります。複数プロセスやサーバー環境でLibreOfficeを動かす際に、ユーザープロファイルの競合を避けるために有用です。
したがってloj全体を役割で分けると
loj-util
LibreOfficeを起動・接続・管理する
↓
LibreOffice
↑
loj-proxy
UNO APIのJavaラッパーを生成する
↑
Doc / Sheet / Range / Cell
人間が使いやすい高水準API
↑
アプリケーション
という関係です。
loj-sb-sampleのloj.myパッケージ
loj.myパッケージは、P_*クラスの上に作った手書きの高水準ライブラリです。
loj-sb-sampleに含めているのは、利用者がコピーして用途に合わせて拡張して使うことを想定しているためです。必要な操作を追加して、それぞれの帳票システムに合わせて育てていくことができます。
右へ進みながら値を設定する場合は、次のように書けます。
Cell c = sheet.getCell("A1");
c.set("JAN")
.right().set("FEB")
.right().set("MAR");
loj-sb-sampleで生成される帳票
| URL | 内容 |
|---|---|
/ |
original.odsから原本をコピーし、さらにシートを複製して値を設定する |
/pdf |
/と同じ帳票をPDFで返す |
/chart |
Calc上にグラフを生成 |
/print |
帳票を生成し、サーバーのデフォルトプリンターへ直接印刷 |
このように、LibreOffice Calcで作成したODSファイルを帳票の原本として利用し、Javaから必要な値や書式を設定して、PDF出力やプリンターへの直接印刷まで行えます。
と
を書きました。