1. Introduction
(*) Fugerit Doc Format is the core of the Venus Doc Framework and comes into a few flavours :
Copyright
@2024 Matteo Franci - CC BY 4.0 - ATTRIBUTION 4.0 INTERNATIONAL - https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en
All trademarks, logos and brand names are the property of their respective owners. All company, product and service names used in this website are for identification purposes only. Use of these names,trademarks and brands does not imply endorsement.
1.1. What is Fugerit Venus Doc?
Fugerit Venus Doc is a document generation framework, largely based on Apache FreeMarker template engine and on a custom document format (available in XML (default), JSON, YAML and Kotlin).
The source format can be rendered to different output formats through Doc Handlers. (the actual rendering often depends on other open source libraries like Apache FOP or OpenCSV).
Here is a diagram showing the usage of the framework on a typical scenario.
-
Using XML as document source format
-
Picking two output format (HTML and MarkDown)
For who is familiar with Apache FreeMarker this is basically an evolution of its approach :
This diagram is a reproduction of the one in What is Apache FreeMarker? page. |
1.2. Release Notes
Whereas the CHANGELOG is a detailed list of modification to project, the release notes just refers to most important changes.
1.2.1. Version 8.11.2 [2024-11-21]
-
New FreeMarker function formatDateTime.
1.2.2. Version 8.11.1 [2024-11-19]
-
Fixed ImageValidator exception handling #262
1.2.4. Version 8.10.9 [2024-11-03]
-
[fj-doc-maven-plugin] fix version check for AsciiDoc example
-
Native support minor fixes
1.2.5. Version 8.10.8 [2024-11-02]
-
Native metadata for module fj-doc-mode-opencsv (and relevant tests)
1.2.6. Version 8.10.7 [2024-11-02]
-
Native metadata for fj-doc-base and fj-doc-freemarker are sorted in a stable way.
-
Added test of native modules against built executable.
1.2.7. Version 8.10.6 [2024-11-01]
-
Added new quarkus project and workflow to test native modules fj-doc-native-quarkus.
1.2.8. Version 8.10.5 [2024-11-01]
-
Native support for module fj-doc-base.
-
Native support for module fj-doc-freemarker.
1.3. GraalVM Ahead Of Time (AOT) Support
The full GraalVM support is currently under development.
Doc handlers with native support are marked as native ready.
Currently native ready modules can be found here.
There is a test project fj-doc-native-quarkus
and a GitHub workflow.
Additional here is a simple project created with fj-doc-maven-plugin:init : https://github.com/fugerit-org/fj-doc-quarkus-tutorial/tree/branch-native-latest
Most metadata have been generated from configuration using native-helper-maven-plugin. |
2. Quickstart
This section cover the creation of a new maven project, configured for Venus Doc.
2.1. New maven project
Just run the org.fugerit.java:fj-doc-maven-plugin:init plugin :
mvn org.fugerit.java:fj-doc-maven-plugin:init \
-DgroupId=org.example.doc \
-DartifactId=fugerit-demo \
-Dflavour=quarkus-3 \
-Dextensions=base,freemarker,mod-fop
And you will get a project folder named after the artifactId.
See the README.md in the project folder for further infos.
In case of 'quarkus-3' flavour, for instance, simply :
cd fugerit-demo
mvn quarkus:dev
Open the Open swagger UI to test available services.
See the Maven Plugin Goal init for further options. |
2.2. Existing maven project
Just run the org.fugerit.java:fj-doc-maven-plugin:add plugin inside the folder containing your pom :
mvn org.fugerit.java:fj-doc-maven-plugin:add \
-Dextensions=base,freemarker,mod-fop
Dependencies, project configuration and an example main will be added to the project.
See the Maven Plugin Goal Add for further options. |
3. Maven Plugin
Here is the Fugerit Doc Maven Plugin Documentation.
Currently, three goals are available :
goal | since | description |
---|---|---|
add |
8.6.0 |
add Venus Doc Configuration to an existing project. |
init |
8.7.2 |
create a new project already configured (actually an extension to 'add' goal); a UI is available on the playground too. |
verify |
8.7.0 |
verify the templates in a FreeMarker configuration (folder), note: it can be used on any Apache FreeMarker configuration, not only Fugerit Venus Doc. |
3.1. Goal 'add'
This goal add Fugerit Venus Doc configuration to an existing maven project.
Simply run the plugin in the folder containing your project POM :
mvn org.fugerit.java:fj-doc-maven-plugin:add \
-Dextensions=base,freemarker,mod-fop
3.1.1. Goal 'add' available parameters
parameter | required | default | description |
---|---|---|---|
version |
true |
latest stable |
fj-doc version to add to the project (i.e. '8.7.5'), advice: keep the default unless a specific version is strictly needed. |
extensions |
true |
base,freemarker |
List of fj-doc core modules to add (*) |
projectFolder |
true |
. |
Maven project base folder |
addDocFacade |
true |
true |
If true, a stub doc configuration helper will be created |
force |
false |
false |
Will force project setup even if fj-doc already configured (warning: can overwrite configuration) |
excludeXmlApis |
false |
false |
It will exclude dependency xml-apis:xml-apis |
addExclusions |
false |
Add comma separated exclusion, for instance : xml-apis:xml-apis,${groupId}:${artificatId} |
|
addVerifyPlugin |
true |
true |
If set to true, it will configure the 'verify' goal on the project |
addJunit5 |
true |
true |
If set to true, it will add junit5 (test scope) and basic test |
addLombok |
true |
true |
If set to true, it will add lombok (provided scope) and slf4j-simple (test scope) |
addDependencyOnTop |
true |
false |
If set to true, added dependencies will be added before existing ones |
freemarkerVersion |
true |
2.3.32 |
Freemarker compatibility version (max 2.3.33) |
3.1.2. Available extensions.
short name | full name | type handler | description | notes |
---|---|---|---|---|
base |
fj-doc-base |
md |
library base, xml as format for document template |
native ready (1) |
base-json |
fj-doc-base-json |
add support to use json documents as format for document template |
||
base-yaml |
fj-doc-base-yaml |
add support to use yaml documents as format for document template |
||
base-kotlin |
fj-doc-base-kotlin |
add support to use Kotlin DSL script (KTS) as format for document template |
||
freemarker |
fj-doc-freemarker |
html |
Template and configuration functionalities based on [Apache FreeMarker](https://freemarker.apache.org/) |
native ready (1) |
mod-fop |
fj-doc-mod-fop |
fo, pdf |
Type handler based on [Apache FOP](https://xmlgraphics.apache.org/fop/) |
|
mod-poi |
fj-doc-mod-poi |
xls, xlsx |
Type handler based on [Apache POI](https://poi.apache.org/) |
|
mod-opencsv |
fj-doc-mod-opencsv |
csv |
Type handler based on [OpenCSV](https://opencsv.sourceforge.net/) |
native ready (1) |
mod-openpdf-ext |
fj-doc-mod-openpdf-ext |
Type handler based on [OpenPDF](https://github.com/LibrePDF/OpenPDF) |
||
mod-openrtf-ext |
fj-doc-mod-openrtf-ext |
rtf |
Type handler based on [OpenRTF](https://github.com/LibrePDF/OpenRTF) |
(1) Native Ready means that the GraalVM metadata are included in the release. |
3.2. Goal 'init'
Create a new project and add Venus Doc Configuration to it.
mvn org.fugerit.java:fj-doc-maven-plugin:init \
-DgroupId=org.example.doc \
-DartifactId=fugerit-demo \
-Dextensions=base,freemarker,mod-fop
Project folder will be ./${artifactId}/
.
3.2.1. Goal 'init' available parameters
parameter | required | default | description |
---|---|---|---|
groupId |
true |
new project group id |
|
artifactId |
true |
new project artifact id |
|
projectVersion |
true |
1.0.0-SNAPSHOT |
new project version |
javaRelease |
true |
21 |
java release version |
flavour |
true |
vanilla |
the flavour for the new project (see below for options) |
flavourVersion |
false |
see below |
override default framework version if supported (recommended : leave default or blank) |
it is possible to set any property from 'add' goal, except 'projectFolder' which is set to ./${artifactId} .
|
3.3. Goal 'verify'
verify the templates in a FreeMarker configuration (folder), note: it can be used on any Apache FreeMarker configuration, not only Fugerit Venus Doc.
3.3.1. Verify at command line
mvn org.fugerit.java:fj-doc-maven-plugin:verify -DtemplateBasePath=./src/test/resources/fj_doc_test/template-fail
3.3.2. Verify at maven build time
<plugin>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-maven-plugin</artifactId>
<version>${fj-doc-version}</version>
<executions>
<execution>
<id>freemarker-verify</id>
<phase>compile</phase>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- Where the FreeMarker templates are located -->
<templateBasePath>${project.basedir}/src/main/resources/fugerit-blank/template</templateBasePath>
<!-- WARNING: if set to 'true', build will fail when at least one syntax error is found -->
<failOnErrors>true</failOnErrors>
<!-- If 'true' a report will be generated (when 'true', param reportOutputFolder is required) -->
<generateReport>true</generateReport>
<!-- Template syntax verify report output folder -->
<reportOutputFolder>${project.build.directory}/freemarker-syntax-verify-report</reportOutputFolder>
</configuration>
</plugin>
3.3.3. Goal 'verify' available parameters
parameter | required | default | description |
---|---|---|---|
templateBasePath |
true |
Path to base folder containing FreeMarker templates |
|
freemarkerVersion |
false |
latest stable |
FreeMarker configuration ( i.e. 2.3.33) |
templateFilePattern |
false |
Filter on templates to be checked, regex on filename, i.e. ".{0,}[.]ftl" |
|
failOnErrors |
true |
true |
If set to true the build will fail when template syntax errors will be found, otherwise errors will be only logged |
generateReport |
false |
false |
If set to true a report will be generated (and property 'reportOutputFolder' will be olso required). |
reportOutputFolder |
false |
Output folder for the generated report. |
|
reportOutputFormat |
false |
'html' |
Output format for the generated report, supported : html (default), pdf, csv, xlsx, md. |
4. The Doc Source Format
The Doc Source Format is the basic of Fugerit Venus Doc library.
4.1. XML Source Format
When writing a sample Venus Document, it is possible to draw from some online resources :
-
Venus DOC XML Schema Definition - Current version of the Venus DOC XSD, the main source for writing valid Venus document meta model.
-
Venus DOC XML Reference - the informations contained in the previous XSD in HTML format for convenience.
-
Venus DOC meta informations reference - documentations for existing 'info' properties for 'metadata' section.
-
Online Playground - To test how the XML elements are rendered to documents by DocHandlers.
Supported is provided by the base module dependency :
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-base</artifactId>
<version>${fj-doc-version}</version>
</dependency>
Here is an example xml :
<?xml version="1.0" encoding="utf-8"?>
<doc
xmlns="http://javacoredoc.fugerit.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://javacoredoc.fugerit.org https://www.fugerit.org/data/java/doc/xsd/doc-2-1.xsd" >
<!--
This is a Venus Fugerit Doc (https://github.com/fugerit-org/fj-doc) XML Source Document.
For documentation on how to write a valid Venus Doc XML Meta Model refer to :
https://venusdocs.fugerit.org/guide/#doc-format-entry-point
-->
<metadata>
<!-- Margin for document : left;right;top;bottom -->
<info name="margins">10;10;10;30</info>
<!-- documenta meta information -->
<info name="doc-title">Hello World</info>
<info name="doc-author">fugerit79</info>
<info name="doc-language">en</info>
</metadata>
<body>
<para>Hello World!</para>
</body>
</doc>
4.2. JSON and YAML Source Format
It is possible to use JSON or YAML as source. It is just needed to follow some conversion rules.
The conversion rules from xml to json/yaml are :
-
xml meta information are translated as top level property (xmlns etc.)
-
Every JSON/YAML object contains the information of a XML tag
-
"_t" special property contains the tag name (for example "_t" : "metadata")
-
"_v" special property contains the text content of an element
-
"_e" special property contains a list of child elements
-
any other xml attribute is mapped as a JSON/YAML property (for example "name" : "margins")
As it is possible to directly convert JSON and YAML, rules for YAML are the same as for JSON format. |
All XML comments are ignored |
For XML/JSON/YAML conversion a Online Playground is available. |
Support for JSON format needs the following dependency :
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-base-json</artifactId>
<version>${fj-doc-version}</version>
</dependency>
Here is a simple JSON source document :
{
"xmlns" : "http://javacoredoc.fugerit.org",
"xsi:schemaLocation" : "http://javacoredoc.fugerit.org https://www.fugerit.org/data/java/doc/xsd/doc-2-0.xsd",
"xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance",
"_t" : "doc",
"_e" : [ {
"_t" : "metadata",
"_e" : [ {
"name" : "margins",
"_t" : "info",
"_v" : "10;10;10;30"
}, {
"name" : "doc-title",
"_t" : "info",
"_v" : "Hello World"
}, {
"name" : "doc-author",
"_t" : "info",
"_v" : "fugerit79"
}, {
"name" : "doc-language",
"_t" : "info",
"_v" : "en"
} ]
}, {
"_t" : "body",
"_e" : [ {
"_t" : "para",
"_v" : "Hello World!"
} ]
} ]
}
Support for YAML format needs the following dependency :
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-base-yaml</artifactId>
<version>${fj-doc-version}</version>
</dependency>
Here is the equivalent YAML :
---
xmlns: "http://javacoredoc.fugerit.org"
xsi:schemaLocation: "http://javacoredoc.fugerit.org https://www.fugerit.org/data/java/doc/xsd/doc-2-1.xsd"
xmlns:xsi: "http://www.w3.org/2001/XMLSchema-instance"
_t: "doc"
_e:
- _t: "metadata"
_e:
- name: "margins"
_t: "info"
_v: "10;10;10;30"
- name: "doc-title"
_t: "info"
_v: "Basic example"
- name: "doc-subject"
_t: "info"
_v: "fj doc venus sample source xml"
- name: "doc-author"
_t: "info"
_v: "fugerit79"
- name: "doc-language"
_t: "info"
_v: "en"
- name: "default-font-name"
_t: "info"
_v: "TitilliumWeb"
- name: "excel-table-id"
_t: "info"
_v: "data-table=print"
- name: "csv-table-id"
_t: "info"
_v: "data-table"
- _t: "footer-ext"
_e:
- align: "right"
_t: "para"
_v: "${currentPage} / ${pageCount}"
- _t: "body"
_e:
- _t: "para"
_v: "My sample title"
- padding: "2"
columns: "3"
width: "100"
id: "data-table"
colwidths: "30;30;40"
_t: "table"
_e:
- _t: "row"
_e:
- border-color: "#000000"
border-width: "1"
align: "center"
_t: "cell"
_e:
- style: "bold"
_t: "para"
_v: "Name"
- align: "center"
_t: "cell"
_e:
- style: "bold"
_t: "para"
_v: "Surname"
- align: "center"
_t: "cell"
_e:
- style: "bold"
_t: "para"
_v: "Title"
- _t: "row"
_e:
- _t: "cell"
_e:
- _t: "para"
_v: "Luthien"
- _t: "cell"
_e:
- _t: "para"
_v: "Tinuviel"
- _t: "cell"
_e:
- _t: "para"
_v: "Queen"
- _t: "row"
_e:
- _t: "cell"
_e:
- _t: "para"
_v: "Thorin"
- _t: "cell"
_e:
- _t: "para"
_v: "Oakshield"
- _t: "cell"
_e:
- _t: "para"
_v: "King"
4.3. Kotlin Source Format (Experimental)
Supported is provided by the base module dependency.
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-base-kotlin</artifactId>
<version>${fj-doc-version}</version>
</dependency>
At the moment kotlin (KTS) support is still experimental. |
When adding this extension, all the kotlin runtime must be included too. |
Kotlin source is based on a custom DSL (Domain Specific Language).
The Fugerit Doc Kotlin DSL is basically a mapping of the xsd.
Here is a sample kotlin source document :
import org.fugerit.java.doc.base.kotlin.dsl.dslDoc
dslDoc {
val docTitle = attStr( data, "docTitle" )
meta {
info( ( docTitle ) ).name( "doc-title" )
info( ( "10;10;10;30" ) ).name( "margins" )
info( ( "fj doc venus sample source Kotlin Template - kts" ) ).name( "doc-subject" )
info( ( "fugerit79" ) ).name( "dock-author" )
info( ( "en" ) ).name( "doc-language" )
info( ( "TitilliumWeb" ) ).name( "default-font-name" )
info( ( "data-table=print" ) ).name( "excel-table-id" )
info( ( "data-table" ) ).name( "csv-table-id" )
footerExt {
para( '$'+"{currentPage} / "+'$'+"{pageCount}" ).align( "right" )
}
}
body {
h( docTitle ).headLevel( 1 )
table {
row {
cell { para( "Name" ) }.align( "center" )
cell { para( "Surname" ) }.align( "center" )
cell { para( "Title" ) }.align( "center" )
}.header( true )
attListMap( data, "listPeople" ).forEach( { e -> row {
cell { para( attStr( e, "name" ) ) }
cell { para( attStr( e, "surname" ) ) }
cell { para( attStr( e, "title" ) ) }
} } )
}.columns( 3 ).colwidths( "30;30;40" ).width( 100 ).id( "data-table" ).padding( 2 )
}
}
4.3.1. DocKotlinParser
The DocKotlinParser provides a utility to eval the kotlin script with data model :
try ( Reader ktsReader = ... ) {
Map<String,Object> dataModel = ...
String xml = DocKotlinParser.dslDocToXml( ktsReader, dataModel );
}
And when using DocFacadeSource it is available with the source type SOURCE_TYPE_KOTLIN (value:9).
4.3.2. FreeMarkerKotlinStep
A new FreeMarkerKotlinStep is also available inside the FreemarkerDocProcessConfig
4.4. Doc Format Info Element
The info element is available to setup some specific properties of the document.
Here is a list of possible info element.
For instance in this document we set following info elements :
-
margin
-
doc-title
-
doc-author
-
doc-language
Some DocHandler will ignore some info elements.
<?xml version="1.0" encoding="utf-8"?>
<doc
xmlns="http://javacoredoc.fugerit.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://javacoredoc.fugerit.org https://www.fugerit.org/data/java/doc/xsd/doc-2-1.xsd" >
<metadata>
<!-- Margin for document : left;right;top;bottom -->
<info name="margins">10;10;10;30</info>
<!-- documenta meta information -->
<info name="doc-title">Hello World</info>
<info name="doc-author">fugerit79</info>
<info name="doc-language">en</info>
</metadata>
<body>
<para>Hello World!</para>
</body>
</doc>
5. Dynamic Data : Freemarker
In a typical workflow, freemarker will be used to generate the Venus Doc Format.
This is a simple tutorial for Fugerit Venus Doc full usage.
This tutorial is based on a quarkus project available at :
tutorial repository git.
The project has been created with the command :
mvn org.fugerit.java:fj-doc-maven-plugin:init \
-DgroupId=org.fugerit.java-tutorial \
-DartifactId=fj-doc-quarkus-tutorial \
-Dflavour=quarkus-3 \
-Dextensions=base,freemarker,mod-fop,mod-poi
5.1. FreemarkerDocProcessConfig configuration
The main configuration file is fm-doc-process-config.xml.
Here you can find :
5.1.1. Root element freemarker-doc-process-config
This is the root configuration element :
<freemarker-doc-process-config
xmlns="https://freemarkerdocprocess.fugerit.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://freemarkerdocprocess.fugerit.org https://www.fugerit.org/data/java/doc/xsd/freemarker-doc-process-1-0.xsd"
validating="true"
failOnValidate="true"
cleanSource="true">
Aside from namespace declaration, it is possible to set some general attribute for the configuration :
name | type | default | description |
---|---|---|---|
boolean |
false |
If set to 'true' the FreemarkerDocProcessConfig will try to validate the source. (since 8.9.1), NOTE: if active, source reader will be buffered, potentially resulting in higher memory usage. See also FAQ. |
|
boolean |
false |
If set to 'true' the FreemarkerDocProcessConfig will fail in case of validation errors, if 'false' will just print the result as warning. (since 8.9.1), NOTE: 'validating' is set to true, this attribute is ignored. See also FAQ |
|
boolean |
false |
If set to 'true' the FreemarkerDocProcessConfig will try to clean the source (i.e. DocXmlUtils.cleanXml()). (since 8.9.1), NOTE: if active, source reader will be buffered, potentially resulting in higher memory usage. See also FAQ |
5.1.2. Element docHandlerConfig
The main elements are the <docHandlerConfig/> containing the available output format doc handlers.
<docHandlerConfig registerById="true">
<!-- Type handler for markdown format -->
<docHandler id="md-ext" info="md" type="org.fugerit.java.doc.base.typehandler.markdown.SimpleMarkdownExtTypeHandler" />
<!-- Type henalder for xml format, generates the source xml:doc -->
<docHandler id="xml-doc" info="xml" type="org.fugerit.java.doc.base.config.DocTypeHandlerXMLUTF8" />
<!-- Type handler for html using freemarker -->
<docHandler id="html-fm" info="html" type="org.fugerit.java.doc.freemarker.html.FreeMarkerHtmlTypeHandlerEscapeUTF8" />
<!-- Type handler for html using freemarker (fragment version, only generates body content no html or head part -->
<docHandler id="html-fragment-fm" info="fhtml" type="org.fugerit.java.doc.freemarker.html.FreeMarkerHtmlFragmentTypeHandlerEscapeUTF8" />
<!-- Type handler generating xls:fo style sheet -->
<docHandler id="fo-fop" info="fo" type="org.fugerit.java.doc.mod.fop.FreeMarkerFopTypeHandlerUTF8" />
<!-- Type handler generating pdf -->
<docHandler id="pdf-fop" info="pdf" type="org.fugerit.java.doc.mod.fop.PdfFopTypeHandler">
<docHandlerCustomConfig charset="UTF-8" fop-config-mode="classloader" fop-config-classloader-path="fj-doc-quarkus-tutorial/fop-config.xml" fop-suppress-events="1"/>
</docHandler>
<!-- Type handler generating xls -->
<docHandler id="xls-poi" info="xls" type="org.fugerit.java.doc.mod.poi.XlsPoiTypeHandler" />
<!-- Type handler generating xlsx -->
<docHandler id="xlsx-poi" info="xlsx" type="org.fugerit.java.doc.mod.poi.XlsxPoiTypeHandler" />
</docHandlerConfig>
5.1.3. Element docChain
And the <docChain/> elements containing the configuration for the freemarker template and data model.
Usually you will need at least one configuration step :
<docChain id="shared">
<chainStep stepType="config">
<config
id="fj_doc_config_fm_fjdocquarkustutorial"
class="org.fugerit.java.tutorial.fjdocquarkustutorial.DocHelper"
exception-handler="RETHROW_HANDLER"
fallback-on-null-loop-variable="false"
log-exception="false"
mode="class"
path="/fj-doc-quarkus-tutorial/template/"
version="2.3.32"
wrap-unchecked-exceptions="true"
load-bundled-functions="true"
/>
</chainStep>
</docChain>
And one or more document process step :
<!-- example document chain -->
<docChain id="document" parent="shared">
<chainStep stepType="complex" map-atts="listPeople" template-path="${chainId}.ftl"/>
</docChain>
5.1.4. Built-in step types
name | type | description |
---|---|---|
config |
org.fugerit.java.doc.freemarker.config.FreeMarkerConfigStep |
responsable for freemarker and venus configuration |
function |
org.fugerit.java.doc.freemarker.config.FreeMarkerFunctionStep |
add freemarker functions to the data model (some built-in functions are available) |
complex |
org.fugerit.java.doc.freemarker.config.FreeMarkerComplexProcessStep |
it apply the freemarker template and render the output |
map |
org.fugerit.java.doc.freemarker.config.FreeMarkerMapStep |
Venus data model to Freemarker data model mapping |
skipfm |
org.fugerit.java.doc.freemarker.config.FreeMarkerSkipProcessStep |
When using this step, freemarker apply template will be skipped. (Since 8.9.7) |
kotlin |
org.fugerit.java.doc.freemarker.config.FreeMarkerKotlinStep |
When using this step, freemarker apply template will be skipped. It uses kotlin script, kts-path must be set, dataModel map can still be used and will be bound to the script (Since 8.10.0) |
Additional step can be added setting the fully qualified class name in the type attribute. |
When using skipfm no FreeMarker template syntax should be used in the template. |
5.1.5. Built-in functions
name | type | description | parameters |
---|---|---|---|
imageBase64CLFun |
org.fugerit.java.doc.freemarker.fun.ImageBase64CLFun |
tries to load from classpath an image and converts it to base64 |
(1) - classloader path of the image to convert |
textWrap |
org.fugerit.java.doc.freemarker.fun.TextWrapFun |
convert a text with ​ characters (useful for long words on pdf) |
(1) - the text to wrap with ​ |
messageFormat |
org.fugerit.java.doc.freemarker.fun.SimpleMessageFun |
formats text with stardard MessageFormat |
(1) - the pattern, (2+) - parameters for message format |
sumLong |
org.fugerit.java.doc.freemarker.fun.SimpleSumLongFun |
sums numbers |
(1+) - numbers to sum |
cleanXml |
org.fugerit.java.doc.freemarker.fun.CleanXmlFun |
cleans invalid xml characters with the regex [^\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD\u10000-\u10FFF]+ |
(1) - the text to clean |
cleanText |
org.fugerit.java.doc.freemarker.fun.CleanTextFun |
cleans text with given regex |
(1) - the text to clean, (2) - regex for the pattern to remove |
formatDateTime |
org.fugerit.java.doc.freemarker.fun.FormatLocalDateTimeFun |
formats a LocalDate, LocalTime or LocalDateTime |
(1) - the date/time to format, (2) - the format pattern |
These functions can all be loaded at once with the config step attribute load-bundled-functions="true". |
5.2. Venus Freemarker Chain
With a venus freemarker chain, we use an Apache FreeMarker template (ftl) :
<?xml version="1.0" encoding="utf-8"?>
<doc
xmlns="http://javacoredoc.fugerit.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://javacoredoc.fugerit.org https://www.fugerit.org/data/java/doc/xsd/doc-2-1.xsd" >
<#--
This is a Venus Fugerit Doc (https://github.com/fugerit-org/fj-doc) FreeMarker Template XML (ftl[x]).
For consideration of Venus Fugerit Doc and Apache FreeMarker integration see :
https://venusdocs.fugerit.org/guide/#doc-freemarker-entry-point
The result will be a :
-->
<!--
This is a Venus Fugerit Doc (https://github.com/fugerit-org/fj-doc) XML Source Document.
For documentation on how to write a valid Venus Doc XML Meta Model refer to :
https://venusdocs.fugerit.org/guide/#doc-format-entry-point
-->
<#assign defaultTitle="My sample title">
<metadata>
<!-- Margin for document : left;right;top;bottom -->
<info name="margins">10;10;10;30</info>
<!-- documenta meta information -->
<info name="doc-title">${docTitle!defaultTitle}</info>
<info name="doc-subject">fj doc venus sample source FreeMarker Template XML - ftlx</info>
<info name="doc-author">fugerit79</info>
<info name="doc-language">en</info>
<!-- property specific for xls/xlsx -->
<info name="excel-table-id">data-table=print</info>
<!-- property specific for csv -->
<info name="csv-table-id">data-table</info>
<footer-ext>
<para align="right">${r"${currentPage}"} / ${r"${pageCount}"}</para>
</footer-ext>
</metadata>
<body>
<para>${docTitle!defaultTitle}</para>
<table columns="3" colwidths="30;30;40" width="100" id="data-table" padding="2">
<row header="true">
<cell align="center"><para>Name</para></cell>
<cell align="center"><para>Surname</para></cell>
<cell align="center"><para>Title</para></cell>
</row>
<#if listPeople??>
<#list listPeople as current>
<row>
<cell><para>${current.name}</para></cell>
<cell><para>${current.surname}</para></cell>
<cell><para>${current.title}</para></cell>
</row>
</#list>
</#if>
</table>
</body>
</doc>
Adding to it the data model, and applying the template :
DocHelper docHelper = new DocHelper();
// create custom data for the fremarker template 'document.ftl'
List<People> listPeople = Arrays.asList(new People("Luthien", "Tinuviel", "Queen"), new People("Thorin", "Oakshield", "King"));
// output generation
docHelper.getDocProcessConfig().fullProcess("document", DocProcessContext.newContext("listPeople", listPeople), handlerId, baos);
The Venus Freemarker Template and the data model will produce a Venus Doc Format document source :
<?xml version="1.0" encoding="utf-8"?>
<doc
xmlns="http://javacoredoc.fugerit.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://javacoredoc.fugerit.org https://www.fugerit.org/data/java/doc/xsd/doc-2-1.xsd" >
<!--
This is a Venus Fugerit Doc (https://github.com/fugerit-org/fj-doc) XML Source Document.
For documentation on how to write a valid Venus Doc XML Meta Model refer to :
https://venusdocs.fugerit.org/guide/#doc-format-entry-point
-->
<metadata>
<!-- Margin for document : left;right;top;bottom -->
<info name="margins">10;10;10;30</info>
<!-- documenta meta information -->
<info name="doc-title">My sample title</info>
<info name="doc-subject">fj doc venus sample source FreeMarker Template XML - ftlx</info>
<info name="doc-author">fugerit79</info>
<info name="doc-language">en</info>
<!-- property specific for xls/xlsx -->
<info name="excel-table-id">data-table=print</info>
<!-- property specific for csv -->
<info name="csv-table-id">data-table</info>
<footer-ext>
<para align="right">${currentPage} / ${pageCount}</para>
</footer-ext>
</metadata>
<body>
<para>My sample title</para>
<table columns="3" colwidths="30;30;40" width="100" id="data-table" padding="2">
<row header="true">
<cell align="center"><para>Name</para></cell>
<cell align="center"><para>Surname</para></cell>
<cell align="center"><para>Title</para></cell>
</row>
<row>
<cell><para>Luthien</para></cell>
<cell><para>Tinuviel</para></cell>
<cell><para>Queen</para></cell>
</row>
<row>
<cell><para>Thorin</para></cell>
<cell><para>Oakshield</para></cell>
<cell><para>King</para></cell>
</row>
</table>
</body>
</doc>
And pass it to the chosen DocHandler in order to have the desired output format, for instance the markdown version :
My sample title
| Name | Surname | Title |
|---------------|---------------|---------------|
| Luthien | Tinuviel | Queen |
| Thorin | Oakshield | King |
5.3. Venus Freemarker Usage
Adding everything together, we need a facade to read the configuration and process the Freemarker template chains :
package org.fugerit.java.tutorial.fjdocquarkustutorial;
import org.fugerit.java.doc.freemarker.process.FreemarkerDocProcessConfig;
import org.fugerit.java.doc.freemarker.process.FreemarkerDocProcessConfigFacade;
/**
* DocHelper, version : auto generated on 2024-09-25 23:53:33.687
*/
public class DocHelper {
private FreemarkerDocProcessConfig docProcessConfig = FreemarkerDocProcessConfigFacade.loadConfigSafe( "cl://fj-doc-quarkus-tutorial/fm-doc-process-config.xml" );
public FreemarkerDocProcessConfig getDocProcessConfig() { return this.docProcessConfig; }
}
And for instance a rest serive to expose the api :
package org.fugerit.java.tutorial.fjdocquarkustutorial;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.MediaType;
import lombok.extern.slf4j.Slf4j;
import org.fugerit.java.doc.base.config.DocConfig;
import org.fugerit.java.doc.base.process.DocProcessContext;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import org.eclipse.microprofile.openapi.annotations.tags.Tags;
@Slf4j
@Path("/doc")
public class DocResource {
byte[] processDocument(String handlerId) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
// creates the doc helper
DocHelper docHelper = new DocHelper();
// create custom data for the fremarker template 'document.ftl'
List<People> listPeople = Arrays.asList(new People("Luthien", "Tinuviel", "Queen"), new People("Thorin", "Oakshield", "King"));
// output generation
docHelper.getDocProcessConfig().fullProcess("document", DocProcessContext.newContext("listPeople", listPeople), handlerId, baos);
// return the output
return baos.toByteArray();
} catch (Exception e) {
String message = String.format("Error processing %s, error:%s", handlerId, e);
log.error(message, e);
throw new WebApplicationException(message, e);
}
}
@APIResponse(responseCode = "200", description = "The Markdown document content" )
@APIResponse(responseCode = "500", description = "In case of an unexpected error" )
@Tags( { @Tag( name = "document" ), @Tag( name = "markdown" ) } )
@Operation( operationId = "MarkdownExample", summary = "Example Markdown generation",
description = "Generates an example Markdown document using Fugerit Venus Doc handler" )
@GET
@Produces("text/markdown")
@Path("/example.md")
public byte[] markdownExample() {
return processDocument(DocConfig.TYPE_MD);
}
@APIResponse(responseCode = "200", description = "The HTML document content" )
@APIResponse(responseCode = "500", description = "In case of an unexpected error" )
@Tags( { @Tag( name = "document" ), @Tag( name = "html" ) } )
@Operation( operationId = "HTMLExample", summary = "Example HTML generation",
description = "Generates an example HTML document using Fugerit Venus Doc handler" )
@GET
@Produces("text/html")
@Path("/example.html")
public byte[] htmlExample() {
return processDocument(DocConfig.TYPE_HTML);
}
@APIResponse(responseCode = "200", description = "The PDF document content" )
@APIResponse(responseCode = "500", description = "In case of an unexpected error" )
@Tags( { @Tag( name = "document" ), @Tag( name = "pdf" ) } )
@Operation( operationId = "PDFExample", summary = "Example PDF generation",
description = "Generates an example PDF document using Fugerit Venus Doc handler" )
@GET
@Produces("application/pdf")
@Path("/example.pdf")
public byte[] pdfExample() {
return processDocument(DocConfig.TYPE_PDF);
}
@APIResponse(responseCode = "200", description = "The Excel document content" )
@APIResponse(responseCode = "500", description = "In case of an unexpected error" )
@Tags( { @Tag( name = "document" ), @Tag( name = "excel" ) } )
@Operation( operationId = "ExcelExample", summary = "Example Excel generation",
description = "Generates an example Excel document using Fugerit Venus Doc handler" )
@GET
@Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@Path("/example.xlsx")
public byte[] excelExample() {
return processDocument(DocConfig.TYPE_XLSX);
}
}
6. Doc Handlers
Doc Handler are modules responsible for rendering the output format.
6.1. DocHandler Module Index
doc-handler | module | type | description | notes |
---|---|---|---|---|
org.fugerit.java.doc.base.typehandler.markdown.SimpleMarkdownExtTypeHandlerNoCommentsUTF8 |
MD |
Renders a MarkDown (Extended) document. |
native ready (1) |
|
org.fugerit.java.doc.base.typehandler.markdown.SimpleMarkdownBasicTypeHandlerNoCommentsUTF8 |
MD |
Renders a MarkDown (Basic) document (tables are rendered as HTML). |
native ready (1) |
|
org.fugerit.java.doc.freemarker.html.FreeMarkerHtmlTypeHandlerEscapeUTF8 |
HTML |
Renders HTML documents using Apache FreeMarker template engine. |
native ready (1) |
|
org.fugerit.java.doc.freemarker.html.FreeMarkerHtmlFragmentTypeHandlerEscapeUTF8 |
HTML Fragment |
Same as above, but an HTML fragment is just the body of the HTML document. |
native ready (1) |
|
org.fugerit.java.doc.freemarker.asciidoc.FreeMarkerAsciidocTypeHandlerUTF8 |
ADOC |
Renders AsciiDoc documents using Apache FreeMarker template engine. |
native ready (1) |
|
PDF (PDF/A, PDF/UA) |
A PDF doc handler based on Apache FOP Project. It offers options for PDF/A and PDF/UA formats. |
|||
FO (XLS-FO) |
A XLS-FO doc handler based on Apache FOP Project. |
|||
XLSX |
Generates an XLSX document using Apache POI Project. |
|||
XLS |
Generates an XLS document using Apache POI Project. |
|||
CSV |
Generates a CSV document using OpenCSV. |
native ready (1) |
||
Generates a PDF document using OpenPDF. |
||||
HTML |
Generates a HTML document using OpenPDF. |
|||
RTF |
Generates a RTF document using OpenRTF. |
(1) Native Ready means that the GraalVM metadata are included in the release. |
Each section describing a specific doc handler will contain this quick reference :
In brief :
-
compliance level : COMPLETE, HIGH, MEDIUM, LOW, The level of support to Venus Doc Format.
-
compliance detail : The limitations to the support of the Venus Doc Format (for instance : unsupported elements or attributes).
-
native ready : YES, NO (If the doc handler is ready for native compilation with GraalVM).
<<<=== [fj-doc-base]
Here are described the doc handlers included in the basic module, which usually is always included :
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-base</artifactId>
<version>${fj-doc-version}</version>
</dependency>
6.1.1. MarkDown (Extended)
This doc handler would render a MarkDown (Extended) document. The Basic and Extended version only differ for table management. Basic version will render tables in html.
In brief :
-
compliance level : HIGH
-
compliance detail : All generic Venus Doc Format elements are supported.
-
native ready : YES
Add this element to <docHandlerConfig/> :
<docHandler id="md-ext" info="md" type="org.fugerit.java.doc.base.typehandler.markdown.SimpleMarkdownExtTypeHandlerNoCommentsUTF8" />
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial base example.
6.1.2. MarkDown (Basic)
This doc handler would render a MarkDown (Basic) document. The Basic and Extended version only differ for table management. Basic version will render tables in html.
In brief :
-
compliance level : HIGH
-
compliance detail : All generic Venus Doc Format elements are supported.
-
native ready : YES
Add this element to <docHandlerConfig/> :
<docHandler id="md-basic" info="md" type="org.fugerit.java.doc.base.typehandler.markdown.SimpleMarkdownBasicTypeHandlerNoCommentsUTF8" />
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial base example.
<<<
6.2. [fj-doc-freemarker]
To use this doc handler, you will need to add the following dependency :
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-freemarker</artifactId>
<version>${fj-doc-version}</version>
</dependency>
6.2.1. HTML
This doc handler would render a full html document.
In brief :
-
compliance level : HIGH
-
compliance detail : All generic Venus Doc Format elements are supported.
-
native ready : YES
Add this element to <docHandlerConfig/> :
<docHandler id="html-fm" info="html" type="org.fugerit.java.doc.freemarker.html.FreeMarkerHtmlTypeHandlerEscapeUTF8" />
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial base example.
6.2.2. Fragment HTML
This doc handler would render only the body of the html document.
(useful to inject the body as a fragment).
In brief :
-
compliance level : HIGH
-
compliance detail : All generic Venus Doc Format elements are supported.
-
native ready : YES
Add this element to <docHandlerConfig/> :
<docHandler id="html-fragment-fm" info="fhtml" type="org.fugerit.java.doc.freemarker.html.FreeMarkerHtmlFragmentTypeHandlerEscapeUTF8" />
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial base example.
6.2.3. Asciidoc (ADOC)
This doc handler would be rendered as an asciidoc document.
In brief :
-
compliance level : HIGH
-
compliance detail : All generic Venus Doc Format elements are supported.
-
native ready : YES
Add this element to <docHandlerConfig/> :
<docHandler id="asciidoc-fm" info="adoc" type="org.fugerit.java.doc.freemarker.asciidoc.FreeMarkerAsciidocTypeHandlerUTF8" />
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial base example.
<<<
6.3. [fj-doc-mod-fop] A PDF/FO DocHandler
To use this doc handler, you will need to add the following dependency :
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-mod-fop</artifactId>
<version>${fj-doc-version}</version>
</dependency>
This module is based on Apache FOP Project for rendering and Apache FreeMarker for composing the source document model.
Usually Apache FOP uses XSL Transformations as a mean of customizing the content. But here we follow the templating approach using FreeMarker.
6.3.1. Basic PDF DocHandler
This doc handler would render a full PDF document with default FOP configuration.
In brief :
-
compliance level : HIGH
-
compliance detail : All generic Venus Doc Format elements are supported.
-
native ready : NO (As Apache FOP is not ready).
Add this element to <docHandlerConfig/> :
<!-- Type handler generating pdf -->
<docHandler id="pdf-fop" info="pdf" type="org.fugerit.java.doc.mod.fop.PdfFopTypeHandler"/>
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial fop example.
6.3.2. Custom configured PDF DocHandler
For this DocHandler it is possible to customize some attributes, for instance :
<!-- Type handler generating pdf -->
<docHandler id="pdf-fop-config" info="pdf" type="org.fugerit.java.doc.mod.fop.PdfFopTypeHandler">
<docHandlerCustomConfig charset="UTF-8" fop-config-mode="classloader" fop-config-classloader-path="fj-doc-quarkus-tutorial/fop-config.xml"
fop-pool-min="20" fop-pool-max="40" fop-suppress-events="1"/>
</docHandler>
docHandlerCustomConfig reference for org.fugerit.java.doc.mod.fop.PdfFopTypeHandler
name | type | default | description |
---|---|---|---|
string |
UTF-8 |
This will set the charset to use. |
|
string |
Custom fop configuration mode, possible values are : classloader (path set fop-config-classloader-path) or inline (child element). |
||
string |
Path to Apache FOP Configuration file. |
||
boolean |
false |
If set to true (or 1), will try to suppress event logging (for example : new page). |
|
string |
If present will set pdf-a-mode, possible values are : PDF/A-1a, PDF/A-1b, PDF/A-2a, PDF/A-3a |
||
string |
If present, will set pdf-ua-mode, possible values are : PDF/UA-1. Partially compatible with pdf-a-mode. |
||
int |
0 |
If present, it will create a fo user agent pool, this is the minimum size of the pool. |
|
int |
0 |
If present, it will create a fo user agent pool, this is the maximum size fo the pool. |
If pdf-a-mode is set, there will be a strict validation of the PDF (i.e. it will be checked if the font are all embedded and the images should comply to PDF/A standard). |
6.3.3. PDF/A DocHandler
See also Apache FOP PDF/A.
Here is an example of PDF/A DocHandler with custom fop configuration :
<docHandler id="pdf_a-fop" info="pdf" type="org.fugerit.java.doc.mod.fop.PdfFopTypeHandler">
<docHandlerCustomConfig charset="UTF-8" fop-config-mode="classloader" fop-config-classloader-path="fop-config-pdfa.xml" pdf-a-mode="PDF/A-1b"/>
</docHandler>
And here a sample configuration file.
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial fop pdf/a example.
the PDF/A configuration is not automatically generated by the Maven Plugin. |
6.3.4. PDF/UA DocHandler (inline configuration)
<docHandlerConfig registerById="true">
<docHandler id="pdf_ua-fop" info="pdf" type="org.fugerit.java.doc.mod.fop.PdfFopTypeHandler">
<docHandlerCustomConfig charset="UTF-8" fop-config-mode="inline" pdf-ua-mode="PDF/UA-1">
<fop version="1.0">
<strict-configuration>true</strict-configuration>
<strict-validation>true</strict-validation>
<base>.</base>
<font-base>.</font-base>
<renderers>
<renderer mime="application/pdf">
<pdf-ua-mode>PDF/UA-1</pdf-ua-mode>
<pdf-a-mode>PDF/A-1b</pdf-a-mode>
<version>1.4</version>
</renderer>
</renderers>
<!-- Source resolution in dpi (dots/pixels per inch) for determining the size of pixels in SVG and bitmap images, default: 72dpi -->
<source-resolution>72</source-resolution>
<!-- Target resolution in dpi (dots/pixels per inch) for specifying the target resolution for generated bitmaps, default: 72dpi -->
<target-resolution>72</target-resolution>
<default-page-settings height="11in" width="8.26in"/>
</fop>
</docHandlerCustomConfig>
</docHandler>
6.3.5. FO DocHandler
This doc handler would render a full FO intermediate document.
In brief :
-
compliance level : HIGH
-
compliance detail : All generic Venus Doc Format elements are supported.
-
native ready : YES
Add this element to <docHandlerConfig/> :
<!-- Type handler generating xls:fo style sheet -->
<docHandler id="fo-fop" info="fo" type="org.fugerit.java.doc.mod.fop.FreeMarkerFopTypeHandlerUTF8" />
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial fop example.
<<<
6.4. [fj-doc-mod-poi] : a XLS/XLSX DocHandler
To use this doc handler, you will need to add the following dependency :
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-mod-poi</artifactId>
<version>${fj-doc-version}</version>
</dependency>
This module is based on Apache POI Project.
6.4.1. POI Handler Basics
The following information apply to both xlsx and xls DocHandler.
You will need at least a table, with an id set. (in this example the id is data-table).
And the excel-table-id element with the comma separated enumeration of the table to render as sheet. :
<info name="excel-table-id">data-table=print</info>
The given table (data-table) will be rendered as the named sheet (print) in the couple : $tableId=$sheetName.
Here is a full example.
<?xml version="1.0" encoding="utf-8"?>
<doc
xmlns="http://javacoredoc.fugerit.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://javacoredoc.fugerit.org https://www.fugerit.org/data/java/doc/xsd/doc-2-1.xsd" >
<metadata>
<!-- property specific for xls/xlsx -->
<info name="excel-table-id">data-table=print</info>
</metadata>
<body>
<table columns="3" colwidths="30;30;40" width="100" id="data-table" padding="2">
<row>
<cell align="center" border-color="#000000" border-width="1"><para style="bold">Name</para></cell>
<cell align="center"><para style="bold">Surname</para></cell>
<cell align="center"><para style="bold">Title</para></cell>
</row>
<row>
<cell><para><![CDATA[Luthien]]></para></cell>
<cell><para><![CDATA[Tinuviel]]></para></cell>
<cell><para><![CDATA[Queen]]></para></cell>
</row>
<row>
<cell><para><![CDATA[Thorin]]></para></cell>
<cell><para><![CDATA[Oakshield]]></para></cell>
<cell><para><![CDATA[King]]></para></cell>
</row>
</table>
</body>
</doc>
More elements specific to excel format are available here.
6.4.2. Xlsx DocHandler
This doc handler would a XLSX document.
In brief :
-
compliance level : MEDIUM
-
compliance detail : Only single table elements of the Venus Doc Format are rendered.
-
native ready : NO (As Apache POI is not ready).
Add this element to <docHandlerConfig/> :
<!-- XLSX type hanlder -->
<docHandler id="xlsx-poi" info="xlsx" type="org.fugerit.java.doc.mod.poi.XlsxPoiTypeHandler" />
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial poi example.
6.4.3. Xls DocHandler
This doc handler would a XLS document.
In brief :
-
compliance level : MEDIUM
-
compliance detail : Only single table elements of the Venus Doc Format are rendered.
-
native ready : NO (As Apache POI is not ready).
Add this element to <docHandlerConfig/> :
<!-- XLSX type hanlder -->
<docHandler id="xls-poi" info="xlsx" type="org.fugerit.java.doc.mod.poi.XlsPoiTypeHandler" />
6.5. [fj-doc-mod-opencsv] : a CSV DocHandler
To use this doc handler, you will need to add the following dependency :
In brief :
-
compliance level : MEDIUM
-
compliance detail : Only a single table element of the Venus Doc Format is rendered as a CSV document.
-
native ready : YES
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-mod-opencsv</artifactId>
<version>${fj-doc-version}</version>
</dependency>
This module is based on OpenCSV.
This doc handler would a CSV document.
Add this element to <docHandlerConfig/> :
<!-- CSV type hanlder -->
<docHandler id="csv-opencsv" info="csv" type="org.fugerit.java.doc.mod.opencsv.OpenCSVTypeHandler"/>
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial opencsv example.
You will need at least a table, with an id set. (in this example the id is data-table).
And the csv-table-id element with the comma separated enumeration of the table to render as sheet. :
<info name="csv-table-id">data-table</info>
Here is a full example.
<?xml version="1.0" encoding="utf-8"?>
<doc
xmlns="http://javacoredoc.fugerit.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://javacoredoc.fugerit.org https://www.fugerit.org/data/java/doc/xsd/doc-2-1.xsd" >
<metadata>
<info name="csv-table-id">data-table</info>
</metadata>
<body>
<table columns="3" colwidths="30;30;40" width="100" id="data-table" padding="2">
<row>
<cell align="center" border-color="#000000" border-width="1"><para style="bold">Name</para></cell>
<cell align="center"><para style="bold">Surname</para></cell>
<cell align="center"><para style="bold">Title</para></cell>
</row>
<row>
<cell><para><![CDATA[Luthien]]></para></cell>
<cell><para><![CDATA[Tinuviel]]></para></cell>
<cell><para><![CDATA[Queen]]></para></cell>
</row>
<row>
<cell><para><![CDATA[Thorin]]></para></cell>
<cell><para><![CDATA[Oakshield]]></para></cell>
<cell><para><![CDATA[King]]></para></cell>
</row>
</table>
</body>
</doc>
More elements specific to CSV format are available here.
In comparison to Xlsx Doc Handler the OpenCSV one is able to render only one table at once. <<< |
6.6. [fj-doc-mod-openpdf-ext] : a PDF and HTML DocHandler
To use this doc handler, you will need to add the following dependency :
In brief :
-
compliance level : MEDIUM
-
compliance detail : Most elements of the Venus Doc Format are supported. lists have not been implemented yet.
-
native ready : NO (As OpenPDF is not ready).
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-mod-openpdf-ext</artifactId>
<version>${fj-doc-version}</version>
</dependency>
This module is based on OpenPDF (based on a fork of iText).
6.6.1. [fj-doc-mod-openpdf-ext-pdf] : PDF DocHandler
This doc handler would a PDF document.
Add this element to <docHandlerConfig/> :
<!-- OpenPDF type hanlder -->
<docHandler id="openpdf" info="openpdf" type="org.fugerit.java.doc.mod.openpdf.ext.PdfTypeHandler"/>
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial openpdf ext example.
More elements specific to fixed size formats, like PDF, are available here.
docHandlerCustomConfig reference for org.fugerit.java.doc.mod.openpdf.ext.PdfTypeHandler"
name | type | default | description |
---|---|---|---|
string |
UTF-8 |
This will set the charset to use. |
Additionaly fonts can be configured as child elements of docHandlerCustomConfig
name | type | default | description |
---|---|---|---|
string |
Name of the font |
||
string |
Path of the font (in classloader of file) |
Here is a custom configuration example :
<!-- OpenPDF type hanlder -->
<docHandler id="openpdf" info="openpdf" type="org.fugerit.java.doc.mod.openpdf.ext.PdfTypeHandler">
<docHandlerCustomConfig charset="UTF-8">
<font name="TitilliumWeb" path="font/TitilliumWeb-Regular.ttf"/>
</docHandlerCustomConfig>
</docHandler>
6.6.2. [fj-doc-mod-openpdf-ext-html] : HTML DocHandler
This doc handler would a HTML document.
In brief :
-
compliance level : MEDIUM
-
compliance detail : Most elements of the Venus Doc Format are supported. lists have not been implemented yet.
-
native ready : NO (As OpenPDF is not ready).
Add this element to <docHandlerConfig/> :
<!-- OpenHTML type hanlder -->
<docHandler id="openpdf-html" info="openpdf-html" type="org.fugerit.java.doc.mod.openpdf.ext.HtmlTypeHandler"/>
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial openpdf ext example.
<<<
6.7. [fj-doc-mod-openrtf-ext] : a RTF DocHandler
To use this doc handler, you will need to add the following dependency :
In brief :
-
compliance level : MEDIUM
-
compliance detail : Most elements of the Venus Doc Format are supported. lists have not been implemented yet.
-
native ready : NO (As OpenRTF is not ready).
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-mod-openrtf-ext</artifactId>
<version>${fj-doc-version}</version>
</dependency>
This module is based on OpenRTF.
This doc handler would a RTF document.
Add this element to <docHandlerConfig/> :
<!-- OpenRTF type hanlder -->
<docHandler id="openrtf" info="openrtf" type="org.fugerit.java.doc.mod.openrtf.ext.RtfTypeHandler"/>
For a demo of this doc handler usage you can refer to the fj-doc-quarkus-tutorial full example or fj-doc-quarkus-tutorial openrtf ext example.
More elements specific to fixed size formats, like RTF, are available here.
7. Frequently asked questions (FAQ)
This sections contains some answers to frequently asked questions.
7.1. How do I create a new project using Fugerit Venus Doc?
It is possible to simply run the plugin :
mvn org.fugerit.java:fj-doc-maven-plugin:init \
-DgroupId=org.example.doc \
-DartifactId=fugerit-demo \
-Dextensions=base,freemarker,mod-fop
For more information see : Maven Plugin Goal Init.
7.2. How do I validate the doc format after freemarker processing?
If using the FreemarkerDocProcessConfig configuration
you can simply set to true the attributes :
-
validating="true"
-
failOnValidate="true" (if you want the generation to fail in case of validation errors)
For instance :
<freemarker-doc-process-config
xmlns="https://freemarkerdocprocess.fugerit.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://freemarkerdocprocess.fugerit.org https://www.fugerit.org/data/java/doc/xsd/freemarker-doc-process-1-0.xsd"
validating="true"
failOnValidate="true">
On log you will find something like :
-
DocValidationResult failed!, errors : 2
-
Validation error 0, org.xml.sax.SAXParseException; lineNumber: 42; columnNumber: 22; cvc-complex-type.2.4.a: Invalid content was found starting with element '{"http://javacoredoc.fugerit.org":h}'. One of '{"http://javacoredoc.fugerit.org":phrase, "http://javacoredoc.fugerit.org":para}' is expected.
-
Validation error 1, org.xml.sax.SAXParseException; lineNumber: 49; columnNumber: 49; cvc-complex-type.3.2.2: Attribute 'attribute-not-allowed' is not allowed to appear in element 'para'.
For more information see :
FreemarkerDocProcessConfig configuration : Attributes.
7.3. How do I clean source document before parsing to Doc Model?
If using the FreemarkerDocProcessConfig configuration
you can simply set to true the attributes :
-
cleanSource="true"
For instance :
<freemarker-doc-process-config
xmlns="https://freemarkerdocprocess.fugerit.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://freemarkerdocprocess.fugerit.org https://www.fugerit.org/data/java/doc/xsd/freemarker-doc-process-1-0.xsd"
cleanSource="true">
In case of XML source, invalid characters will be stripped :
\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD\u10000-\u10FFF
See https://www.w3.org/TR/xml/#charsets and GitHub Issue 213 - An invalid XML character (Unicode: 0x2) was found in the element content
For instance the following XML :
<para id="to-clean">test clean \u0002 end test.</para>
Would be cleaned to :
<para id="to-clean">test clean end test.</para>
For more information see :
FreemarkerDocProcessConfig configuration : Attributes.
7.4. How do I have a Excel document cells resize to fit the content.
It is possible to use the elements :
For instance :
<info name="excel-try-autoresize">true</info>
<info name="excel-fail-on-autoresize-error">false</info>
The DocHandler will try to automatically resize the cell content of the Excel Sheet.
7.5. How do I configure kotlin step in FreemarkerDocProcessConfig?
As stated in the Kotlin Source Format documentation
First of all we need to add the kotlin source support to our project :
<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-base-kotlin</artifactId>
<version>${fj-doc-version}</version>
</dependency>
Then let’s create this very simple script in the resource folder of the project kts/kotlin-01.kts :
import org.fugerit.java.doc.base.kotlin.dsl.dslDoc
dslDoc {
meta {
info( "DSL Kotlin Sample" ).name( "doc-title" )
info( "10;10;10;30" ).name( "margins" )
info( "fugerit79" ).name( "dock-author" )
info( "en" ).name( "doc-language" )
info( "data-table=print" ).name( "excel-table-id" )
}
body {
table {
row {
cell { para( "Name" ) }.align( "center" )
cell { para( "Surname" ) }.align( "center" )
cell { para( "Title" ) }.align( "center" )
}.header( true )
attListMap( data, "userList" ).forEach( { e -> row {
cell { para( attStr( e, "name" ) ) }
cell { para( attStr( e, "surname" ) ) }
cell { para( attStr( e, "title" ) ) }
} } )
}.width( 100 ).columns( 3 ).colwidths( "30;30;40" ).id( "data-table" ).padding( 2 )
}
}
Then we should create the FreemarkerDocProcessConfig configuration (or modify existing one) inside our resources folder config/freemarker-doc-process.xml :
<?xml version="1.0" encoding="utf-8"?>
<freemarker-doc-process-config
xmlns="https://freemarkerdocprocess.fugerit.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://freemarkerdocprocess.fugerit.org https://www.fugerit.org/data/java/doc/xsd/freemarker-doc-process-1-0.xsd" >
<docHandlerConfig registerById="true">
<docHandler id="md-ext" info="md" type="org.fugerit.java.doc.base.typehandler.markdown.SimpleMarkdownExtTypeHandler" />
</docHandlerConfig>
<docChain id="kotlin-01">
<chainStep stepType="kotlin" kts-path="kts/kotlin-01.kts"/>
</docChain>
</freemarker-doc-process-config>
stepType kotlin is standalone and it does not freemarker configuration step. |
stepType kotlin uses attribute kts-path, which resolve the path in the class loader. |
Then we can create and use our configuration :
FreemarkerDocProcessConfig config = FreemarkerDocProcessConfigFacade.loadConfigSafe( "cl://config/freemarker-doc-process.xml" );
List<UserModel> userList = new ArrayList<>();
userList.add( new UserModel( "Queen" , "Luthien", "Tinuviel" ) );
userList.add( new UserModel( "King" , "Thorin", "Oakshield" ) );
userList.add( new UserModel( "Strider" , "Aragorn II", null ) );
DocProcessContext context = DocProcessContext.newContext( "list", userList );
try ( FileOutputStream os = FileOutputStream( ... ) ) {
config.fullProcess( "kotlin-01", context, DocConfig.TYPE_MD, os );
}
The result should be something like :
| Name | Surname | Title |
|---------------|---------------|---------------|
| Luthien | Tinuviel | Queen |
| Thorin | Oakshield | King |
| Aragorn II | null | Strider |
7.6. PDF FOP doc handler ignores endline?
Usually PDF FOP doc handler will ignore endline.
To have endline actually be processed, it is possible to use the https://venusdocs.fugerit.org/fj-doc-base/src/main/docs/doc_xsd_config_ref.html#para attribute (when applicable).
Here is an example :
<para>This will be rendered
as a single line.</para>
<para white-space-collapse="preserve">This will be rendered
as two lines.</para>
when getting data from outside the template, endline should be property encoded (for instance with \n in properties file). |
8. Optimizations
In this chapter the main Venus optimizations ara described.
<<<
8.1. Eager vs Lazy initialization
By default, Fugerit Venus Doc has a lazy initialization approach.
In some situation it could be a good idea to have an eager (Ahead Of Time) initialization.
This can be achieved using a built-in utility :
org.fugerit.java.doc.base.config.InitHandler
Here is an example of eager initialization based on Jakarta EE event API.
package org.fugerit.java.doc.demo;
import io.quarkus.runtime.StartupEvent;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
import org.fugerit.java.doc.base.config.InitHandler;
@ApplicationScoped
public class AppInit {
@Inject
DocHelper docHelper;
void onStart(@Observes StartupEvent ev) {
/*
* This will initialize all the doc handlers using async mode.
* (use method InitHandler.initDocAll() for synced startup)
*/
InitHandler.initDocAllAsync(
docHelper.getDocProcessConfig().getFacade().handlers() );
}
}
This will initialize all the doc handlers specified as arguments by trying to create a simple document. |