
poi-tl
Open Source Java Library for Word Document Generation
Create Professional Word (DOCX) Documents Using Templates with Text, Images, Tables, Charts & More.
What is poi-tl?
poi-tl is an open source Java template engine built on top of Apache POI that enables developers to generate professional Word (DOCX) documents using templates. Unlike traditional template engines that produce text-based outputs, poi-tl works directly with Word documents, preserving all styles and formatting from the template. It uses a logic-less approach where developers define tags in the template and provide data to render the final document, ensuring clean separation between presentation and business logic.
The library supports a wide range of features including text replacement, image insertion, table rendering, numbered/bulleted lists, conditional sections, loops, nested templates, charts, comments, SDT, hyperlinks, bookmarks, and custom plugins. With support for SpringEL and extensible expression languages, poi-tl allows developers to focus on template design while keeping the code simple and maintainable. It is ideal for generating reports, invoices, certificates, and other document-heavy applications.
Getting Started with poi-tl
To get started with poi-tl, add the dependency to your Maven project or download the JAR from the [poi-tl GitHub](https://github.com/Sayi/poi-tl) releases page. The library is lightweight and integrates seamlessly with existing Apache POI-based applications. The core API follows a minimalist design—just one line of code is needed to compile, render, and write the output document. poi-tl works with DOCX templates and supports both local and remote resources like images and sub-templates.
Install poi-tl via Maven
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.2</version>
</dependency>Quick Start Example
XWPFTemplate.compile("template.docx").render(new HashMap(){{
put("title", "poi-tl template engine");
}}).writeToFile("out_template.docx"); Render Text, Images & Tables in Word Documents
poi-tl provides intuitive tag syntax to render text, images, and tables. Text tags like `{{name}}` are replaced with corresponding data values, while preserving the original style. Image tags prefixed with `@` support local paths, URLs, or structured image objects with sizing. Table tags prefixed with `#` render Java arrays or collections as formatted Word tables with customizable borders and styles. This makes it easy to generate dynamic reports, invoices, and certificates with consistent formatting and professional appearance.
How to Render Text, Image & Table via Java?
// Text & Image
put("name", "Mama");
put("logo", "assets/logo.png");
put("chart", Pictures.ofLocal("chart.png", PictureType.PNG).size(300, 200).create());
// Table
put("data", Tables.of(new String[][] {
{"Product", "Price"},
{"Apple", "$1.20"},
{"Banana", "$0.80"}
}).border(BorderStyle.DEFAULT).create());Conditional Sections & Looping for Dynamic Content
poi-tl supports conditional rendering and looping using section tags (`{{?section}}...{{/section}}`). Sections are displayed only when the data value is non-null, non-false, and non-empty. For collections, the section content is repeated for each item, enabling powerful data-driven document generation. You can use `{{=#this}}` to reference the current iteration object directly. This feature is ideal for generating dynamic lists, repeating sections in contracts, or conditionally showing/hiding content based on business rules.
How to Use Conditional & Looping Sections in Java?
// Data model
Map data = new HashMap<>();
data.put("announce", true);
data.put("songs", Arrays.asList(
new Song("Memories"),
new Song("Sugar")
));
// Template: {{?announce}}Top of the world!{{/announce}}
// Template: {{?songs}}{{name}}{{/songs}} Generate Charts, Comments & Structured Tags
poi-tl enables advanced Word features like chart rendering, comments, and structured document tags (SDT). Charts can be generated programmatically or embedded as images, supporting bar, line, pie, area, and radar chart types in 2D and 3D. Comments can be created, edited, or deleted programmatically, making it suitable for collaborative document workflows. SDT support allows integration with Word forms and structured content, while bookmarks, anchors, and hyperlinks provide navigation capabilities within the document.
How to Add Chart & Comment to Word via Java?
// Chart (using chart plugin or image)
put("chart", Charts.ofBar(new double[]{1,2,3}, new String[]{"A","B","C"}).create());
// Comment
Comment comment = new Comment("John Doe", "2023-01-01", "Please review this section.");
put("comment", comment);
// SDT
put("sdt", SDT.of("Structured content").tag("tag1").create());Template Nesting, Merging & Custom Plugins
poi-tl supports template nesting and merging, allowing modular document design. The `{{+nested}}` tag enables importing and rendering sub-templates with their own data models, ideal for reusable components like headers, footers, or sections. Document merging lets you combine multiple DOCX files into one. Additionally, poi-tl’s plugin architecture lets developers extend functionality—such as adding custom tags for Markdown conversion, code highlighting, or specialized report generation—making it highly adaptable to complex document generation needs.
How to Use Template Nesting & Merging in Java?
// Nesting
put("nested", Includes.ofLocal("footer.docx")
.setRenderModel(footerData).create());
// Merging
List files = Arrays.asList("part1.docx", "part2.docx");
XWPFTemplate merged = XWPFTemplate.compile(files).render(data);
merged.writeToFile("merged.docx"); 