使用POI-tI实现数据导出到word之快速入门

使用POI-tI实现数据导出到word之快速入门

因为POI-ti的不同版本的变动比较明显,所以以下都是使用1.9.1版本,本篇文章只针对快速使用POI-ti实现数据导出功能,而数据导出功能的实现,基本上都是依赖于各种各样的标识符,所以,本片文章旨在搞懂常见标识符的使用。POI-ti的使用总体分为三部分:①自定义文档模板;②编译模板+数据填充;③数据渲染;文档模板中,POI-ti默认的标识符都是以 {{ 开头,并以 }} 结尾的。

注意:以下标签中的var是自定义的,但是必须保证要与数据填充的变量名对应上。

引入依赖
<!--poi-tl-->
<dependency>
    <groupId>com.deepoove</groupId>
    <artifactId>poi-tl</artifactId>
    <version>1.9.1</version>
</dependency>
<!--hutool工具类-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.18</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-core</artifactId>
    <version>5.8.18</version>
</dependency>
文本标签

标识符:{{var}}

文档模板(保存为docx文件)

在这里插入图片描述

模板编译

模板编译的操作首先执行,且只能执行一次,是公用的;

XWPFTemplate template = null;
//方式1:加载模板文件
File file = new File("C:templates\\poi\\模板.docx");
template = XWPFTemplate.compile(file);
//方式2:加载指定路径对应的文件
template = XWPFTemplate.compile("C:templates\\poi\\模板.docx"");
//方式3:加载IO输入流
InputStream is =ResourceUtil.getResourceObj("模板.docx").getStream();
template = XWPFTemplate.compile(is); //加载IO流文件的方式,是从classpass路径开始找;          
数据填充
String:直接赋值
//准备参数(普通参数建议使用map装载)
HashMap<String, Object> map = new HashMap<>();
map.put("name", "张三");
map.put("gender", "男");
map.put("age", 18);
map.put("collect", "信息工程学院");
map.put("major", "计算机应用");
map.put("xl", "本科");
map.put("phone", "17788899900");
TextRenderData:可以指定文本的样式
TextRenderData textRenderData = new TextRenderData();
textRenderData.setText("信息工程学院");
Style style = Style.builder()
    .buildFontFamily("微软雅黑")
    .buildFontSize(10)
    .buildColor("7F7F7F")
.build();
textRenderData.setStyle(style);
map.put("collect", textRenderData);
数据渲染

模板编译的操作最后执行,且只能执行一次,是公用的;

template.render(map);
图片标签

标识符:{{@var}}

文档模板

在这里插入图片描述

数据填充
//方式1:直接传递图片地址
put("photo", "C:\\logo.png"); //绝对地址
put("photo", "https://img.shields.io/badge/jdk-1.6%2B-orange.svg"); //网络地址

//方式2:使用Pictures构建
put("photo", Pictures.ofLocal("C:\\logo.png").size(120, 120).create()); //绝对路径
put("photo", Pictures
    .ofStream(new FileInputStream("C:\\logo.jpeg"), PictureType.JPEG)
  	.size(100, 120)
    .create()
); //IO流
put("photo", Pictures
    .ofUrl("http://deepoove.com/images/icecream.png")
  	.size(100, 100)
    .create()
); //网络地址
表格标签

标识符:{{#var}}

文档模板

在这里插入图片描述

数据填充
方式1:使用工厂 Tables 、 Rows 和 Cells 构建表格模型
//举例:第0行居中且背景为蓝色的表格
RowRenderData row0 = Rows.of("姓名", "学历").textColor("FFFFFF")
      .bgColor("4472C4").center().create();
RowRenderData row1 = Rows.create("李四", "博士");
put("table", Tables.create(row0, row1));
方式2:使用TableRenderData构建

注意:这种方式比较麻烦,在POI-ti1.5的版本时还比较好,使用POI-ti1.9版本时,就变得非常麻烦,这里不做演示

上面三种标签使用的完整代码

注意:这里是将数据输出到word文件并下载的方式

public class Test{
	public void test(HttpServletResponse response) {
        Resource resource = null;
        InputStream is = null;
        ServletOutputStream sos = null;
        XWPFTemplate template = null;
        try {
            //1,获取模板文件
            resource = ResourceUtil.getResourceObj("templates/模板.docx");
            is = resource.getStream();
            //2,编译模板
            template = XWPFTemplate.compile(is);
            //3,准备参数(普通参数建议使用map装载)
            HashMap<String, Object> map = new HashMap<>();
			map.put("name", "张三");
			map.put("gender", "男");
			map.put("age", 18);
			map.put("collect", "信息工程学院");
			map.put("major", "计算机应用");
			map.put("xl", "本科");
			map.put("phone", "17788899900");
            map.put("photo", Pictures.ofUrl("http://deepoove.com/images/icecream.png", PictureType.PNG).size(100, 100).create());
            RowRenderData row0 = Rows.of("姓名", "学历").textColor("FFFFFF")
                    .bgColor("4472C4").center().create();
            RowRenderData row1 = Rows.create("李四", "博士");
            map.put("table", Tables.create(row0, row1));

            //4,数据渲染
            template.render(map);
            //5,设置响应参数
            response.setContentType("application/vnd.ms-word"); //数据类型
            response.setCharacterEncoding("utf-8"); //编码格式
            //如果响应中带有附件,需要设置下面这行参数
            response.setHeader("Content-disposition", "attachment; filename="
                    //ISO-8859-1适用范围比UTF-8更广泛,但自身无法显示中文,需要配合其他编码集使用,如UTF-8
                    + new String(resource.getName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); //附件名称
            sos = response.getOutputStream();
            //6,输出
            template.writeAndClose(sos); //IO流
//            template.writeToFile(""); //输出到文件
        } catch (IOException e) {
            e.printStackTrace();
        }
}
列表标签

标识符:{{*var}}

文档模板

在这里插入图片描述

数据填充
put("hobby", Numberings.create("唱","跳","rap"));
区块对

标识符:{{?var}} … {{/var}}

两个标签之间是其他标识符,这种方式的实现情况有很多种,常用的就两种:标签内的其他标签值为空或条件为false时,不会填充该标签;标签内的数据可以是一条也可以是集合;

注意:这种方式必须是使用模板类进行填充,不能使用Map;

文档模板

在这里插入图片描述

代码
模板类
public class info {
    private String school;
    private String addr;
    private List<User> users;
    //get和set方法...
}
public class User{
    private string name;
    private Integer age;
    private Character gender;
    //get和set方法...
}
方法实现
Info data = new Info();
public void test(HttpServletResponse response) {
        Resource resource = null;
        InputStream is = null;
        ServletOutputStream sos = null;
        XWPFTemplate template = null;
        try {
            sos = response.getOutputStream();
            //1,获取模板文件
            resource = ResourceUtil.getResourceObj("templates/模板.docx");
            is = resource.getStream();
            //2,编译模板
            template = XWPFTemplate.compile(is);
            //3,准备参数(普通参数建议使用map装载)
            data.setSchool("xx大学");
            TextRenderData renderData = new TextRenderData("xx省。。。");
            Style style = Style.builder().buildFontSize(10).buildColor("7F7F7F").buildFontFamily("微软雅黑").build();
            renderData.setStyle(style);
            data.setAddr(renderData.getText());
            ArrayList<User> list = new ArrayList<>();
            User u1 = new User();
            u1.setName("张三");
            u1.setAge(20);
            u1.setGender('男');
            TextRenderData hobby = new TextRenderData("唱,跳,rap");
            hobby.setStyle(style);
            u1.setHobby(Numberings.of(hobby, hobby, hobby).create());
            User u2 = new User();
            u2.setName("张三");
            u2.setAge(20);
            u2.setGender('男');
            TextRenderData hobby2 = new TextRenderData("唱,跳,rap");
            hobby.setStyle(style);
            u2.setHobby(Numberings.of(hobby2, hobby2, hobby2).create());
            list.add(u1);
            list.add(u2);
            list.add(u1);
            list.add(u2);
            data.setUsers(list);
            //4,数据渲染
            template.render(data);
            //5,设置响应参数
            response.setContentType("application/vnd.ms-word"); //数据类型
            response.setCharacterEncoding("utf-8"); //编码格式
            //如果响应中带有附件,需要设置下面这行参数
            response.setHeader("Content-disposition", "attachment; filename="
                    //ISO-8859-1适用范围比UTF-8更广泛,但自身无法显示中文,需要配合其他编码集使用,如UTF-8
                    + new String(resource.getName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); //附件名称

            //6,输出并关闭
            template.writeAndClose(sos); //IO流
//            template.writeToFile(""); //输出到文件
        }
嵌套标签

标识符:{{+var}}

注意:这种标签必须要有两个文档模板,一个是用于数据展示的主模板;一个是数据填充的子模板;

文档模板
主模板

在这里插入图片描述

子模板

在这里插入图片描述

代码
public void test(HttpServletResponse response) {
        Resource resource = null;
        InputStream is = null;
        ServletOutputStream sos = null;
        XWPFTemplate template = null;
        try {
            sos = response.getOutputStream();
            //1,获取模板文件
            resource = ResourceUtil.getResourceObj("templates/father.docx");
            is = resource.getStream();
            //2,编译模板
            template = XWPFTemplate.compile(is);
            //3,准备参数(普通参数建议使用map装载)
            Map<String,Object> map=new HashMap<>();
            map.put("school","xx大学");
            map.put("addr","xx省。。。");
            ArrayList<User> list = new ArrayList<>();
            User u1 = new User();
            u1.setName("张三");
            u1.setAge(20);
            u1.setGender('男');
            User u2 = new User();
            u2.setName("张三");
            u2.setAge(20);
            u2.setGender('男');
            list.add(u1);
            list.add(u2);
            list.add(u1);
            list.add(u2);
            InputStream stream = ResourceUtil.getResourceObj("templates/sub.docx").getStream();
            map.put("users",Includes.ofStream(stream).setRenderModel(list).create());
            //4,数据渲染
            template.render(map);
            //5,设置响应参数
            response.setContentType("application/vnd.ms-word"); //数据类型
            response.setCharacterEncoding("utf-8"); //编码格式
            //如果响应中带有附件,需要设置下面这行参数
            response.setHeader("Content-disposition", "attachment; filename="
                    //ISO-8859-1适用范围比UTF-8更广泛,但自身无法显示中文,需要配合其他编码集使用,如UTF-8
                    + new String(resource.getName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); //附件名称

            //6,输出并关闭
            template.writeAndClose(sos); //IO流
//            template.writeToFile(""); //输出到文件
        }

至此,使用POI-ti导出数据到word的快速入门就结束了。。。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中使用poi-tl库来导出带有合并列的Word表格并下载,您可以按照以下步骤操作: 1. 首先,确保您的Spring Boot项目中已经添加了poi-tl的依赖。您可以在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.6.0</version> </dependency> ``` 2. 创建一个Controller来处理导出请求。例如,创建一个名为WordExportController的类,并添加一个处理导出请求的方法。 ```java import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.data.*; import com.deepoove.poi.util.BytePictureUtils; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.apache.poi.xwpf.usermodel.XWPFTableRow; import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; @Controller public class WordExportController { @GetMapping("/export") public ResponseEntity<InputStreamResource> exportWord() throws IOException { // 创建一个数据模型 List<List<String>> tableData = new ArrayList<>(); tableData.add(createRow("Merged Cells", "Cell 3")); tableData.add(createRow("Cell 4", "Cell 6")); // 使用poi-tl的XWPFTemplate来生成Word文档 XWPFTemplate template = XWPFTemplate.compile("templates/template.docx").render( new DataTable(tableData) .setHeader(createRow("Header 1", "Header 2")) .setCellWidth(2000) // 设置单元格宽度 .setHeaderCellStyle(new CellStyle().setBold(true).setColor("FFFFFF").setBgColor("336699")) .setOddRowCellStyle(new CellStyle().setColor("FFFFFF").setBgColor("99CCFF")) .setEvenRowCellStyle(new CellStyle().setColor("FFFFFF").setBgColor("CCEEFF")) ); // 将生成的Word文档转换为字节数组 ByteArrayOutputStream out = new ByteArrayOutputStream(); template.write(out); byte[] documentBytes = out.toByteArray(); // 设置下载响应的头信息 HttpHeaders headers = new HttpHeaders(); headers.setContentDispositionFormData("attachment", "merged_table.docx"); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); // 创建一个包含Word文档字节数组的InputStreamResource InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(documentBytes)); // 返回响应实体 return ResponseEntity.ok() .headers(headers) .body(resource); } private List<String> createRow(String cell1, String cell2) { List<String> row = new ArrayList<>(); row.add(cell1); row.add(cell2); return row; } } ``` 3. 在resources目录下创建一个名为template.docx的Word模板文件。在模板文件中,您可以根据自己的需求设置表格样式和内容。 4. 启动您的Spring Boot应用程序,并访问导出请求的URL(例如:http://localhost:8080/export)。将会自动下载名为merged_table.docx的Word文档,其中包含合并列的表格。 请确保按照您的需求修改代码,并根据模板文件的位置进行相应的调整。 希望对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值