* Groovyスクリプトレットを使用した.Docxテンプレート

画像

私のプロジェクトの1つで、クライアント用の契約文書を自動的に生成する必要がありました。 契約は約10ページの長さの法的文書であり、テンプレートです。特定のクライアントのデータが適切な場所で置き換えられます。

挑戦する


主な要件は次のとおりです。
複雑な様式化されたdocまたはdocxドキュメントで、マークされた場所に必要な情報を表示します。

それらはさらに洗練され拡張されました。


既存のソリューション


フィールドで利用可能な製品(私はJavaプラットフォームについて話している)がタスクを解決しないことが判明しました。 製品の概要は次のとおりです。

ジャスパーレポート

テンプレートとして、xmlマークアップファイル* .jrxmlを使用します。 ドキュメントマークアップファイル+データ(データベースおよびマップパラメーターの両方)がプロセッサーに渡され、PDF、XML、HTML、CSV、XLS、RTF、TXTのいずれかの形式が生成されます。
合わなかった:

Docx4java

Java-APIを使用してdocx-、pptx-、xlsx-documentsのコンポーネントを操作するためのツール。
合わなかった:

Apache POI

Java APIを使用して、doc-、ppt-、xls-documentsのコンポーネントを操作するためのツール。 これらの形式のドキュメントからデータを取得するために最初に作成されました。
合わなかった:


問題解決


面白かったです:)

1.ドキュメントコンテンツはxmlとして保存され、zipアーカイブに圧縮されます。 従来のJDK 6のジッパーは明示的なエンコード(明らかにファイル名)をサポートしていないため、解凍は困難です。 アーカイブの際に、docxが無効になりました。 コンテンツをパックするときに、対応するパラメーターでGroovy AntBuilderラッパークラスを使用する必要がありました。

2. MS Wordに入力されたテキストは、プログラムによって断片に分割され、xmlタグの異なるグループに配置されるため、生成されたxmlガスケットからテンプレートを削除する問題を最初に解決する必要がありました。 このタスクでは、正規表現を使用しましたが、SAXパーサーよりも高速に見えました(ただし、パフォーマンスは測定しませんでした)。

3. Groovyをスクリプト言語として使用することにしましたその理由は、その単純さ、Javaの性質、およびコアに含まれるテンプレートプロセッサです 。 彼には興味深い困難もありました。 10枚の小さなドキュメントであっても、2つのスクリプトレット間の行の長さの制限に簡単に到達できることが判明しました。 スクリプトレットの間にあるすべてのテキストをUUID文字列で置き換え、Groovyテンプレートプロセッサを実行し、最後にのみUUID文字列を元のXMLピースで置き換えなければなりませんでした。

これらの困難を克服して、私は実際にプロジェクトを試しました。 うまくいきました!

英語のプロジェクトサイトを作成して公開しました。
プロジェクトの住所: snowindy.github.com/scriptlet4docx

APIの使用例

 HashMap<String, Object> params = new HashMap<String, Object>(); params.put("name", "John"); params.put("sirname", "Smith"); DocxTemplater docxTemplater = new DocxTemplater(new File("path_to_docx_template/template.docx")); docxTemplater.process(new File("path_to_result_docx/result.docx"), params); 


プロジェクトのWebサイトにアクセスすると、ここで終了できます...
しかし、理解を深めるために、「スクリプトレットのタイプの説明」の最も興味深いセクションを翻訳します。

スクリプトレットの種類、詳細


免責事項: テンプレートを使用する場合、GroovyテンプレートプロセッサはすべてのスクリプトレットをGroovyコードに変換し、スクリプトレット間のテキストは次のように表示されますout.print('template_text')

$ {データ}

データをoutにout.print(data)同等: out.print(data)

<%=データ%>

データをoutにout.print(data)同等: out.print(data)

<%any_code%>

スクリプトレット内でコードを実行しても何も表示されません。 条件付き出力に使用できます:
 <% if (cond) { %>    ,  "cond == true" <% } else { %>    ,  "cond != true" <% } %> 


$ [@ listVar.field]

これは最も興味深い種類のスクリプトレットです! docxドキュメント内のテーブルにオブジェクトのリストを表示するために使用されます。 テーブルセル内で使用する必要があります。
たとえば、Personオブジェクトのリストがあります。 オブジェクトには、「名前」と「アドレス」の2つのフィールドがあります。 2列のテーブルにリストを表示します。

  1. 入力値マップで「personList」パラメーターを作成すると、オブジェクトのリストが参照されます。
  2. docxドキュメントに2つの列と1つの行を持つテーブルを作成します。
  3. $[@person.name]は最初のセルに入力する必要があります。 $[@person.address]番目。
  4. すべての準備ができたら、personListリストがテーブルに印刷されます。


ライブテンプレートの例

ここにあります: link

プロジェクト開発


docxテンプレートの処理に対する新しいアプローチを実際に考案した場合、それを普及させたいと思います。
このプロジェクトには次のような努力が必要です。


英語圏の聴衆にプロジェクトを配布する際のアドバイスをうれしく思います!

Source: https://habr.com/ru/post/J142350/


All Articles