结合hutool工具导出多个sheet页

结合hutool工具导出多个sheet页

1.引入所需依赖

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

<!-- 引入hutool依赖 -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-core</artifactId>
    <version>4.6.17</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-poi</artifactId>
    <version>4.6.17</version>
</dependency>

2.创建导出数据封装实体类

这里简单创建两个 实体对象 学生(Student) 和 老师(Teacher) 类

Student

@Date
public class Student {
    @ApiModelProperty(value = "姓名")
    private String name;
    @ApiModelProperty(value = "语文")
    private int chinese;
    @ApiModelProperty(value = "数学")
    private int math;
    @ApiModelProperty(value = "外语")
    private int english;
  
   	public Student() {
    }

    public Student(String name, int chinese, int math, int english) {
        this.name = name;
        this.chinese = chinese;
        this.math = math;
        this.english = english;
    }
}

Teacher

@Date
public class Teacher {
    @ApiModelProperty(value = "姓名")
    private String name;
    @ApiModelProperty(value = "编号")
    private String code;
    @ApiModelProperty(value = "职务")
    private String position;
    @ApiModelProperty(value = "电话")
    private String phone;
    
  	public Teacher() {
    }

    public Teacher(String name, String code, String position, String phone) {
        this.name = name;
        this.code = code;
        this.position = position;
        this.phone = phone;
    }
}

3.创建导出数据页封装对象 SheetDto

/**
 * Excel - Sheet页 数据封装类
 */
public class SheetDTO implements Serializable {

    private static final long serialVersionUID = 1L;
    
    /**
     * sheet页名称
     * */
    private String sheetName;
    
    /** 
     * 字段和别名,如果使用这个,properties 和 titles可以不用处理
     * 如果要求导出字段按集合顺序则需要LinkedHashMap 无要求则用HashMap
     * LinkedHashMap<字段, 别名>  如:LinkedHashMap<"name", "姓名">
     */
    private LinkedHashMap<String, String> fieldAndAlias;
    
    /**
     * 列宽<br/>
     * 设置列宽时必须每个字段都设置才生效(columnWidth.size = fieldAndAlias.size)
     */
    private List<Integer> columnWidth;
    
    /**
     * 数据集 (需要导出的数据集)
     * */
    private Collection<?> collection;
    
    public SheetDTO() {
        
    }
    
    /**
     * 
     * @param sheetName      sheet页名称
     * @param fieldAndAlias  字段和别名
     * @param collection     数据集
     */
    public SheetDTO(String sheetName, LinkedHashMap<String, String> fieldAndAlias, Collection<?> collection) {
        super();
        this.sheetName = sheetName;
        this.fieldAndAlias = fieldAndAlias;
        this.collection = collection;
    }

    public String getSheetName() {
        return sheetName;
    }

    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }

    public Map<String, String> getFieldAndAlias() {
        return fieldAndAlias;
    }

    public void setFieldAndAlias(LinkedHashMap<String, String> fieldAndAlias) {
        this.fieldAndAlias = fieldAndAlias;
    }

    public List<Integer> getColumnWidth() {
        return this.columnWidth;
    }

    public void setColumnWidth(List<Integer> columnWidth) {
        this.columnWidth = columnWidth;
    }

    public Collection<?> getCollection() {
        return collection;
    }

    public void setCollection(Collection<?> collection) {
        this.collection = collection;
    }

}

4.编写工具类Excel导出方法

public class ExcelUtils {
    
    /** 
     * 导出多个 Sheet 页
     * @param response
     * @param sheetList 页数据
     * @param fileName 文件名
     */
    public static void exportExcel(HttpServletResponse response, List<SheetDTO> sheetList, String fileName) {
        ExcelWriter bigWriter = ExcelUtil.getBigWriter();
        // 重命名第一个Sheet的名称,不然会默认多出一个Sheet1的页
        bigWriter.renameSheet(0, sheetList.get(0).getSheetName());
        for (SheetDTO sheetDto : sheetList) {
            // 指定要写出的 Sheet 页
            bigWriter.setSheet(sheetDto.getSheetName());
            List<Integer> columnWidthList = sheetDto.getColumnWidth();
            if (CollectionUtils.isEmpty(columnWidthList) || columnWidthList.size() != sheetDto.getFieldAndAlias().size()) {
                // 设置默认宽度 
                for (int i = 0; i < sheetDto.getFieldAndAlias().size(); i++) {
                    bigWriter.setColumnWidth(i, 25);
                }
            } else {
                // 设置自定义宽度 
                for (int i = 0; i < columnWidthList.size(); i++) {
                    bigWriter.setColumnWidth(i, columnWidthList.get(i));
                }
            }
            // 设置字段和别名
            bigWriter.setHeaderAlias(sheetDto.getFieldAndAlias());
            // 设置只导出有别名的字段
            bigWriter.setOnlyAlias(true);
            // 设置默认行高
            bigWriter.setDefaultRowHeight(18);
            // 一次性写出内容,使用默认样式,强制输出标题
            bigWriter.write(sheetDto.getCollection(), true);
        }
        
        ServletOutputStream out = null;
        try {
            //attachment 弹出下载对话框, inline 则会使用默认浏览器打开文件,不出现弹框(在线预览)
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment;filename=%s", URLEncoder.encode(fileName + ".xlsx", "UTF-8")));
            out = response.getOutputStream();
          	//这里的servlet流会自动关闭, 我们不需要手动自己去关, 否则会报 stream is close错误
            bigWriter.flush(out, true);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭writer,释放内存
            bigWriter.close();
        }
    }
}

5.编写测试方法 简单测试一下

@RestController
@RequestMapping("/test")
public class TestController {


@ApiOperation("导出多页ExcelC功能测试")
@GetMapping("/exportExcel/test")
@ApiImplicatParam(name="token", paramType="header")
public Result exportExcelTest() { 
	List<SheetDTO> exportList = new ArrayList<>();
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = null;
        if(Objects.nonNull(requestAttributes)){
            response = requestAttributes.getResponse();
        }

        //模拟导出的学生成绩信息
        List<Student> cjList = new ArrayList<>();
        cjList.add(new Student("小明",96,98,95));
        cjList.add(new Student("小李",96,97,99));
        cjList.add(new Student("小王",98,97,95));
        cjList.add(new Student("小华",94,99,99));
        cjList.add(new Student("小黑",97,95,99));
        cjList.add(new Student("小羽",97,99,98));

        //模拟导出的教师信息
        List<Teacher> jsList = new ArrayList<>();
        jsList.add(new Teacher("李老师","NO001","语文教师","13647735282"));
        jsList.add(new Teacher("赵老师","NO002","语文教师","13647735283"));
        jsList.add(new Teacher("王老师","NO003","数学教师","13647735284"));
        jsList.add(new Teacher("黄老师","NO004","数学教师","13647735285"));
        jsList.add(new Teacher("张老师","NO005","外语教师","13647735286"));
        jsList.add(new Teacher("刘老师","NO006","外语教师","13647735287"));

  	    //设置需要导出的字段
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        SheetDTO sheetDTO = new SheetDTO();
        map.put("name", "姓名");
        map.put("chinese", "语文成绩");
        map.put("math", "数学成绩");
        map.put("english", "英语成绩");
        sheetDTO.setSheetName("学生成绩");
        sheetDTO.setFieldAndAlias(map);
        sheetDTO.setCollection(cjList);
        exportList.add(sheetDTO);

        LinkedHashMap<String, String> map2 = new LinkedHashMap<>();
        SheetDTO sheetDTO2 = new SheetDTO();
        map2.put("name", "姓名");
        map2.put("code", "编号");
        map2.put("position", "职务");
        map2.put("phone", "电话");
        sheetDTO2.setSheetName("教师信息");
        sheetDTO2.setFieldAndAlias(map2);
        sheetDTO2.setCollection(jsList);
        exportList.add(sheetDTO2);

        ExcelUtils.exportExcel(response, exportList, "师生信息导出");
    }
  
	return Result.SUCCESS();
}
    

6.导出结果

在这里插入图片描述
在这里插入图片描述

从以上结果可以看到导出测试是成功的…自此本次导出工作完成.

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值