使用poi,通过重写render对表格进行处理

导入POI依赖

		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.14</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>3.14</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml-schemas</artifactId>
			<version>3.14</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-scratchpad</artifactId>
			<version>3.14</version>
		</dependency>

初始word

在这里插入图片描述

废话不说,代码走起

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.policy.DynamicTableRenderPolicy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@SuppressWarnings("unused")
public class POITest {


    public static void main(String[] args) throws IOException {
        //填写数据
        List<Person> pList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            String anInt = String.valueOf(new Random().nextInt(10));
            String name = "阿恺" + i;
            String sex = i % 2 == 0 ? "男" : "女";
            String phone = anInt + anInt + anInt + anInt + anInt + anInt + anInt + i;
            String mail = anInt + anInt + anInt + anInt + anInt + anInt + anInt + i + "@qq.com";
            Person person = new Person(String.valueOf(i), name, sex, phone, mail);
            pList.add(person);
        }
        //通过性别分组
        Map<String, List<Person>> collect = pList.stream().collect(Collectors.groupingBy(Person::getSex));
        //通过RowRenderData去构建每行数据
        List<RowRenderData> rList = new ArrayList<>();
        //建好准备分类的RowRenderData数据
        Map<String, List<RowRenderData>> rm = new HashMap<>();
        collect.forEach((x, y) -> {
            List<RowRenderData> rl = new ArrayList<>();
            y.stream().forEach(e -> {
                RowRenderData rrd = RowRenderData.build(e.id, e.name, e.sex, e.phone, e.mail);
                rl.add(rrd);
            });
            rm.put(x, rl);
        });
        Map<String, Object> map = new HashMap<>();
        //放入解析模板的数据
        map.put("sex", rm);
        //通过Configure.ConfigureBuilder调用DynamicTableRenderPolicy接口重写render方法
        Configure.ConfigureBuilder config = Configure.newBuilder();
        config.bind("sex", new DynamicTableRenderPolicy() {
            @Override
            public void render(XWPFTable table, Object o) {
                //格式转化
                Map<String, List<RowRenderData>> rm = (Map<String, List<RowRenderData>>) o;
                List<RowRenderData> girl = rm.get("女");
                for (int i = 0; i < girl.size(); i++) {
                    //表格中有一行就,第一行就不需要新建了
                    if (i != 0) {
                        //没有行就新增一行数据
                        XWPFTableRow insertNewTableRow = table.insertNewTableRow(i + 2);
                        for (int j = 0; j < 5; j++) {
                            //根据需求自己选择几列:i就是列
                            insertNewTableRow.createCell();
                        }
                        for (int j = 0; j < 5; j++) {
                            //插入数据到每个单元格
                            //可以自行debug,查看RenderData中数据
                            table.getRow(i + 2).getCell(j).setText(girl.get(i).getCellDatas().get(j).getRenderData().getText());
                        }
                        /**
                         * 合并单元格
                         * mergeCellsHorizonal(XWPFTable table, int row, int fromCol, int toCol)
                         * row:哪一行
                         * fromCol:从哪开始
                         * toCol:到哪结束
                         * 注意:fromCol到toCol区间是左闭右闭
                         */
//                        TableTools.mergeCellsHorizonal(table, i+2, 2, 3);
                    }
                }
                List<RowRenderData> man = rm.get("男");
                for (int i = 0; i < girl.size(); i++) {
                    //表格中没有一行数据
                    //没有行就新增一行数据
                    XWPFTableRow insertNewTableRow = table.insertNewTableRow(i + 5);
                    for (int j = 0; j < 5; j++) {
                        //根据需求自己选择几列:i就是列
                        insertNewTableRow.createCell();
                        //插入数据到每个单元格
                        //可以自行debug,查看RenderData中数据
                        table.getRow(i + 2).getCell(j).setText(girl.get(i).getCellDatas().get(j).getRenderData().getText());

                    }
                }
            }
        });
        //获取resources下的docx资源包的输入流
        InputStream resourceAsStream = new FileInputStream(new File("C:/Users/11142/Desktop/test.docx"));
        XWPFTemplate render = XWPFTemplate.compile(resourceAsStream, config.build()).render(map);
        FileOutputStream outputStream = new FileOutputStream(new File("C:/Users/11142/Desktop/out_template.docx"));
        render.write(outputStream);
        outputStream.flush();
        outputStream.close();
        render.close();
    }
}

class Person {
    public String id;
    public String name;
    public String sex;
    public String phone;
    public String mail;

    public Person(String id, String name, String sex, String phone, String mail) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.phone = phone;
        this.mail = mail;
    }

    public String getSex() {
        return this.sex;
    }
}

可能会有一丢丢多,如果有大佬可以指正,欢迎评论区留言

出问题啦,不过项目中亲测可以

报错:Exception in thread "main" java.lang.IncompatibleClassChangeError: Found interface org.apache.poi.util.POILogger, but class was expected
这个错误说是POI的jar包版本问题,具体可以查看

结果(按照项目中走法)

按照项目中的走法,最终结果就是这样子啦

踩过的坑

1.千万要注意下{{sex}}所放位置,那里相对于来说是0
在这里插入图片描述
2.最好使用.doxc做模板,不然可能会报错,这个还有待研究
在这里插入图片描述

总结一下

1.使用steam流去进行分组,第一次用,用起来还不错的样子
在这里插入图片描述
通过函数式表达式根据性别分组
2.对表格单元格的行合并以及增加一行、多列和赋值
在这里插入图片描述

在这里插入图片描述

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值