Quickly Generate Word Reports with SpringBoot and POI‑TL
This article shows how to use SpringBoot together with the POI‑TL template engine to create Word reports that embed text, images, tables and charts, providing a step‑by‑step guide, code snippets and a reusable utility class for rapid document generation.
1. Poi‑tl Overview
Poi‑tl is a lightweight, cross‑platform Java library built on Apache POI. It uses a Freemarker‑like syntax to replace placeholders in a Word template and provides extensibility through a plugin mechanism.
2. Common Tags
2.1 Text
Format: {{var}}
Example:
put("name", "Sayi");
put("author", new TextRenderData("000000", "Sayi"));
// Hyperlink
put("link", new HyperLinkTextRenderData("website", "http://deepoove.com"));2.2 Image
Format: starts with @, {{@var}}
Example:
// Local image
put("local", new PictureRenderData(80, 100, "./sayi.png"));
// Image stream
put("localbyte", new PictureRenderData(80, 100, ".png", new FileInputStream("./logo.png")));
// Network image (beware of latency)
put("urlpicture", new PictureRenderData(50, 50, ".png", BytePictureUtils.getUrlBufferedImage("http://deepoove.com/images/icecream.png")));2.3 Table
Format: starts with #, {{#var}}
Data model is illustrated in the accompanying image.
2.4 List
Format: starts with *, {{*var}}
Supported list styles include decimal, roman numerals, bullets, etc.
FMT_DECIMAL // 1. 2. 3.
FMT_DECIMAL_PARENTHESES // 1) 2) 3)
FMT_BULLET // ● ● ●
FMT_LOWER_ROMAN // i ii iii2.5 Single‑Series Chart
Used for charts that display a single data series (e.g., pie chart). The placeholder follows the same {{val}} syntax.
2.6 Multi‑Series Chart
Used for combined charts such as bar‑line mixes. The format is identical to the single‑series case.
3. Code Encapsulation
The tag handling is wrapped in a set of classes:
public enum WordContentTypeEnum { TEXT, PICTURE, TABLE, LIST, CHART; }
public class LabelData { private String labelName; private WordContentTypeEnum typeEnum; }
public interface GenerateWord { Object generateWord(LabelData data); }
public class GenerateWordFactory {
private static final Map<WordContentTypeEnum, GenerateWord> TYPE_BACK_DATA = new HashMap<>();
public static void register(WordContentTypeEnum type, GenerateWord impl) { TYPE_BACK_DATA.put(type, impl); }
public static GenerateWord getBackData(WordContentTypeEnum type) { return TYPE_BACK_DATA.get(type); }
}Specific implementations ( TextGenerateWord, PictureGenerateWord, TableGenerateWord, ListGenerateWord, ChartGenerateWord) are annotated with @Component and register themselves in GenerateWordFactory via @PostConstruct.
3.5 Chart Generation
The chart data model distinguishes single‑series ( ChartSingleSeriesRenderData) and multi‑series ( ChartMultiSeriesRenderData) and uses CharCombinationType to indicate the combination mode.
4. Testing
4.1 Template File
The Word template is placed under resources/static/template/demo_template.docx.
4.2 Assemble Data
private static final String TEMPLATE_PATH = "static/template/demo_template.docx";
List<LabelData> generates = new ArrayList<>();
// Text
TextContentData title = new TextContentData();
title.setContent("2022 Monthly Report").setLabelName("title").setTypeEnum(WordContentTypeEnum.TEXT);
generates.add(title);
// Styled text
TextContentData styled = new TextContentData();
styled.setRenderData(new TextRenderData("cc0000", "Styled content"))
.setLabelName("typeContent").setTypeEnum(WordContentTypeEnum.TEXT);
generates.add(styled);
// Image
PictureContentData pic = new PictureContentData();
pic.setWidth(200).setHeight(160).setPicType(PicTypeEnum.JPG)
.setFile(new File("D:/down/java.jpg"))
.setLabelName("picture").setTypeEnum(WordContentTypeEnum.PICTURE);
generates.add(pic);
// Table
TableSeriesRenderData table = new TableSeriesRenderData();
TextRenderData[] header = { new TextRenderData("Class"), new TextRenderData("Rank") };
List<TextRenderData[]> rows = Arrays.asList(
new TextRenderData[]{ new TextRenderData("Science 1"), new TextRenderData("1") },
new TextRenderData[]{ new TextRenderData("Kindergarten 3"), new TextRenderData("6") }
);
table.setHeader(header).setContents(rows).setLabelName("showTable").setTypeEnum(WordContentTypeEnum.TABLE);
generates.add(table);
// List
ListRenderData list = new ListRenderData();
list.setList(Arrays.asList(new TextRenderData("Item 1"), new TextRenderData("Item 2"), new TextRenderData("Item 3")))
.setPair(NumbericRenderData.FMT_LOWER_ROMAN)
.setLabelName("numList").setTypeEnum(WordContentTypeEnum.LIST);
generates.add(list);
// Charts (line, bar, pie, etc.) – examples omitted for brevity but follow the same pattern using ChartSeriesRenderData.
OperateWordManage.generateWordContent(templateFile, "D:/down/output.docx", generates);4.3 Result
The generated Word document contains all placeholders replaced with the supplied text, images, tables, lists and charts, demonstrating that the POI‑TL based utility can quickly produce complex reports.
Source code is available at:
https://github.com/lovejiashn/generate_report.git
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer XiaoFu
xiaofucode.com – a programmer learning guide driven by the pursuit of profit
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
