使用POI-tl 导出word文档 包含表格

710 阅读2分钟

记一次使用poi-tl导出word,包含表格,表格里面图片

主要问题:导出的word里面包含大量图片,导出总是不显示里面的图片信息。 解决方案:最后选择把图片转为byte[],一个个放入PictureRenderData里面,下方附源码 需要导出的word如下图: 在这里插入图片描述

  • 1.附 poi-tl官网(deepoove.com/poi-tl/#) 导入依赖可以查看官网,这里不在叙述。 本次导出word使用了里面的一个 LoopRowTableRenderPolicy(10.2 表格行循环的特定场景插件)。

  • 2.导出模板 选用的是docx 需要注意的是,我把他放在了resource/wordTemplate/user.docx下面,这个地方导出的时候getResourceAsStream("wordTemplate/user.docx")。 模板如下: 在这里插入图片描述

  • 3.实体类

@Data
@NoArgsConstructor
public class Grade {
    private String title;
    private String grade;
    private String classes;
    private String teacher;
    private List<Student> studentList;
}
@Data
@NoArgsConstructor
@Accessors(chain = true)
public class Student {
    private String name;
    private String gender;
    private LocalDateTime time;
    private PictureRenderData photo;
}
  • 4业务代码
    @ApiOperation(value = "导出word")
    @PostMapping(value = "student/export/word")
    public void exportStudent(HttpServletResponse response) throws IOException {
        //存放要填充的数据
        Grade grade = new Grade();
        grade.setGrade("一年级");
        grade.setClasses("一年级");
        grade.setTeacher("老李");
        grade.setTitle("一年级导出word");
        List<Student> students=new ArrayList<>();
        students.add(new Student().setName("老赵").setTime(LocalDateTime.now()).setGender("男"));
        students.add(new Student().setName("老李").setTime(LocalDateTime.now()).setGender("男"));
        students.add(new Student().setName("老胡").setTime(LocalDateTime.now()).setGender("男"));
        students.add(new Student().setName("老张").setTime(LocalDateTime.now()).setGender("男"));
        //自己的图片链接地址,根据自己业务需要,可能需要在下面students 里面一条一条拿
        String url = "xxxx/xxxx/xxx.";
        students.forEach(student -> {
        	//	HttpDownloader hutool的转为字节 
            byte[] imageStream = HttpDownloader.downloadBytes(url);
            Pictures.PictureBuilder pictureBuilder = Pictures.ofBytes(imageStream);
            PictureRenderData pictureRenderData = pictureBuilder.size(100, 100).create();
            student.setPhoto(pictureRenderData);
        });
        grade.setStudentList(students);

		//以上自己业务代码 返回的实体类 放入render,  XWPFTemplate.compile(in, config).render(grade) 
        //这是第一条说的表格行循环的插件,可以参考官网
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure config = Configure.builder()
                .bind("studentList", policy)
                .bind("photo", new PictureRenderPolicy())
                .build();
        //getResourceAsStream 里面是自己的模板位置
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("wordTemplate/user.docx");
        assert in != null;
        XWPFTemplate template = XWPFTemplate.compile(in, config).render(grade);
        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment;filename=\"" + System.currentTimeMillis() + ".docx" + "\"");
        OutputStream out = response.getOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(out);
        template.write(bos);
        bos.flush();
        out.flush();
        PoitlIOUtils.closeQuietlyMulti(template, bos, out);
    }

业务代码根据自己的需要去写就行了