Hutool(Excel工具使用)

Hutool(Excel工具使用)

官方文档Hutool

目录:

基本依赖的导入

Writer方法的使用

1.1 写出List数据
1.2 写出Map数据
1.3 写出我们的Bean对象
1.4 自定义Bean的key别名
1.5 写出到IO流
1.6 写出到客户端下载(写出到Servlet)

Writer方法的使用补充

2.1 设置单元格背景色
2.2 自定义字体
2.3 写出多个sheet
2.4 更详细的定义样式

ExcelReader读取Excel、流、工作簿

3.1 常用的读取方式

简单实战

4.1 实现Excel的下载
4.2 实现Excel导入到数据库
4.3 实现Excel的模板从服务器下载到客户端


基本依赖的导入


<!-- 基本依赖包 -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.3.8</version>
</dependency>
<!-- Excel包 -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>

Writer方法的使用



1. 写出List数据


1.1 制造我们的rows集合对象

List<String> row1 = CollUtil.newArrayList("aa", "bb", "cc", "dd");
List<String> row2 = CollUtil.newArrayList("aa1", "bb1", "cc1", "dd1");
List<String> row3 = CollUtil.newArrayList("aa2", "bb2", "cc2", "dd2");
List<String> row4 = CollUtil.newArrayList("aa3", "bb3", "cc3", "dd3");
List<String> row5 = CollUtil.newArrayList("aa4", "bb4", "cc4", "dd4");

List<List<String>> rows = CollUtil.newArrayList(row1, row2, row3, row4, row5);

1.2 将我们的对象写出

//通过工具类创建writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeTest.xlsx");
//通过构造方法创建writer
//ExcelWriter writer = new ExcelWriter("d:/writeTest.xls");

//跳过当前行,既第一行,非必须,在此演示用
writer.passCurrentRow();

//合并单元格后的标题行,使用默认标题样式
writer.merge(row1.size() - 1, "测试标题");
//一次性写出内容,强制输出标题
writer.write(rows, true);
//关闭writer,释放内存
writer.close();

2. 写出Map数据


1.1 制造我们的Map对象

Map<String, Object> row1 = new LinkedHashMap<>();
row1.put("姓名", "张三");
row1.put("年龄", 23);
row1.put("成绩", 88.32);
row1.put("是否合格", true);
row1.put("考试日期", DateUtil.date());

Map<String, Object> row2 = new LinkedHashMap<>();
row2.put("姓名", "李四");
row2.put("年龄", 33);
row2.put("成绩", 59.50);
row2.put("是否合格", false);
row2.put("考试日期", DateUtil.date());

ArrayList<Map<String, Object>> rows = CollUtil.newArrayList(row1, row2);

1.2 写出我们的rows对象

// 通过工具类创建writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeMapTest.xlsx");
// 合并单元格后的标题行,使用默认标题样式
writer.merge(row1.size() - 1, "一班成绩单");
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
// 关闭writer,释放内存
writer.close();

3. 写出我们的Bean对象


1.1 制造我们的Bean数据

TestBean bean1 = new TestBean();
bean1.setName("张三");
bean1.setAge(22);
bean1.setPass(true);
bean1.setScore(66.30);
bean1.setExamDate(DateUtil.date());

TestBean bean2 = new TestBean();
bean2.setName("李四");
bean2.setAge(28);
bean2.setPass(false);
bean2.setScore(38.50);
bean2.setExamDate(DateUtil.date());

List<TestBean> rows = CollUtil.newArrayList(bean1, bean2);

1.2 写出我们的Rows对象

// 通过工具类创建writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeBeanTest.xlsx");
// 合并单元格后的标题行,使用默认标题样式
writer.merge(4, "一班成绩单");
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
// 关闭writer,释放内存
writer.close();

4. 自定义Bean的key别名


// 通过工具类创建writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeBeanTest.xlsx");

//自定义标题别名
writer.addHeaderAlias("name", "姓名");
writer.addHeaderAlias("age", "年龄");
writer.addHeaderAlias("score", "分数");
writer.addHeaderAlias("isPass", "是否通过");
writer.addHeaderAlias("examDate", "考试时间");

// 合并单元格后的标题行,使用默认标题样式
writer.merge(4, "一班成绩单");
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
// 关闭writer,释放内存
writer.close();

5. 写出到IO流


// 通过工具类创建writer,默认创建xls格式
ExcelWriter writer = ExcelUtil.getWriter();
//创建xlsx格式的
//ExcelWriter writer = ExcelUtil.getWriter(true);
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
//out为OutputStream,需要写出到的目标流
writer.flush(out);
// 关闭writer,释放内存
writer.close();

6. 写出到客户端下载(写出到Servlet)


1.1 写出xls

// 通过工具类创建writer,默认创建xls格式
ExcelWriter writer = ExcelUtil.getWriter();
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
//out为OutputStream,需要写出到的目标流

//response为HttpServletResponse对象
response.setContentType("application/vnd.ms-excel;charset=utf-8"); 
//test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
response.setHeader("Content-Disposition","attachment;filename=test.xls"); 
ServletOutputStream out=response.getOutputStream(); 

writer.flush(out, true);
// 关闭writer,释放内存
writer.close();
//此处记得关闭输出Servlet流
IoUtil.close(out);

1.2 写出xlsx

ExcelWriter writer = ExcelUtil.getWriter(true);
writer.write(rows, true);

response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); 
response.setHeader("Content-Disposition","attachment;filename=test.xlsx"); 

writer.flush(out, true);
writer.close();
IoUtil.close(out);

Writer方法的使用补充



1. 设置单元格背景色


// 定义单元格背景色
StyleSet style = writer.getStyleSet();
// 第二个参数表示是否也设置头部单元格背景
style.setBackgroundColor(IndexedColors.RED, false);
Copy to clipboardErrorCopied

2. 自定义字体


ExcelWriter writer = ...;
//设置内容字体
Font font = writer.createFont();
font.setBold(true);
font.setColor(Font.COLOR_RED); 
font.setItalic(true); 
//第二个参数表示是否忽略头部样式
writer.getStyleSet().setFont(font, true);
Copy to clipboardErrorCopied

3. 写出多个sheet


//初始化时定义表名
ExcelWriter writer = new ExcelWriter("d:/aaa.xls", "表1");
//切换sheet,此时从第0行开始写
writer.setSheet("表2");
...
writer.setSheet("表3");
...
Copy to clipboardErrorCopied

4. 更详细的定义样式


在Excel中,由于样式对象个数有限制,因此Hutool根据样式种类分为4个样式对象,使相同类型的单元格可以共享样式对象。样式按照类别存在于StyleSet中,其中包括:

头部样式 headCellStyle
普通单元格样式 cellStyle
数字单元格样式 cellStyleForNumber
日期单元格样式 cellStyleForDate
其中cellStyleForNumber cellStyleForDate用于控制数字和日期的显示方式。

因此我们可以使用以下方式获取CellStyle对象自定义指定种类的样式:

StyleSet style = writer.getStyleSet();
CellStyle cellStyle = style.getHeadCellStyle();
...

ExcelReader读取Excel、流、工作簿



1. 常用的读取方式


1.1 构建我们的实体类

@Data
public class Student {
    String name;
    String gender;
    String idCard;
    String mobile;
    String education;
    String remarks;
    // 这个字段在Excel表中没有就不会被Htool封装进入数据
    String more;
}

1.2 选择一张excel表

在这里插入图片描述

1.3 进行ExcelReader的测试使用

@Test
public void test01() {
    // 直接按照行读取所有行的数据
    ExcelReader reader = ExcelUtil.getReader("B:/xlxx backup.xlsx");
    List<List<Object>> read = reader.read();
    read.stream().forEach(objects -> System.out.println(objects));

    System.out.println("-----------------");

    // 第一行的列名 ——> 接下来的列的对应值
    List<Map<String, Object>> maps = reader.readAll();
    maps.stream().forEach(map -> map.entrySet().stream().forEach(item -> System.out.println("Column: "+item.getKey()+" Value: "+item.getValue())));

    System.out.println("-----------------");

    // 根据实体类进行字段的对应
    List<Student> students = reader.readAll(Student.class);
    students.stream().forEach(student -> System.out.println(student));

}

简单实战



1. 实现Excel的下载


1.1 Controller

/**
 * @param pageNum       当前页
 * @param pageSize      页面信息条数
 * @param response      返回流信息对象
 * @description 导出学生Excel
 * @author 叶之越
 * @email 739153436@qq.com
 * @date 2020/7/7 13:50
 */
@ApiOperation("导出分页学生信息")
@PostMapping("/export")
public void export(Integer pageNum, Integer pageSize,HttpServletResponse response) {
    talentStudentService.export(pageNum, pageSize, response);
}

1.2 Service

/**
 * @param pageNum       当前页
 * @param pageSize      页面信息条数
 * @param talentStudent 我们导出的学生数据类型
 * @param response      返回流信息对象
 * @description 导出学生Excel
 * @author 叶之越
 * @email 739153436@qq.com
 * @date 2020/7/7 13:54
 */
@Override
public void export(Integer pageNum, Integer pageSize, TalentStudent talentStudent, HttpServletResponse response) {
    // 从数据库查出数据对象封装成map
    final List<Map<String, Object>> educationList = page(new Page<>(pageNum, pageSize), Wrappers.lambdaQuery(talentStudent)).getRecords()
            .stream()
            // 封装成 Map 并且放入 List
            .map(item -> {
                final Map<String, Object> map = new LinkedHashMap<>();
                // 错误,这里需要根据表中字段名称进行命名
                map.put("name", item.getName());
                map.put("gender", item.getGender());
                map.put("idCard", item.getIdCard());
                map.put("mobile", item.getMobile());
                map.put("education", item.getEducation());
                map.put("remarks", item.getRemarks());
                return map;
            })
            .collect(Collectors.toList());
    // 准备将数据集合封装成Excel对象
    ExcelWriter writer = ExcelUtil.getWriter(true);
    // 通过工具类创建writer并且进行别名
    writer.addHeaderAlias("name", "姓名");
    writer.addHeaderAlias("gender", "性别( 0 表示男 , 1 表示 女)");
    writer.addHeaderAlias("idCard", "身份证");
    writer.addHeaderAlias("mobile", "电话");
    writer.addHeaderAlias("education", "个人介绍");
    writer.addHeaderAlias("remarks", "备注");
    // 准备将对象写入我们的 List
    writer.write(educationList, true);
    try {
        // 获取我们的输出流
        final OutputStream output = response.getOutputStream();
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("stu.xlsx", "UTF-8"));
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        writer.flush(output, true);
        writer.close();
        // 这里可以自行关闭资源或者写一个关闭资源的工具类
        IoUtil.close(output);
    } catch (IOException e) {
        log.error("EducationServiceImpl [export] 输出到响应流失败", e);
        throw new BusinessException("导出Excel异常");
    }
}

2. 实现Excel导入到数据库


1.1 Controller

/**
 * @param file 需要同步学生信息用户的Excel文件
 * @description 导入查询学生信息
 * @author 叶之越
 * @email 739153436@qq.com
 * @date 2020/7/7 13:50
 */
@ApiOperation("通过Excel表导入数据")
@PostMapping("/importStudent")
public ResultBean<Boolean> importStudent(@RequestParam MultipartFile file) {
    try {
        return ResultBean.restResult(talentStudentService.getStudentInfos(file.getInputStream()), ErrorCodeInfo.OK);
    } catch (IOException e) {
        log.error("EducationController [getEducation] 获取输入流失败", e);
        throw new BusinessException("获取输入流失败");
    }
}

1.2 Service

/**
 * @param pageNum 当前页
 * @param pageSize 页面信息条数
 * @param talentStudent 我们导出的学生数据类型
 * @param response 返回流信息对象
 * @description 导出学生Excel
 * @author 叶之越
 * @email 739153436@qq.com
 * @date 2020/7/7 13:50
 */
@ApiOperation("导出分页学生信息")
@PostMapping("/export")
public void export(Integer pageNum, Integer pageSize, TalentStudent talentStudent, HttpServletResponse response) {
    talentStudentService.export(pageNum,pageSize, talentStudent,response);
}

3. 实现Excel的模板从服务器下载到客户端


1.1 Controller

/**
 * @param response: 需要对返回IO流
 * @description 返回我们 Excel 的模板
 * @author 叶之越
 * @email 739153436@qq.com
 * @date 2020/7/7 15:15
 */
@ApiOperation("获取学生的数据模板")
@PostMapping("/getExcelTemplate")
public void getExcelTemplate(HttpServletResponse response) {
    talentStudentService.getExcelTemplate(response);
}
}

1.2 Service

/**
 * @param response: 返回输入流
 * @description 下载我们 Excel 的模板
 * @author 叶之越
 * @email 739153436@qq.com
 * @date 2020/7/7 15:17
 */
@Override
public void getExcelTemplate(HttpServletResponse response) {

    try {
        // 1 读取对象
        final ExcelReader reader = ExcelUtil.getReader(this.getClass().getResourceAsStream("/exceltemplate/stu.xlsx"));
        List<List<Object>> lists = reader.read();
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.write(lists);

        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("stu.xlsx", "UTF-8"));
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        // 2 写出对象
        ServletOutputStream outputStream = response.getOutputStream();
        // 通过IO写出我们的表格对象
        writer.flush(outputStream, true);
        writer.close();
        IoUtil.close(outputStream);
    } catch (IOException e) {
        log.error("EducationServiceImpl [export] 输出到响应流失败", e);
        throw new BusinessException("导出Excel异常");
    }
}
  • 23
    点赞
  • 158
    收藏
    觉得还不错? 一键收藏
  • 31
    评论
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值