本文是 vhr 系列的第十一篇.
vhr 项目地址 https://github.com/lenve/vhr
导出 Excel
整体来说, Excel 有. xls 和. xlsx, 那么在 POI 中这两个也对应两个不同的类, 但是类名不同, 方法基本都是一致的, 因此我这里将只介绍. xls 一种.
整体来说, 可以分为如下七个步骤:
1. 创建 Excel 文档
HSSFWorkbook workbook = new HSSFWorkbook();
2. 设置文档的基本信息, 这一步是可选的
// 获取文档信息, 并配置
DocumentSummaryInformation dsi = workbook.getDocumentSummaryInformation();
// 文档类别
dsi.setCategory("员工信息");
// 设置文档管理员
dsi.setManager("江南一点雨");
// 设置组织机构
dsi.setCompany("XXX 集团");
// 获取摘要信息并配置
SummaryInformation si = workbook.getSummaryInformation();
// 设置文档主题
si.setSubject("员工信息表");
// 设置文档标题
si.setTitle("员工信息");
// 设置文档作者
si.setAuthor("XXX 集团");
// 设置文档备注
si.setComments("备注信息暂无");
这些信息将显示在详细信息窗格中:
3. 创建一个 Excel 表单, 参数为 sheet 的名字
HSSFSheet sheet = workbook.createSheet("XXX 集团员工信息表");
4. 创建一行
HSSFRow headerRow = sheet.createRow(0);
0 表示第一行.
5. 在第一行中创建第一个单元格, 并设置数据
HSSFCell cell0 = headerRow.createCell(0);
cell0.setCellValue("编号");
6. 将 Excel 写到 ByteArrayOutputStream 中
baos = new ByteArrayOutputStream();
workbook.write(baos);
7. 创建 ResponseEntity 并返回
return new ResponseEntity<byte[]>(baos.toByteArray(), headers, HttpStatus.CREATED);
核心步骤就这七个步骤, 当然还有其他设置单元格数据格式, 单元格背景, 单元格宽度等, 大家可以在源码中研究, 这里就不赘述了.
导入 Excel 数据
数据导入主要涉及三个步骤 1. 文件上传; 2.Excel 解析; 3. 数据插入. 第三步就比较简单了, 我们这里重点来看看前两个步骤.
文件上传
文件上传采用了 ElementUI 中的 Upload 控件, 如下:
<el-upload :show-file-list="false" accept="application/vnd.ms-excel" action="/emp/basic/importEmp"
:on-success="fileUploadSuccess" :on-error="fileUploadError" :disabled="fileUploadBtnText=='正在导入'"
:before-upload="beforeFileUpload">
<el-button size="mini" type="success" :loading="fileUploadBtnText=='正在导入'">
<i class="fa fa-lg fa-level-up">
</i>
{{fileUploadBtnText}}
</el-button>
</el-upload>
正在上传时, 文件上传控件不可用, 上传成功或者失败之后才可用, 上传过程中, 上传按钮会有 loading 显示.
然后在 SpringMVC 中接收上传文件即可:
@RequestMapping(value = "/importEmp", method = RequestMethod.POST)
public RespBean importEmp(MultipartFile file) {
//...
}
Excel 解析
将上传到的 MultipartFile 转为输入流, 然后交给 POI 去解析即可. 可以分为如下四个步骤:
1. 创建 HSSFWorkbook 对象
HSSFWorkbook workbook = new HSSFWorkbook(new POIFSFileSystem(file.getInputStream()));
2. 获取一共有多少 sheet, 然后遍历
int numberOfSheets = workbook.getNumberOfSheets();
for (int i = 0; i < numberOfSheets; i++) {
HSSFSheet sheet = workbook.getSheetAt(i);
//...
}
3. 获取 sheet 中一共有多少行, 遍历行 (注意第一行是标题)
int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
Employee employee;
for (int j = 0; j < physicalNumberOfRows; j++) {
if (j == 0) {
continue; // 标题行
}
//...
}
4. 获取每一行有多少单元格, 遍历单元格
int physicalNumberOfCells = row.getPhysicalNumberOfCells();
employee = new Employee();
for (int k = 0; k < physicalNumberOfCells; k++) {
HSSFCell cell = row.getCell(k);
//...
}
单元格的遍历就比较简单了, 将遍历到的数据放入 Employee 实例中, 每遍历一行, 就将一个 employee 实例放入集合中.
好了, 大致的步骤就是这样, 详细信息小伙伴可以 star 微人事的源码仔细研究.
本系列其他文章:
1. SpringBoot+vue 前后端分离, 使用 SpringSecurity 完美处理权限问题 (一)
2. SpringBoot+Vue 前后端分离, 使用 SpringSecurity 完美处理权限问题 (二)
3. SpringSecurity 中密码加盐与 SpringBoot 中异常统一处理
4. axios 请求封装和异常统一处理
5. 权限管理模块中动态加载 Vue 组件
6. SpringBoot+Vue 前后端分离, 使用 SpringSecurity 完美处理权限问题 (六)
7. vhr 部门管理数据库设计与编程
8. 使用 MyBatis 轻松实现递归查询与存储过程调用
9. ElementUI 中 tree 控件踩坑记
10. SpringBoot 中自定义参数绑定
来源: https://segmentfault.com/a/1190000013036679