Git Product home page Git Product logo

poi-tl's Introduction

poi-tl(poi-template-language)

Build Status jdk1.6+ jdk1.8 poi3.16%2B poi5.1.0 Gitter

A better way to generate word(docx) with template,based on Apache POI。

What is poi-tl

FreeMarker or Velocity generates new html pages or configuration files based on text template and data. poi-tl is a Word template engine that generates new documents based on Word template and data.

The Word template has rich styles. Poi-tl will perfectly retain the styles in the template in the generated documents. You can also set styles for the tags. The styles of the tags will be applied to the replaced text, so you can focus on the template design.

poi-tl is a "logic-less" template engine. There is no complicated control structure and variable assignment, only tags, some tags can be replaced with text, pictures, tables, etc., some tags will hide certain some document content, while other tags will loop a series of document content.

"Powerful" constructs like variable assignment or conditional statements make it easy to modify the look of an application within the template system exclusively... however, at the cost of separation, turning the templates themselves into part of the application logic.

《Google CTemplate》

poi-tl supports custom functions (plug-ins), functions can be executed anywhere in the Word template, do anything anywhere in the document is the goal of poi-tl.

Feature Description
✅ Text Render the tag as text
✅ Picture Render the tag as a picture
✅ Table Render the tag as a table
✅ Numbering Render the tag as a numbering
✅ 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 Figure) and other chart rendering
✅ If Condition Hide or display certain document content (including text, paragraphs, pictures, tables, lists, charts, etc.) according to conditions
✅ Foreach Loop Loop through certain 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 column Loop copy and render a column of the table
✅ Loop ordered list Support the loop of ordered list, and support multi-level list at the same time
✅ Highlight code Word highlighting of code blocks, supporting 26 languages ​​and hundreds of coloring styles
✅ Markdown Convert Markdown to a word document
✅ Word attachment Insert attachment in Word
✅ Word Comments Complete support comment, create comment, modify comment, etc.
✅ Word SDT Complete support structured document tag
✅ Textbox Tag support in text box
✅ Picture replacement Replace the original picture with another picture
✅ bookmarks, anchors, hyperlinks Support setting bookmarks, anchors and hyperlinks in documents
✅ Expression Language Fully supports SpringEL expressions and can extend more expressions: OGNL, MVEL...
✅ Style The template is the style, and the code can also set the style
✅ Template nesting The template contains sub-templates, and the sub-templates then contain sub-templates
✅ Merge Word merge Merge, you can also merge in the specified position
✅ custom functions (plug-ins) Plug-in design, execute function anywhere in the document

TOC

Maven

<dependency>
  <groupId>com.deepoove</groupId>
  <artifactId>poi-tl</artifactId>
  <version>1.12.2</version>
</dependency>

NOTE: poi-tl 1.12.x requires POI version 5.2.2+.

Quick start

Start with a deadly simple example: replace {{title}} with "poi-tl template engine".

  1. Create a new document template.docx, including the content {{title}}
  2. TDO mode: Template + data-model = output
//The core API uses a minimalist design, only one line of code is required
XWPFTemplate.compile("template.docx").render(new HashMap<String, Object>(){{
         put("title", "poi-tl template engine");
}}).writeToFile("out_template.docx");

Open the out_template.docx document, everything is as you wish.

Tags

The tag consists of two curly braces, {{title}} is a tag, {{?title}} is also a tag, title is the name of the tag, and ? identifies the type of tag. Next, we Let’s see what tag types are there.

Text

The text tag is the most basic tag type in the Word template. {{name}} will be replaced by the value of key name in the data model. If the key is not exist, the tag will be cleared(The program can configure whether to keep the tag or throw an exception).

The style of the text tag will be applied to the replaced text, as shown in the following example.

Code:

put("name", "Mama");
put("thing", "chocolates");

Template:

{{name}} always said life was like a box of {{thing}}.

Output:

Mama always said life was like a box of chocolates.

Picture

The image tag starts with @, for example, {{@logo}} will look for the value with the key of logo in the data model, and then replace the tag with the image. The data corresponding to the image tag can be a simple URL or Path string, or a structure containing the width and height of the image.

Code:

put("watermelon", "assets/watermelon.png");
put("watermelon", "http://x/lemon.png");
put("lemon", Pictures.ofLocal("sob.jpeg", PictureType.JPEG).size(24, 24).create());

Template:

Fruit Logo:
watermelon {{@watermelon}}
lemon {{@lemon}}
banana {{@banana}}

Output:

Fruit Logo:
watermelon 🍉
lemon 🍋
banana 🍌

Table

The table tag starts with #, such as {{#table}}, it will be rendered as a Word table with N rows and N columns. The value of N depends on the data of the table tag.

Code:

put("table", Tables.of(new String[][] {
                new String[] { "Song name", "Artist" }
            }).border(BorderStyle.DEFAULT).create());

Template:

{{#table}}

Output:

Song nameArtist

Numbering

The list tag corresponds to Word's symbol list or numbered list, starting with *, such as {{*number}}.

Code:

put("list", Numberings.create("Plug-in grammar",
                  "Supports word text, pictures, table...",
                  "Template, not just template, but also style template"));

Template:

{{*list}}

Output:

● Plug-in grammar
● Supports word text, pictures, table...
● Templates, not just templates, but also style templates

Sections

A section is composed of two tags before and after, the start tag is identified by ?, and the end tag is identified by /, such as {{?section}} as the start tag of the sections block, {{/section} } is the end tag, and section is the name of this section.

Sections are very useful when processing a series of document elements. Document elements (text, pictures, tables, etc.) located in a section can be rendered zero, one or N times, depending on the value of the section.

False Values or Empty collection

If the value of the section is null, false or an empty collection, all document elements located in the section will not be displayed, similar to the condition of the if statement is false.

Datamodel:

{
  "announce": false
}

Template:

Made it,Ma!{{?announce}}Top of the world!{{/announce}}
Made it,Ma!
{{?announce}}
Top of the world!🎋
{{/announce}}

Output:

Made it,Ma!
Made it,Ma!

Non-False Values and Not a collection

If the value of the section is not null, false, and is not a collection, all document elements in the section will be rendered once, similar to the condition of the if statement is true.

Datamodel:

{
  "person": { "name": "Sayi" }
}

Template:

{{?person}}
  Hi {{name}}!
{{/person}}

Output:

  Hi Sayi!

Non-Empty collection

If the value of the section is a non-empty collection, the document elements in the section will be looped once or N times, depending on the size of the collection, similar to the foreach syntax.

Datamodel:

{
  "songs": [
    { "name": "Memories" },
    { "name": "Sugar" },
    { "name": "Last Dance" }
  ]
}

Template:

{{?songs}}
{{name}}
{{/songs}}

Output:

Memories
Sugar
Last Dance

In the loop, a special tag {{=#this}} can be used to directly refer to the object of the current iteration.

Datamodel:

{
  "produces": [
    "application/json",
    "application/xml"
  ]
}

Template:

{{?produces}}
{{=#this}}
{{/produces}}

Output:

application/json
application/xml

Nesting

Nesting is the merging of another Word template in a Word template, which can be understood as import, include or word document merging, marked with +, such as {{+nested}}.

Code:

class AddrModel {
  String addr;
  public AddrModel(String addr) {
    this.addr = addr;
  }
}

List<AddrModel> subData = new ArrayList<>();
subData.add(new AddrModel("Hangzhou,China"));
subData.add(new AddrModel("Shanghai,China"));
put("nested", Includes.ofLocal("sub.docx").setRenderModel(subData).create());

Two Word Template:

main.docx:

Hello, World
{{+nested}}

sub.docx:

Address: {{addr}}

Output:

Hello, World
Address: Hangzhou,China
Address: Shanghai,China

Documentation and examples

中文文档

For more examples and the source code of all examples, see JUnit testcases.

Contributing

You can join this project in many ways, not limited to the following ways:

  • Feedback problems encountered in use
  • Share the joy of success
  • Update and improve documentation
  • Solve and discuss issues

FAQ

See FAQ.

poi-tl's People

Contributors

c-poet avatar caocao0427 avatar dependabot[bot] avatar donglong avatar imlzw avatar jolongriver avatar larryju avatar realize096 avatar sayi avatar show1999 avatar storypanda avatar wninayyds avatar xiaokarepo avatar xzxiaoshan avatar zjiajun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

poi-tl's Issues

english

feature request : translate lib/doc in english : Minimum

怎么进行数学公式TeX或MathMl的写入呢?

就是怎么将数学公式的tex格式或mathml格式的写到word,打开的时候显示正常的数学公式。如:{A= \{(x,\, y)\mathrel{|} x^{2}+ y^{2}\leq 16\}} 的tex,将显示x的平方加y的平方等,而不是tex格式串。

一点点奇怪的想法

我觉得这个项目要是可以函数化参数就太棒了。
比如我在word中 写{{add(1,2)}}
后台模板参数替换 add(,)
1和2形成一个String 的参数列表, 传给后台
后台再进行处理

表格合并

1.不知道是否支持去除表格边框及合并单元格?
2.您说的自定义表格处理是指的什么,在wiki上没有看到

是否有考虑过实现目录这个功能呢,这个功能有点头疼

现在本人需要从一个带有目录的word中读取出内容,再把这个目录的内容格式化生成另一个文件
问题
1.在读取时如何更好的读取,因为有分一级目录,二级目录等,因为一级目录与二级目录所要的样式不同。
2.读取后格式化到另一个word时里面的目录如何实现(ctrl+点击)直接到达那个目录下的内容
楼主有什么好的建议么?打扰了...

table 渲染?

为什么表格数据的渲染,要用 value1;value2 之间要用 ; 分割开??? 这种写法好奇怪。如果我的value1的值中含有“;” 就会出问题。感觉不应该这样处理。应该有其他更好的方法。比如用List

如何实现动态数量数量的模版

定义一个模版之后,如何可以实现对这个模版的套用多个数据,生成不定多个模版的渲染结果,在同一个word文件里面。

或者说部分模版功能的循环调用,实现模版对多个数据对象的渲染。

表格内嵌套表格生成出错

您好,我在生成嵌套表格时遇到一些问题,样式如下:
default

堆栈如下:
java.lang.IndexOutOfBoundsException: Index: 11, Size: 4

at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:661)
at java.util.ArrayList.add(ArrayList.java:473)
at com.deepoove.poi.NiceXWPFDocument.insertNewTable(NiceXWPFDocument.java:158)
at com.deepoove.poi.policy.SimpleTableRenderPolicy.render(SimpleTableRenderPolicy.java:86)
at com.deepoove.poi.render.RenderAPI.render(RenderAPI.java:126)
at com.deepoove.poi.XWPFTemplate.render(XWPFTemplate.java:140)

看了下是bodyElements.add(i, newT)时下标越界了。
尝试将嵌入的表格移到外边,可正常生成,希望能得到您的帮助,谢谢

特定文档位置放变量会出现空指针:存在bug

在特定文档位置放变量会出现空指针 startText为null
if (startOffset <= 0) {
//start run 无需split
XWPFRun templateRun = runs.get(startRunPos);
templateRun.setText(tags.get(--tagIndex), 0);
runTemplate = parseRun(runs.get(startRunPos));
} else {
//split start run, set extra in a run
String extra = startText.substring(0, startOffset);
XWPFRun extraRun = runs.get(startRunPos);
extraRun.setText(extra, 0);

			XWPFRun templateRun = paragraph.insertNewRun(startRunPos + 1);
			StyleUtils.styleRun(templateRun, extraRun);
			templateRun.setText(tags.get(--tagIndex), 0);
			runTemplate = parseRun(runs.get(startRunPos + 1));
		}

缺少个测试模板

你好,
有个小问题,
ComplexRenderTest中引用的模板缺失
src/test/resources/complex.docx

不支持替换文本框吗?

由于自己有个套打的需求,需要将文字定位在某个位置上,但是发现如果参数写在了文本框中就无法进行替换,请问只能拿表格来替换吗?

可不可以实现中括号开始和结尾,中间的变量中文

作者你好,你写的框架解决了我很大难题,可不可以实现中括号开始和结尾,中间的变量中文,目前我通过修改GramerSymbol这个类GRAMER_PREFIX,GRAMER_SUFFIX实现了中括号开头和结尾,通过修改TemplateResolver这个类修改RULER_REGEX的正则 MessageFormat.format("{0}{1}[\u4e00-\u9fa5\w]+{2}", prefixRegex, signRegex, suffixRegex);实现中文变量。但是这样违反了框架的扩展性。希望提供可配置类

关于表格的疑问

  1. 请问 TableRenderData width参数的单位是什么?
  2. 请问 可以处理table有两个头的情况么?
    image

如何自定义下划线?

有些内容是需要动态生成的,里面有的文字需要添加下划线,这是怎么给部分内容添加下划线呢,希望给予回复,谢谢

请问文本框的变量怎么替换?

在模板word里插入一个 文本框 , 文本框里 输入 {{xxx}} 变量 , 可是生成后的word 文档中 依然存在{{xxx}} ,没有替换成功

关于云服务器上部署

查看了你的说明文档,这个需要有
image
请问下是否可以在Linux系统下搭建,是否在Linux下安装openoffice 与word lib库一样可以用呢

V1.0.0 版本特性

  • 完善单元测试,应用场景
  • 优化奔跑的字符串算法
  • 网页下载docx demo
  • 高级扩展:插件化,支持自定义语法

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.