springboot使用easypoi通过使用模板导出文件

第一步:导入poi以及easypoi的maven坐标

首先,easypoi是依赖于Apache的poi实现的,因此需要先引入poi

<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>4.1.2</version>
</dependency>
<!--xlsx格式excel依赖包-->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>4.1.2</version>
</dependency>

其次引入easypoi
maven项目引入:

        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>3.1.0</version>
        </dependency>

springboot项目引入:

<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-spring-boot-starter</artifactId>
    <version>4.4.0</version>
</dependency>

第二步:编写后台代码

我后台使用的是springboot

方式一:此种方式比较简单,直接写入模板的地址,使用WordExportUtil就可以直接拿到带有数据的模板文档。

注意:但是有个坑,就是一旦更换模板,项目需要重新启动才能刷新模板。意思就是你第一次使用模板通过此程序时,它会对模板进行缓存,等你下次再通过时会使用缓存中的模板来进行输出,因此在模板不改变的情况下使用此种方式还算是比较简单一些。

    @GetMapping("/exportByEasypoi")
    public void exportByEasypoi() throws Exception {
        ArrayList<User> users = new ArrayList<User>();
        User user = new User();
        user.setId("1");
        user.setName("小张");
        user.setAge("18");
        user.setTel("138383838383");
        users.add(user);

        users.add(new User("2","小王","22","384324324"));
        users.add(new User("3","小3","23","3843243224"));
        users.add(new User("4","小4","24","11122224"));
        users.add(new User("5","小5","25","14654324324"));

        File fileOut = new File("C:\\Users\\Administrator\\Desktop\\test\\target.docx");
        OutputStream outputStream = new FileOutputStream(fileOut);

        Map<String,Object> data = new HashMap();
        data.put("data",users);

        XWPFDocument document = WordExportUtil.exportWord07("C:\\Users\\Administrator\\Desktop\\test\\template.docx", data);
        document.write(outputStream);
        outputStream.close();
    }
方拾二:这种方式就是自定义加载模板的方式,让你的模板可以随时改变,并且每次导出倒是按照你地址的最新形态来给你导出
@GetMapping("/exportByEasypoi")
    public void exportByEasypoi() throws Exception {
        ArrayList<User> users = new ArrayList<User>();
        User user = new User();
        user.setId("1");
        user.setName("小张");
        user.setAge("18");
        user.setTel("138383838383");
        users.add(user);

        users.add(new User("2","小王","22","384324324"));
        users.add(new User("3","小3","23","3843243224"));
        users.add(new User("4","小4","24","11122224"));
        users.add(new User("5","小5","25","14654324324"));

        File fileIn = new File("C:\\Users\\Administrator\\Desktop\\test\\template.docx");
        File fileOut = new File("C:\\Users\\Administrator\\Desktop\\test\\target.docx");
        OutputStream outputStream = new FileOutputStream(fileOut);

        Map<String,Object> data = new HashMap();
        data.put("data",users);
        InputStream inputStream = new FileInputStream(fileIn);
        MyXWPFDocument sourceDocument = new MyXWPFDocument(inputStream);
        WordExportUtil.exportWord07(sourceDocument, data);
        sourceDocument.write(outputStream);
        
        outputStream.close();
    }

导出图片到模板中

ImageEntity imageEntity = new ImageEntity();
imageEntity.setUrl(imageUrl);
imageEntity.setHeight(384);
imageEntity.setWidth(676);
imageEntity.setType(ImageEntity.URL);
previewContractObj.setImage(imageEntity);
data.put("previewContractObj", previewContractObj);

图片的长宽必须设置,这里设置为多少,导出时显示的大小就是多少
模板直接引用:
在这里插入图片描述

可能遇到的问题:

在这里插入图片描述
我这里这个问题的原因是因为文档格式不正确,原来是doc格式的Word,强行改后缀换成docx格式的文件就会报错
修改:打开文件,使用另存为,把文件另存为想要的格式就可以了!

另外,值得一提的是,easypoi对doc文件的格式支持不是很好,所以使用doc格式的Word进行导出会有各种问题
在这里插入图片描述

第三步:编辑模板

在这里插入图片描述
注意:

  • 模板这里有个小坑,就是当传入的值为数组时,需要遍历输出必须要放到表格里easypoi才能完整的遍历,对于表格以外的位置支持的并不是很好。
  • 模板遍历时,解析的数组子对象默认为“t”。直接用“t”来引用就可以了。也可以在后面自定义

以下就是模板常用的指令:
空格分割
三目运算 {{test ? obj:obj2}}
n: 表示 这个cell是数值类型 {{n:}}
le: 代表长度{{le:()}} 在if/else 运用{{le:() > 8 ? obj1 : obj2}}
fd: 格式化时间 {{fd:(obj;yyyy-MM-dd)}}
fn: 格式化数字 {{fn:(obj;###.00)}}
fe: 遍历数据,创建row
!fe: 遍历数据不创建row
$fe: 下移插入,把当前行,下面的行全部下移.size()行,然后插入
#fe: 横向遍历
v_fe: 横向遍历值
!if: 删除当前列 {{!if:(test)}}
单引号表示常量值 ‘’ 比如’1’ 那么输出的就是 1
&NULL& 空格
&INDEX& 表示循环中的序号,自动添加
]] 换行符 多行遍历导出
sum: 统计数据
cal: 基础的±X% 计算
dict: 字典
i18n: 国际化

第四步 运行访问

由于这里只需要后端处理,因此我就不写前端了,直接用postman访问就可以了。把文件写到本地文件夹进行预览,如图所示:
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐