Table of contents
2. Comparison of common word generation
Two, poi-tl document generation
1. Mixed chart generation error report
2. Chart parameter setting skills
foreword
Maybe you will encounter the following scenarios in your work. For example, you need to organize an event, and the organizer needs to generate a registration notice for each unit that signs up. Maybe you will say that there are not many people participating in the event, so you can fill in the information manually and then send it to the applicants. It’s okay if there are only a few or dozens of people, but if there are hundreds of people, would you still choose this way?
For this kind of batch dynamic and personalized word generation needs, is there any technology that can assist in the generation? There must be. In the Java world, there are several implementation schemes to achieve this requirement. This article recommends a simple and fast implementation method based on the open source poi-tl implementation mechanism. This article will briefly introduce the relevant knowledge of poi-tl, through a practical case practice, fully introduce how to use poi-tl to generate target documents, and share several solutions for how to generate charts in different office versions. If you happen to be making relevant technology selection, this article can be used as a reference.
1. Introduction to poi-tl
1. What is poi-tl
poi-tl (poi template language) is a Word template engine that uses Word templates and data to create awesome Word documents . poi-tl is an open source product using the Apache License 2.0 open source protocol, poi-tl github address .
2. Comparison of common word generation
plan | Portability | Feature | ease of use |
---|---|---|---|
Poi-tl |
JavaCross-platform |
Word template engine, based on Apache POI, provides a more friendly API |
Low code, just prepare document templates and data |
Apache POI |
JavaCross-platform |
The Apache project encapsulates common document operations and can also manipulate the underlying XML structure |
Documentation is incomplete, here is a tutorial: Apache POI Word Quickstart |
Freemarker |
XML cross-platform |
Only supports text, very limited |
Not recommended, XML structured code is almost unmaintainable |
OpenOffice |
Deploy OpenOffice, poor portability |
- |
Need to understand OpenOffice API |
HTML browser export |
Rely on browser implementation, poor portability |
HTML is not well compatible with Word format, the style is terrible |
- |
Jacob、winlib |
Windows platform |
- |
Complicated and not recommended at all |
3. POI-TL function points
Word Template Engine Features | describe |
---|---|
text |
render label as text |
picture |
Render labels as images |
sheet |
Render the label as a table |
the list |
Render labels as a list |
chart |
Bar chart (3D bar chart), column chart (3D column chart), area chart (3D area chart), line chart (3D line chart), radar chart, pie chart (3D pie chart), scatter chart etc. chart rendering |
If Condition Judgment |
Hide or display certain document content (including text, paragraphs, pictures, tables, lists, charts, etc.) based on conditions |
Foreach Loop |
Loop some document content (including text, paragraphs, pictures, tables, lists, charts, etc.) according to the collection |
Loop table row |
Loop to copy a row of the rendered table |
Loop table columns |
Cyclic copy rendering a column of the table |
Loop ordered list |
Supports looping of ordered lists and multi-level lists |
Highlight code highlighting |
Code block highlighting in Word, supports 26 languages and hundreds of coloring styles |
Markdown |
Render Markdown as a word document |
Word comments |
Complete annotation function, creating annotations, modifying annotations, etc. |
Word attachment |
Insert attachments in Word |
SDT Content Control |
Label support in content controls |
Textbox text box |
Label support in textbox |
picture replacement |
Replace the original picture with another picture |
bookmarks, anchors, hyperlinks |
Support for setting bookmarks, anchor points and hyperlinks in documents |
Expression Language |
Fully supports SpringEL expressions, and more expressions can be extended: OGNL, MVEL… |
style |
The template is the style, and the code can also set the style |
template nesting |
Templates contain subtemplates, and subtemplates contain subtemplates |
merge |
Word Merge Merge can also be merged at a specified location |
User-defined functions (plugins) |
Plug-in design, execute functions anywhere in the document |
Two, poi-tl document generation
Generally speaking, we will first make a standard reference template, and then replace the data that needs to be replaced into the target parameters to complete the replacement of the corresponding parameters, so we will prepare a word template at the beginning.
1. Template preparation
On any drive letter of the computer, here we take the D drive as an example, create a file and input a word document of .docx, open the document for editing
In this template, the definition of text label and image is defined. It should be noted here that { {}} must be input in English. Some friends did not pay attention to Chinese and English, which caused the program to fail to come out as expected. At the same time, note that the reference character of the picture is preceded by the English @ symbol in front of the parameter name.
Add some chart information to the template to enrich the material, which needs to be set here. The chart parameters on my personal computer are set as follows (especially pay attention to different office versions, the corresponding editing and processing methods are inconsistent):
2. Target parameter filling
First import pom.xml in the project
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yelang</groupId>
<artifactId>poi-demo2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.9.1</version>
</dependency>
</dependencies>
</project>
Parameter filling: Here, for the convenience of demonstration, the demonstration data is directly constructed. In real projects, corresponding data can be obtained from the database or other interfaces to set parameters.
package com.yelang.test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.ChartMultiSeriesRenderData;
import com.deepoove.poi.data.Charts;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.data.SeriesRenderData;
public class TestMain2 {
public static void main(String[] args) throws IOException {
Map<String, Object> map = new HashMap<String,Object>();
map.put("score", "28");
map.put("title", "测试任务");
map.put("type", "上半年综合测评");
map.put("status", "已完成");
map.put("time", "2023-07-18");
map.put("locpicture", new PictureRenderData(400, 300, "D:/image.jpg"));
map.put("urlImg", Pictures.ofUrl("https://p1.itc.cn/images01/20230418/5d13ab4a86c04a8dac668bf4129e1f0c.png", PictureType.PNG).size(400, 300).create());
ChartMultiSeriesRenderData sbqk = Charts
.ofMultiSeries("十六市区县情况", new String[] { "济南","青岛","烟台","威海"})
.addSeries("上报情况", new Double[] { 15.0,20.6,42.6,90.1})
.addSeries("查出情况", new Double[] { 12.0,15.3,28.6,80.1})
.create();
map.put("sbqk", sbqk);
ChartMultiSeriesRenderData sjzlpm = Charts
.ofMultiSeries("医院综合排名", new String[] { "山东大学齐鲁医院","山东省泰山医院","山东省第二人民医院","山东省第三医院"})
.addSeries("数据质量排名", new Double[] { 70.5,40.6,22.7,85.4})
.addSeries("价格质量排名", new Double[] { 80.5,75.6,72.7,85.4})
.create();
map.put("sjzlpm", sjzlpm);
ChartMultiSeriesRenderData qst = Charts
.ofMultiSeries("任务趋势", new String[] { "06-10","06-11","06-12","06-13","06-14","06-15"})
.addSeries("微信端", new Double[] { 70.5,40.6,22.7,85.4,700.0,40.8})
.addSeries("PC端", new Double[] { 80.5,50.6,62.7,45.4,200.0,140.8})
.addSeries("小程序端", new Double[] { 120.5,520.6,362.7,405.4,300.0,340.8})
.create();
map.put("qst", qst);
//柱状图、折线图共存
List<SeriesRenderData> seriesRenderData = new ArrayList<SeriesRenderData>(3);
SeriesRenderData series1 = new SeriesRenderData("GDP", new Double[] {70.5,40.6,22.7,85.4,700.0,40.8});
series1.setComboType(SeriesRenderData.ComboType.BAR);
seriesRenderData.add(series1);
SeriesRenderData series2 = new SeriesRenderData("人口", new Double[] {80.5,50.6,62.7,45.4,200.0,140.8});
series2.setComboType(SeriesRenderData.ComboType.BAR);
seriesRenderData.add(series2);
SeriesRenderData series3 = new SeriesRenderData("指数", new Double[] {0.6,0.6,0.7,0.4,0.7,0.8});
series3.setComboType(SeriesRenderData.ComboType.LINE);
seriesRenderData.add(series3);
ChartMultiSeriesRenderData hntb = Charts
.ofMultiSeries("某省社会排名", new String[] { "城市1","城市2","城市3","城市4","城市5","城市6"})
.create();
hntb.setSeriesDatas(seriesRenderData);
map.put("hntb", hntb);
File file = new File("D:/文件输入.docx");
XWPFTemplate template = XWPFTemplate.compile(file).render(map);
FileOutputStream out = new FileOutputStream(new File("D:\\文件输出.docx"));
template.write(out);
out.flush();
out.close();
template.close();
System.out.println("完成");
}
}
3. Generate effects
After running the above code, you can see the following output results in the D disk directory.
3. Possible problems
1. Mixed chart generation error report
If the following exception is encountered during code execution:
Exception in thread "main" com.deepoove.poi.exception.RenderException: Combo chart must set comboType field of series!
at com.deepoove.poi.policy.reference.MultiSeriesChartTemplateRenderPolicy.validate(MultiSeriesChartTemplateRenderPolicy.java:122)
at com.deepoove.poi.policy.reference.MultiSeriesChartTemplateRenderPolicy.doRender(MultiSeriesChartTemplateRenderPolicy.java:56)
at com.deepoove.poi.policy.reference.MultiSeriesChartTemplateRenderPolicy.doRender(MultiSeriesChartTemplateRenderPolicy.java:48)
at com.deepoove.poi.policy.reference.AbstractTemplateRenderPolicy.render(AbstractTemplateRenderPolicy.java:38)
at com.deepoove.poi.render.processor.ElementProcessor.visit(ElementProcessor.java:70)
at com.deepoove.poi.render.processor.ElementProcessor.visit(ElementProcessor.java:56)
at com.deepoove.poi.template.ChartTemplate.accept(ChartTemplate.java:117)
at com.deepoove.poi.render.processor.DocumentProcessor.visit(DocumentProcessor.java:104)
at com.deepoove.poi.template.ChartTemplate.accept(ChartTemplate.java:117)
at com.deepoove.poi.render.processor.DocumentProcessor.lambda$process$0(DocumentProcessor.java:58)
at java.util.ArrayList.forEach(Unknown Source)
at com.deepoove.poi.render.processor.DocumentProcessor.process(DocumentProcessor.java:58)
at com.deepoove.poi.render.DefaultRender.renderTemplate(DefaultRender.java:82)
at com.deepoove.poi.render.DefaultRender.render(DefaultRender.java:64)
at com.deepoove.poi.XWPFTemplate.render(XWPFTemplate.java:127)
at com.yelang.test.TestMain2.main(TestMain2.java:87)
Combo chart must set comboType field of series! The high probability of this problem is that the chart generation does not specify the chart type. Just specify the chart type in the required code, the error reference code is as follows:
ChartMultiSeriesRenderData hntb = Charts
.ofMultiSeries("title", new String[] { "06-10","06-11","06-12","06-13","06-14","06-15"})
.addSeries("系列1", new Double[] { 70.5,40.6,22.7,85.4,700.0,40.8})
.addSeries("系列1", new Double[] { 80.5,50.6,62.7,45.4,200.0,140.8})
.addSeries("系列1", new Double[] { 120.5,520.6,362.7,405.4,300.0,340.8})
.create();
The correct reference code is specified by series3.setComboType(SeriesRenderData.ComboType.LINE):
List<SeriesRenderData> seriesRenderData = new ArrayList<SeriesRenderData>(3);
SeriesRenderData series1 = new SeriesRenderData("GDP", new Double[] {70.5,40.6,22.7,85.4,700.0,40.8});
series1.setComboType(SeriesRenderData.ComboType.BAR);
seriesRenderData.add(series1);
SeriesRenderData series2 = new SeriesRenderData("人口", new Double[] {80.5,50.6,62.7,45.4,200.0,140.8});
series2.setComboType(SeriesRenderData.ComboType.BAR);
seriesRenderData.add(series2);
SeriesRenderData series3 = new SeriesRenderData("指数", new Double[] {0.6,0.6,0.7,0.4,0.7,0.8});
series3.setComboType(SeriesRenderData.ComboType.LINE);
seriesRenderData.add(series3);
ChartMultiSeriesRenderData hntb = Charts
.ofMultiSeries("某省社会排名", new String[] { "城市1","城市2","城市3","城市4","城市5","城市6"})
.create();
hntb.setSeriesDatas(seriesRenderData);
2. Chart parameter setting skills
Different versions of office have different interfaces for parameter replacement settings, so you need to pay special attention. Here are the setting references for the two environments. The first is office2021.
The chart parameter setting of office2021 is to click the right button of the mouse on the chart, and the optional text for viewing will appear, and you can set it here.
Taking wps as an example, the installed version of this machine is: wps11.1.0
Double-click the blank area of the chart, and set the size and attributes in the text option
Summarize
The above is the main content of this article. This article will briefly introduce the relevant knowledge of poi-tl, through a practical case practice, fully introduce how to use poi-tl to generate target documents, and share how to generate charts in several different office versions s solution. If you happen to be making relevant technology selection, this article can be used as a reference. The writing is hasty, if there is something inappropriate, welcome to criticize and correct.
Portal: poi-tl reference technology website poi-tl technology website