poi-tl简介与文本/表格和图片渲染

news2024/12/23 18:40:25

一、poi-tl简介

下面简介来自官方文档。

官方文档:http://deepoove.com/poi-tl/#_why_poi_tl

1、简介

poi-tl(poi template language)是Word模板引擎,使用Word模板和数据创建很棒的Word文档。

poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你可以非常方便的加入到你的项目中,并且拥有着让人喜悦的特性。

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

  • 重构了PictureRenderData,改为抽象类,建议使用Pictures工厂方法来创建图片数据

2、poi-tl与poi区别

poi-tl与poi区别:

在这里插入图片描述

3、快速入门

poi-tl使用的通用步骤:

  1. 引入依赖
<dependency>
  <groupId>com.deepoove</groupId>
  <artifactId>poi-tl</artifactId>
  <version>1.12.1</version>
</dependency>
  1. 定义模板

模板是Docx格式的Word文档,你可以使用Microsoft office、WPS Office、Pages等任何你喜欢的软件制作模板,也可以使用Apache POI代码来生成模板。

模板即样式,同时代码也可以设置样式。

所有的标签都是以{{开头,以}}结尾,标签可以出现在任何位置,包括页眉,页脚,表格内部,文本框等,表格布局可以设计出很多优秀专业的文档,推荐使用表格布局。

标签由前后两个大括号组成,{{title}}是标签,{{?title}}也是标签,title是这个标签的名称,?问号标识了标签类型,比如表格,图片或者自定义标签等。

一般我们线下定义好模板格式。比如:新建Word文档 template.docx,文件内容如下:
在这里插入图片描述

  1. 填充数据

数据类似于哈希或者字典,可以是Map结构(key是标签名称),也可以是对象(属性名是标签名称)。

  1. 输出模板

输出模板的方式有很多种,比如:

  • 以输出流|文件流等方式进行输出。最后不要忘记关闭这些流。

入门示例demo:

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

二、文本/表格和图片渲染

下面进行文本、表格和图片的渲染简介。

1、文本

文本标签:{{var}}

数据模型:

  • String :文本
  • TextRenderData :有样式的文本
  • HyperlinkTextRenderData :超链接和锚点文本
  • Object :调用 toString() 方法转化为文本
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());

POI-TL模板即样式,一般模板文档能设置好的样式,代码就不要处理啦。

2.表格

表格标签以#开始:{{#var}}

数据模型:

  • 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、图片

图片标签以@开始:{{@var}}

数据模型:

  • String :图片url或者本地路径,默认使用图片自身尺寸
  • 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、示例模板demo

示例demo,进行文本、表格和图片的渲染。

1)新建模板文档 template文档.docx

在这里插入图片描述

2)完整代码如下:

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)输出文档:

在这里插入图片描述

注意:

  • 图片默认是嵌入型的,如果你想使用浮于文字之上,目前博主还没找到方法。

在这里插入图片描述

上面文件都是本地的。下面写一个常用的方法。模板流,输出生成模板流,保存到文件系统中。

        // 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);

更多使用参见官方文档。

– 求知若饥,虚心若愚。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/455539.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Python】【进阶篇】5、Django Admin后台管理系统

目录 5、Django Admin后台管理系统1. 后台管理系统的重要性2. 了解Django后台管理功能 5、Django Admin后台管理系统 Django 的后台管理系统是非常出色的&#xff0c;新建项目以后&#xff0c;Django 就为我们设置好了后台管理系统的各种功能&#xff0c;本节我们将一起认识它…

SQLServer:Win/Linux环境安装及一键部署脚本

1. Win安装SQLServer CSDN已有完整安装流程&#xff0c;亲测可用。----》Windows安装SQLServer流程 2. Linux安装 SQLServer 2.1 设置镜像 curl https://packages.microsoft.com/config/rhel/7/mssql-server-2017.repo > /etc/yum.repos.d/mssql-server.repo 2.2 通过y…

Adobe国际认证证书有用吗?

Adobe国际认证又称为Adobe认证(英文:Adobe Certified Professional)是Adobe公司CEO签发的权威国际认证体系,旨在为用户提供Adobe软件的专业认证。 该体系基于Adobe核心技术及岗位实际应用操作能力的测评体系得到国际ISTE协会的认可&#xff0c;并在全球 148 各国家推广&#x…

心理预期太大,容易失望

心理预期太大&#xff0c;是做事的障碍 心理预期与标准有关&#xff1a;亚马逊创始人谈标准 趣讲大白话&#xff1a;对事要有合理的心理预期 【趣讲信息科技144期】 **************************** 亚马逊创始人贝索斯在《长期主义》中 对高标准的四大要素&#xff1a; 1.可以通…

Node实现CSDN博客导出(后续)

前言 在2021年我实现了一个Node导出博客的功能&#xff1a;爬取接口及博客页面并导出为md文件格式。中途有许多迭代及优化以及解决了一些关键问题&#xff0c;写篇文章做个记录和review 博客更新功能 在原有的导出功能上增加了博客更新的功能&#xff0c;避免了每次都全部导…

Java7

Java7 &#xff08;一&#xff09;、集合体系&#xff08;二&#xff09;、Collection&#xff08;三&#xff09;、Collection的遍历方式3.1迭代器3.2增强for遍历3.3 Lambda表达式遍历 &#xff08;四&#xff09;、List&#xff08;五&#xff09;、数据结构5.1 栈5.2 队列5.…

C learning_8

猜数字游戏 猜数字游戏&#xff1a; 1.电脑会随机产生一个数 2.猜数字 a>猜大了&#xff0c;提醒猜大了&#xff0c;继续猜 b>猜小了&#xff0c;提醒猜小了&#xff0c;继续猜 c>猜对了&#xff0c;恭喜你&#xff0c;猜对了&#xff0c;游戏结束 3.玩完之后可以继续…

给httprunnermanager接口自动化测试平台加点颜色(一)

文章目录 一、背景1.1、部署过程略 二、使用过程2.1、新增接口列2.2、实现搜索效果 三、总结 一、背景 https://github.com/httprunner/HttpRunnerManager.git从github上找的接口测试平台&#xff0c;引入公司作为测试协同测试的平台&#xff0c;底层框架基于httprunner(reque…

SOLIDWORKS钣金设计需要考虑的折弯问题

设计需要考虑&#xff0c;究竟哪些是成型前加工&#xff0c;究竟哪些是成型后加工。 考虑工作制作工艺过程中&#xff0c;必须先折弯&#xff0c;后加工部分孔的情况有&#xff1a; 距离折弯边很近的圆孔&#xff0c;方孔&#xff0c;腰圆孔&#xff0c;螺纹等&#xff0c;下…

如何测试信号源或者发射机的回波损耗

信用源或者发射机的return loss测试过程 1.用网分线缆的第一步就是看线的抖动情况&#xff0c;后面还是要多注意 经过一系列排查后&#xff0c;选用两个抖动比较小的线缆&#xff0c;然后开始测试另外一台仪器。 2.检查测试仪器的输出功率&#xff0c;见图1 打开信号源或者发射…

项目管理-项目经理的5种权力

1、项目团队&#xff1a;是执行项目工作&#xff0c;以实现项目目标的一组人员&#xff0c;由为了完成项目而承担不同角色与职责的人员组成。 项目团队成员可能具备不同的技能&#xff0c;可能是全职的或兼职的&#xff0c;也可能随项目进展而增加或减少。尽管项目团队成员被分…

Mysql列的类型定义(二进制类型)

文章目录 前言一、类型图二、类型 1.BINARY和VARBINARY2.BIT类型3.BLOB类型三、实战建议总结 前言 二进制数据和文本数据在mysql 中的最大区别在于&#xff1a; 二进制类型存储原始的二进制数据(如图片&#xff0c;视频&#xff0c;exe文件等)。文本类型(TEXT)用来存储字符字…

【13】SCI易中期刊推荐——计算机工程 | 电子与电气(中科院4区)

💖💖>>>加勒比海带,QQ2479200884<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉…

【嵌入式】HC32F定时器PWM输出+PAC芯片实现模拟DA输出

目录 一 项目背景 二 原理说明 三 设计实现——定时器初始化 四 设计实现——PWM输出 五 梳理总结 一 项目背景 目前使用了TI的DAC芯片DAC7311&#xff0c;将MCU的4-20/0-20数据转化电压信号&#xff0c;经由一系列电路&#xff0c;最终输出4-20/0-20mA电流输出。 但是限于…

执行composer update报错(Segmentation fault php “${dir}/composer.phar“ “$@“)

在php项目中执行composer update&#xff0c;出现如图报错 可在php.ini文件中开启xdebug扩展&#xff0c;即可更新成功

(数字图像处理MATLAB+Python)第六章图像平滑-第二节:频域平滑滤波

文章目录 一&#xff1a;理想低通滤波&#xff08;1&#xff09;概述&#xff08;2&#xff09;程序 二&#xff1a;巴特沃斯低通滤波&#xff08;1&#xff09;概述&#xff08;2&#xff09;程序 三&#xff1a;指数低通滤波&#xff08;1&#xff09;概述&#xff08;2&…

Day1_vue集成elementUI主体布局

本次&#xff0c;将从0开始带你手撸一套SpringBootVue后台管理系统 从前端到后端&#xff0c;手把手搭建&#xff0c;方便学习从0学会基础实战&#xff01;&#xff01;&#xff01; 目录 软件版本 前端开发环境安装&#xff1a; vue-cli安装 : npm设置淘宝镜像加速: 创建v…

vue2+vue3——1~35

vue2vue3 尚硅谷vue2vue2 课程简介【02:24】vue2 Vue简介【17:59】vue2 Vue官网使用指南【14:07】vue2 搭建Vue开发环境【13:54】vue2 Hello小案例【22:25】了解&#xff1a; 不常用常用&#xff1a;id 更常用 简单class 差值总结vue 实例vue 模板 &#xff1a; 先 取 &#xf…

【香橙派+DHT11】香橙派(全志H616)+ DHT11温湿度传感器的驱动教程

目录 一、前言产品概述特点数据传送逻辑DHT11通信时序 二、代码GPIO初始化起始信号读取数据整体代码执行结果 一、前言 最近写DHT11的代码到香橙派&#xff08;全志H616&#xff09;上&#xff0c;发现网上案例基本上都是树莓派DHT11的居多&#xff0c;香橙派的少&#xff0c;…

Linux进程通信:无名管道

进程通信目的&#xff1a; &#xff08;1&#xff09;数据传输&#xff1a;进程间数据传输&#xff1b; &#xff08;2&#xff09;通知事件&#xff1a;一个进程向另一个或一组进程发送消息&#xff0c;通知某个事件的发生&#xff08;如子进程终止时需通知父进程&#xff0…