java使用easypoi导出为word文档

环境:jdk1.8+springboot2.5.6+easypoi

EasyPoi官网:1. 前言 - Powered by MinDoc (wupaas.com),easypoi的easypoi-spring-boot-starter坐标,这里建议用4.4.0版本,使用官网中的4.0.0需要在yml中额外的配置。这里就使用4.4.0版本了

 
       cn.afterturn
       easypoi-spring-boot-starter
       4.4.0
  

easypoi中的模板指令有

  • 空格分割

  • 三目运算 {{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: 国际化

代码中的word模板和图片位置截图如下

在springboot项目中,在static目录下的图片和视频文件都是可以通过url地址访问的,如果文件在其他位置,就需要我们自己进行静态资源映射的配置,具体看(2条消息) springboot静态资源映射配置_m0_62317155的博客-CSDN博客_springboot静态资源映射配置

java使用easypoi导出为word文档_第1张图片

word模板截图如下所示

这里使用word模板的形式,word模板如下图所示,使用{{}}在word中填写对应的map字段即可,如{{name}}。注意是英文状态下的输入法。这里的文字大小和颜色、字体等可以使用word和wps软件先在模板中设置好。

java使用easypoi导出为word文档_第2张图片

注意上图中的{{$fe: studentList t.name}}这里必须放在表格中,我试过了如果没有放在表格中代码会报错不生效,如果担心这里表格影响,可以使用word软件或者wps将word模板中的表格线去掉即可

https://plus.wps.cn/blog/p35884.html

Java代码

pom.xml


    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.5.6
         
    
    com.example
    wordexport
    0.0.1-SNAPSHOT
    wordexport
    wordexport
    
        1.8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            cn.afterturn
            easypoi-spring-boot-starter
            4.4.0
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    


Controller
package com.example.controller;

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.word.WordExportUtil;
import com.example.entity.Student;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/export")
public class ExportWordController {

    @GetMapping("/exportword/{id}")
    public void exportword(@PathVariable Integer id, HttpServletResponse response) throws Exception {
        // 这里可以通过id查找数据库中保存的信息,这里就不查数据库了,大概数据数据测试就行了
        Student student = new Student();
        student.setId(id);
        student.setName("罗辑");
        student.setSex("男");
        student.setNation("汉族");
        student.setDescribe("我没有太多可说的,只有一个警告:生命从海洋登上陆地是地球生物进化的一个里程碑," +
                "但那些上岸的鱼再也不是鱼了;同样,真正进入太空的人,再也不是人了,所以,人们,当你们打算飞向外太空再也不回头时," +
                "请千万慎重,需付出的代价比你们想象的要大得多。" +
                "我们都是阴沟里的虫子,但总还是得有人仰望星空。" +
                "死亡是一座永恒的灯塔,不管你驶向何方,最终都会朝它转向。一切都将逝去,只有死神永生。");
        student.setResource("翻阅坐标数据是歌者的工作,判断坐标的诚意是歌者的乐趣。");
        // 读取word文档模板
        // File filepath = new File("D:\\private\\javastudaykeshanchu\\javaweb\\wordexport\\src\\main\\resources\\templates\\exportword_template.docx");
        File rootFile = new File((ResourceUtils.getURL("classpath:").getPath()));
        File templateFile = new File(rootFile, "/templates/exportword_template.docx");
        System.out.println(templateFile);
        // 需要将bean转换为map集合
        Map maps = new HashMap<>();
        maps.put("name", student.getName());
        maps.put("sex", student.getSex());
        maps.put("nation", student.getNation());
        maps.put("describe", student.getDescribe());
        maps.put("resource", student.getResource());

        // 写入图片
        ImageEntity imageEntity = new ImageEntity();
        // 这里可以是磁盘地址,也可以是对应的http地址,例如在springboot中static下的图片可以直接通过http的url访问。
        imageEntity.setUrl("http://localhost:8080/img/1.jpg");
        // 这里的宽高必须要设置
        imageEntity.setWidth(500);
        imageEntity.setHeight(300);
        maps.put("photo",imageEntity);

        ImageEntity imageEntity1 = new ImageEntity();
        imageEntity1.setUrl("D:\\private\\javastudaykeshanchu\\javaweb\\wordexport\\src\\main\\resources\\static\\img\\2.jpg");
        imageEntity1.setWidth(500);
        imageEntity1.setHeight(300);
        maps.put("photo1",imageEntity1);

        // 这里以集合List的形式,在word模板中使用模板指令fe:遍历数据,创建row
        List> infoList = new ArrayList<>();
        Map mapObj = null;
        for (int i = 1; i <= 3; i++) {
            mapObj = new HashMap<>();
            ImageEntity imageEntity2 = new ImageEntity();
            // 这里可以是磁盘地址,也可以是对应的http地址,例如在springboot中static下的图片可以直接通过http的url访问。
            imageEntity2.setUrl("http://localhost:8080/img/" + i + ".jpg");
            // 这里的宽高必须要设置
            imageEntity2.setWidth(300);
            imageEntity2.setHeight(200);
            mapObj.put("imgurl",imageEntity2);
            mapObj.put("name", "罗辑" + i);
            infoList.add(mapObj);
        }
        maps.put("studentList", infoList);
        String name = student.getName();
        XWPFDocument word = WordExportUtil.exportWord07(templateFile.getPath(), maps);
        String fileName = "三体资料(" + name + ")详情.docx";
        response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes(), "ISO8859-1"));
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        ServletOutputStream outputStream = response.getOutputStream();
        word.write(outputStream);
        outputStream.close();
        word.close();
    }
}
Entity
package com.example.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private Integer id;
    private String name;
    private String sex;
    private String nation;
    private String describe;
    private String resource;
}

运行结果

在浏览器地址栏输入大概如下的地址http://localhost:8080/export/exportword/1,地址中的id为1是我随便输入的,这里之所以放id是因为在真实的开发中我们可以根据传入的id到对应的数据库表中查找到数据。我在代码中是自己懒得连数据库了,自己造了一个数据。具体看代码就行了。在浏览器输入的地址栏输入http://localhost:8080/export/exportword/1,即可下载一个word文档。将这个word文档打开之后得到如下的结果

java使用easypoi导出为word文档_第3张图片

代码中对应的字段和模板中对应的字段如下

java使用easypoi导出为word文档_第4张图片

最终的结果如下

java使用easypoi导出为word文档_第5张图片

跟前端代码联动

可以通过 window.location.href = "http://localhost:8080/export/exportword/1",调用对应的地址来实现导出word的功能。

使用window.location.href=url,window.open(url)也可以实现文件下载,但下载需要传请求头时,就不适用这种方法了。

参考文章:

(2条消息) vue前端调后台接口下载文件(get,post方法集合)爱写程序的小高的博客-CSDN博客vue调用下载文件接口

(2条消息) 下载Content-Type,Blob type类型汇总_爱写程序的小高的博客-CSDN博客

js下载doxc 文件示例和部分后缀对应的content-type 总结 - 天高任鸟飞吧 - 博客园 (cnblogs.com)





    
    
    
    vue简单页面试验
    
    
    
    
    
    
    
    



    
导出为word 导出为word2 导出为word3 导出为word4

对应的html页面如下,点击对应的按钮就可以实现导出word文档了

java使用easypoi导出为word文档_第6张图片

java使用easypoi导出为word文档_第7张图片

你可能感兴趣的:(spring,boot,java,后端)