Introduction to poi-tl and rendering of text/tables and images

1. Introduction to poi-tl

The introduction below is from the official documentation.

Official document: http://deepoove.com/poi-tl/#_why_poi_tl

1 Introduction

poi-tl (poi template language) is a Word template engine that uses Word templates and data to create awesome Word documents.

poi-tl is a Word template engine based on Apache POI. It is also a free and open source Java class library. You can easily add it to your project, and it has pleasing features.

V1.12.x版本作了一个不兼容的改动,升级的时候需要注意:

  • Refactored PictureRenderData and changed it to an abstract class. It is recommended to use the Pictures factory method to create picture data

2. The difference between poi-tl and poi

The difference between poi-tl and poi:

insert image description here

3. Quick start

General steps used by poi-tl:

  1. Introduce dependencies
<dependency>
  <groupId>com.deepoove</groupId>
  <artifactId>poi-tl</artifactId>
  <version>1.12.1</version>
</dependency>
  1. define template

模板是Docx格式的Word文档, you can use any software you like to make templates, such as Microsoft office, WPS Office, Pages, etc., or you can use Apache POI code to generate templates.

The template is the style, and the code can also set the style.

All tags end with { {开头,以}}, and tags can appear anywhere, including headers, footers, inside tables, text boxes, etc. Table layouts can design many excellent and professional documents, and table layouts are recommended.

A label is composed of two braces before and after, { {title}} is a label, { {?title}} is also a label, title is the name of the label, and the ? question mark identifies the type of label, such as a table, picture or custom label.

Generally, we define the template format offline. For example: create a new Word document template.docx, the file content is as follows:
insert image description here

  1. Data input

The data is similar to a hash or a dictionary, and can be a Map structure (key is the label name) or an object (the attribute name is the label name).

  1. output template

There are many ways to output templates, such as:

  • Output in the form of output stream | file stream, etc. Finally don't forget to close these streams.

Getting started example demo:

XWPFTemplate template = XWPFTemplate.compile("template.docx").render(
  new HashMap<String, Object>(){
    
    {
    
    
    put("title", "Hi, poi-tl Word模板引擎");
}});  
template.writeAndClose(new FileOutputStream("output.docx")); 

2. Text/Table and Image Rendering

The following is a brief introduction to the rendering of text, tables and pictures.

1. Text

Text tags: { {var}}

Data model:

  • String: text
  • TextRenderData : styled text
  • HyperlinkTextRenderData : hyperlink and anchor text
  • Object: call toString() method to convert to text
put("name", "Sayi");
put("author", new TextRenderData("000000", "Sayi"));
put("link", new HyperlinkTextRenderData("website", "http://deepoove.com"));
put("anchor", new HyperlinkTextRenderData("anchortxt", "anchor:appendix1"));

// 还提供了更加优雅的工厂 Texts 和链式调用的方式轻松构建文本模型。
put("author", Texts.of("Sayi").color("000000").create());
put("link", Texts.of("website").link("http://deepoove.com").create());
put("anchor", Texts.of("anchortxt").anchor("appendix1").create());

The POI-TL template is the style. Generally, the template document can set the style, and the code does not need to be processed.

2. Form

Table tags start with #: { {#var}}

Data model:

  • TableRenderData

推荐使用工厂 Tables 、 Rows 和 Cells 构建表格模型。

// 第0行居中且背景为蓝色的表格
RowRenderData row0 = Rows.of("姓名", "学历").textColor("FFFFFF")
      .bgColor("4472C4").center().create();
RowRenderData row1 = Rows.create("李四", "博士");
put("table1", Tables.create(row0, row1));

3. Pictures

Image tags start with @: { {@var}}

Data model:

  • String : image url or local path, the image size is used by default
  • PictureRenderData
  • ByteArrayPictureRenderData
  • FilePictureRenderData
  • UrlPictureRenderData

推荐使用工厂 Pictures 构建图片模型。

// 指定图片路径
put("image", "logo.png");
// svg图片
put("svg", "https://img.shields.io/badge/jdk-1.6%2B-orange.svg");

// 设置图片宽高
put("image1", Pictures.ofLocal("logo.png").size(120, 120).create());

// 图片流
put("streamImg", Pictures.ofStream(new FileInputStream("logo.jpeg"), PictureType.JPEG)
  .size(100, 120).create());

// 网络图片(注意网络耗时对系统可能的性能影响)
put("urlImg", Pictures.ofUrl("http://deepoove.com/images/icecream.png")
  .size(100, 100).create());

// java图片
put("buffered", Pictures.ofBufferedImage(bufferImage, PictureType.PNG)
  .size(100, 100).create());

4. Example template demo

Example demo, rendering text, tables and pictures.

1) Create a new template document template document.docx

insert image description here

2) The complete code is as follows:

public class PoiWordTest1 {
    
    


    private static void createTemplateData() throws IOException {
    
    
        String dirName = "D:\\TempFiles\\poitl";
        String templateFileName = "template文档.docx";
        String outFileName = "output文档.docx";

        // 模板数据
        Map<String, Object> templateData = new HashMap<>();

        // 1.文本
        templateData.put("txt1", "测试文本1");
        templateData.put("txt2", "测试文本2");
        templateData.put("table1Name", "测试table1Name");
        templateData.put("img1Name", "测试img1Name");

        // 2.表格
        List<TableInfo> tableInfoList = new ArrayList<>();
        tableInfoList.add(new TableInfo("类型1", 3001, new BigDecimal("19.484")));
        tableInfoList.add(new TableInfo("类型2", 180, new BigDecimal("1.10")));
        tableInfoList.add(new TableInfo("类型3", 2000, new BigDecimal("19.485")));
        tableInfoList.add(new TableInfo("类型4", 180, new BigDecimal("1.100")));

        tableInfoList = tableInfoList.stream().sorted(Comparator.comparingInt(TableInfo::getInfoCount).reversed()).collect(Collectors.toList());
        String[] tableHeader = new String[]{
    
    "序号", "类型", "数量", "百分比"};
        createTable(templateData, tableHeader, tableInfoList);

        // 3.图片
        String fileName = "b1.jpg";
        FileInputStream inputStream = new FileInputStream(dirName + File.separator + fileName);
        templateData.put("img1", Pictures.ofStream(inputStream, PictureType.PNG)
                .size(200, 220)
                .create());

        // 4. 创建模板,输出模板
        XWPFTemplate template = XWPFTemplate.compile(dirName + File.separator + templateFileName)
                .render(templateData);
        template.writeAndClose(new FileOutputStream(dirName + File.separator + outFileName));
    }

    private static void createTable(Map<String, Object> templateData, String[] tableHeader, List<TableInfo> tableInfoList) {
    
    
        // 表格
        RowRenderData tableHeaderRow = Rows.of(tableHeader).bgColor("BDDCE6").center().create();

        RowRenderData[] rowRenderData = new RowRenderData[tableInfoList.size() + 1];
        rowRenderData[0] = tableHeaderRow;
        for (int i = 0; i < tableInfoList.size(); i++) {
    
    
            TableInfo tableInfo = tableInfoList.get(i);
            String type = tableInfo.getType();
            Integer infoCount = tableInfo.getInfoCount();
            BigDecimal ratio = tableInfo.getRatio();

            String infoCountStr = infoCount == null ? "" : String.valueOf(infoCount);
            // 保留两位小数
            String ratioStr = bigDecimal2Str(ratio, 2);
            if (StringUtils.isNotBlank(ratioStr)) {
    
    
                ratioStr = ratioStr + "%";
            }

            RowRenderData rowData = Rows.create(String.valueOf(i + 1), type, infoCountStr, ratioStr);
            rowRenderData[i + 1] = rowData;
        }

        // 一个几行4列的表格
        templateData.put("table1Info", Tables.create(rowRenderData));

    }

    /**
     * 转string,四舍五入
     *
     * @param value
     * @param newScale - 保留几位小数,默认2
     * @return
     */
    private static String bigDecimal2Str(BigDecimal value, Integer newScale) {
    
    
        if (value == null) {
    
    
            return "";
        }
        newScale = newScale == null ? 2 : newScale;
        BigDecimal bigDecimal = value.setScale(newScale, BigDecimal.ROUND_HALF_UP);
        return bigDecimal.toString();
    }

    public static void main(String[] args) throws IOException {
    
    
        createTemplateData();
    }

}

3) Output document:

insert image description here

注意:

  • The picture is embedded by default. If you want to use it to float above the text, bloggers have not yet found a way.

insert image description here

The above files are all local. Write a common method below. Template stream, the output generates a template stream and saves it to the file system.

        // 4. 创建模板,输出模板
        InputStream templateInput = getTemplateInputStream("文件ID"); //通过文件系统获取定义好的文件模板流
        XWPFTemplate template = XWPFTemplate.compile(templateInput).render(templateData);
        // 输出生成的模板流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        template.writeAndClose(byteArrayOutputStream);

        // 保存生成的模板流文件到文件系统
        byte[] buffer = byteArrayOutputStream.toByteArray();
        InputStream saveInputStream = new ByteArrayInputStream(buffer);
        String outFileName = "output文档.docx";
        saveGenerateTemplateFile(saveInputStream, outFileName);

For more usage, see the official documentation.

– If you are hungry for knowledge, be humble if you are foolish.

Guess you like

Origin blog.csdn.net/qq_42402854/article/details/130248645