poi-tl word模版生成、动态表格、坑点合集

一、配置

1、导入依赖

java 复制代码
  <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.10.0</version>
   </dependency>

apache poi版本要对应

java 复制代码
 <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
</dependency>
<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
</dependency>

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

2、模版存放问题

(1)如果你的模版存放在你c盘之类的,是不用再去配置maven文件

(2)如果你的是要发布到inux的spring项目,或者为了可用性,将模版存放在resource文件夹下面,这个时候就要配置maven文件,因为打jar包的时候,会将你的word文件默认压缩,通过maven构建文件不对后缀docx的文件压缩过滤,这样文件打包之后就不会损坏

java 复制代码
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <version>2.6</version>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <nonFilteredFileExtensions>
                        <nonFilteredFileExtension>docx</nonFilteredFileExtension>
                    </nonFilteredFileExtensions>
                </configuration>
            </plugin>

        </plugins> 
    </build> 

二、案例

1、普通模版

新建一个word文档,{{}}这种格式,里面放替换的字母,将map集合替换内容设置好,交给poi-tl渲染。

word模版

以下就是普通模版生成的三个方法,其中一个为主方法,调用生成。如果需要字节流转成mutipartfile需要导入mock依赖

java 复制代码
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-mock</artifactId>
            <version>2.0.8</version>
        </dependency>
java 复制代码
public class WordTemplateUtils {  


    public static void main(String[] args) {
        Map<String, Object> templateMap = new HashMap<>();
        templateMap.put("Year", "2023年");
        templateMap.put("HqCompany","测试名单");
        exportWord(templateMap);
    }


/**
     * 生成word模版
     *
     * @param data
     * @return
     */
    public static MultipartFile exportWord(Map<String, Object> data) {
        MultipartFile multipartFile = null;
        ByteArrayOutputStream ostream = null;
        XWPFTemplate template = null;
        try {
            //获取模板
            template = getWordTemplate(data);
            ostream = new ByteArrayOutputStream();
            // 将模板输出到字节流
            template.write(ostream);//这里还有一个方法是template.writeToFile("");可以直接填写本地文件路径
            byte[] fileBytes = ostream.toByteArray();
            String newFileName = "测试" + data.get("Year") + "年生成文件.docx";
            //转成可上传的文件(作者这里是为了上传到服务器转换成mutipartFile)
            multipartFile = new MockMultipartFile(newFileName, newFileName,
                    "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fileBytes);
        } catch (IOException e) {
            log.error("模版1导出异常");
        } finally {
            //关闭流
            IOUtils.close(ostream);
            IOUtils.close(template);
        }
        return multipartFile;
    }

    /**
     * 获取普通word模版渲染
     *
     * @param data
     * @return
     * @throws IOException
     */
    private static XWPFTemplate getWordTemplate(Map<String, Object> data) {
        //获取模板的输入流,读取resource里面的template文件夹里的word1.docx
        ClassPathResource tempFileResource = new ClassPathResource("template/" + "word1.docx");
        InputStream stream = null;
        try {
            stream = tempFileResource.getInputStream();
        } catch (IOException e) {
            log.error("获取模版失败!");
        }
        ConfigureBuilder builder = Configure.builder();
        builder.useSpringEL();
        XWPFTemplate template = XWPFTemplate.compile(stream, builder.build()).render(data);
        return template;
    }

}

2、带有表格的模版

word模版

代码:

java 复制代码
  public class WordTemplateUtils {
  /**
     * 生成word表格模版
     *
     * @param data
     * @return
     */
    public static MultipartFile exportWordTable(Map<String, Object> data) {
        //模板地址
        ClassPathResource tempFileResource = new ClassPathResource("template/" + "word2.docx");
        // 行循环实例
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        //这里可以指定一个config类,用来指定一些规则,也可以改变模板中{{}}的这种格式
        MultipartFile multipartFile = null;
        XWPFTemplate compile = null;
        File file = null;
        ByteArrayOutputStream ostream = null;
        try {
            //lists绑定对象
            Configure config = Configure.builder()
                    .bind("lists", policy).build();
            compile = XWPFTemplate.compile(tempFileResource.getInputStream(), config);
            compile.render(data);
            ostream = new ByteArrayOutputStream();
            compile.write(ostream);
            byte[] fileBytes = ostream.toByteArray();
            String newFileName = "测试" + data.get("Year") + "年企业名单.docx";
            multipartFile = new MockMultipartFile(newFileName, newFileName,
                    "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fileBytes);
        } catch (IOException e) {
            log.error("模版导出失败");
        } finally {
            IOUtils.close(ostream);
            IOUtils.close(compile);
        }
        return multipartFile;
    }


    public static void main(String[] args) {
        Map<String, Object> templateMap = new HashMap<>();
        //建立公司对象集合
        List<Company> companyList=new ArrayList();
        Company company1=new Company();
        company1.setIndex(1);
        company1.setEnterpriseName("测试1");
        Company company2=new Company();
        company1.setIndex(2);
        company1.setEnterpriseName("测试2");
        companyList.add(company1);
        //放进模版集合
        templateMap.put("Year", "2023年");
        templateMap.put("lists","测试名单");
        exportWordTable(templateMap);
    }

}
相关推荐
Freak嵌入式14 分钟前
全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类
java·开发语言·数据结构·python·接口·抽象基类
前端小马24 分钟前
解决IDEA出现:java: 程序包javax.servlet不存在的问题
java·servlet·intellij-idea
IH_LZH1 小时前
Broadcast:Android中实现组件及进程间通信
android·java·android studio·broadcast
去看全世界的云1 小时前
【Android】Handler用法及原理解析
android·java
.Net Core 爱好者1 小时前
Redis实践之缓存:设置缓存过期策略
java·redis·缓存·c#·.net
晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑1 小时前
苍穹外卖学习笔记(五)
java·笔记·学习
码上一元1 小时前
【百日算法计划】:每日一题,见证成长(017)
java·算法
用生命在耍帅ㅤ1 小时前
java spring boot 动态添加 cron(表达式)任务、动态添加停止单个cron任务
java·开发语言·spring boot
学java的小菜鸟啊1 小时前
第五章 网络编程 TCP/UDP/Socket
java·开发语言·网络·数据结构·网络协议·tcp/ip·udp
zheeez1 小时前
微服务注册中⼼2
java·微服务·nacos·架构