前两篇文章都是创立 Excel 文档,那么如何将 Excel 文档读取进去进行操作呢?
一、加载解析 Excel 文档
比如说以后有一个 Excel 文档里,如何将这些内容读取进去呢?
1. 咱们须要获取到这个 Excel 文档
2. 获取须要操作的 sheet 表,从 0 下标开始代表为第一页
3. 获取 sheet 表里的每一行、从 0 下标开始代表为第一行
4. 获取 sheet 表里的每一列、从 0 下标开始代表为第一列
// 单元格款式
public static void main(String[] args) throws Exception {
//1. 创立 workbook 工作簿
Workbook wb = new XSSFWorkbook("E:\\demo.xlsx");
//2. 获取 sheet 从 0 开始
Sheet sheet = wb.getSheetAt(0);
// 循环所有行 getLastRowNum 指的是 sheet 表里的最初一行
for (int rowNum = 0; rowNum <sheet.getLastRowNum(); rowNum++) {Row row = sheet.getRow(rowNum);// 获取行对象
// 循环每行中的所有单元格
for(int cellNum = 0; cellNum < row.getLastCellNum();cellNum++) {Cell cell = row.getCell(cellNum);// 获取单元格列对象
}
}
}
如图发现,其实单元格第一列、第二列是没有内容的,其实能够从第三列开始
那么咱们在操作 excel 单元格的时候呢,会有不同的属性类型的
咱们读取的时候,要依据以后单元格的属性,赋值不同的数据类型
// 获取数据
private static Object getValue(Cell cell) {
Object value = null;
switch (cell.getCellType()) {
case STRING: // 字符串类型
value = cell.getStringCellValue();
break;
case BOOLEAN: //boolean 类型
value = cell.getBooleanCellValue();
break;
case NUMERIC: // 数字类型(蕴含日期和一般数字)if(DateUtil.isCellDateFormatted(cell)) {value = cell.getDateCellValue();
}else{value = cell.getNumericCellValue();
}
break;
case FORMULA: // 公式类型
value = cell.getCellFormula();
break;
default:
break;
}
return value;
}
咱们能够打印输出校验获取的数据是否与 Excel 文档里的统一
// 单元格款式
public static void main(String[] args) throws Exception {
//1. 创立 workbook 工作簿
Workbook wb = new XSSFWorkbook("E:\\demo.xlsx");
//2. 获取 sheet 从 0 开始
Sheet sheet = wb.getSheetAt(0);
//3. 创立行对象、列对象 防止反复节约
Row row = null;
Cell cell = null;
// 循环所有行 getLastRowNum 指的是 sheet 表里的最初一行
for (int rowNum = 0; rowNum <sheet.getLastRowNum(); rowNum++) {Row row = sheet.getRow(rowNum);// 获取行对象
StringBuilder sb = new StringBuilder();
// 循环每行中的所有单元格
for(int cellNum = 2; cellNum < row.getLastCellNum();cellNum++) {Cell cell = row.getCell(cellNum);// 获取单元格列对象
}
System.out.println(sb.toString());
}
}
运行后果如下:序号 - 姓名 - 年龄 - 家庭住址 - 出生日期
1- 张三 -18- 北京 - 北京 -Thu Nov 01 00:00:00 CST 2001-
2- 李四 -20- 上海 - 北京 -Thu Nov 01 00:00:00 CST 2001-
3- 王五 -18- 广州 - 北京 -Thu Nov 01 00:00:00 CST 2001-
4- 赵六 -20- 深圳 - 北京 -Thu Nov 01 00:00:00 CST 2001-
二、需要报表导入
实现批量导入员工性能
页面端上传 excel 表格,服务端解析表格获取数据,批量新增用户
咱们在应用导入的时候,要依据提供的模板填写相应的数据信息
比如说咱们以后有一个模板,外面的信息是
那么咱们如何将这些信息读取到,并且将它们保留到服务器数据库中?
第一步:搭建环境、引入 JAR 包或者 MAVEN 坐标
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.0.1</version>
</dependency>
第二步:依据解析 Excel 文档思路获取上传文件
1. 咱们须要获取到这个 Excel 文档
2. 获取须要操作的 sheet 表,从 0 下标开始代表为第一页
3. 获取 sheet 表里的每一行、从 0 下标开始代表为第一行
4. 获取 sheet 表里的每一列、从 0 下标开始代表为第一列
5. 同时咱们读取的时候,要依据以后单元格的属性,赋值不同的数据类型
// 获取数据
private static Object getValue(Cell cell) {
Object value = null;
switch (cell.getCellType()) {
case STRING: // 字符串类型
value = cell.getStringCellValue();
break;
case BOOLEAN: //boolean 类型
value = cell.getBooleanCellValue();
break;
case NUMERIC: // 数字类型(蕴含日期和一般数字)if(DateUtil.isCellDateFormatted(cell)) {value = cell.getDateCellValue();
}else{value = cell.getNumericCellValue();
}
break;
case FORMULA: // 公式类型
value = cell.getCellFormula();
break;
default:
break;
}
return value;
}
- 依据思路咱们创立对应的用户类,以及测试
class User{
private String name;
private String tel;
private String code;
private String deptCode;
public User(Object[] obj) {this.name = obj[0].toString();// 用户名
this.tel = obj[1].toString();// 手机号
this.code = obj[2].toString();// 工号
this.deptCode = obj[5].toString();// 部门编码}
// 省略 get、set 办法
}
@RequestMapping(value="/user/import", method = RequestMethod.POST)
public Result importExcel(@RequestParam(name = "file") MultipartFile attachment)throws Exception {
//1. 依据上传流信息创立工作簿
Workbook workbook = WorkbookFactory.create(attachment.getInputStream());
//2. 获取第一个 sheet
Sheet sheet = workbook.getSheetAt(0);
List<User> users = new ArrayList<>();
//3. 从第二行开始获取数据
for (int rowNum = 1; rowNum <sheet.getLastRowNum(); rowNum++) {
// 获取行对象
Row row = sheet.getRow(rowNum);
// 获取该行的所有列单元格数量
Object objs[] = new Object[row.getLastCellNum()];
// 从第二列获取数据
for(int cellNum = 0; cellNum < row.getLastCellNum();cellNum++) {Cell cell = row.getCell(cellNum);
objs[cellNum] = getValue(cell);
}
// 依据每一列结构用户对象
User user = new User(objs);
users.add(user);
}
// 第一个参数:用户列表,第二个参数:部门编码
userService.save(users);
return Result.SUCCESS();}
第三步:批量保留用户信息到数据库中
@Transactional
public void save(List<User> users) throws Exception {for (User user : users) {userDao.save(user);
}
}
若对于 Excel 文档中,数字有时会携带.0 小数点,手机号会存在迷信记数法问题
这样的状况咱们要怎么转化解决呢?
public User(Object[] obj) {this.name = obj[0].toString();// 用户名
this.tel = new DecimalFormat("#").format(obj[1].toString());// 手机号
this.code = new DecimalFormat("#").format(obj[2].toString());// 工号
this.deptCode = obj[5].toString();// 部门编码}
这样咱们就不会呈现转换的问题了
三、需要文档导出
实现当月人事报表的导出:蕴含当月入职员工信息,到职员工信息
次要思路分为:获取报表数据、创立 excel、输入下载
@RequestMapping(value = "/export/{month}", method = RequestMethod.GET)
public void export(@PathVariable(name = "month") String month) throws Exception {
//1. 结构数据
List<User> list = userService.findByReport(companyId,month+"%");
//2. 创立工作簿
XSSFWorkbook workbook = new XSSFWorkbook();
//3. 结构 sheet
String[] titles = {"编号", "姓名", "手机"};
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
int titleInext = 0;
//4. 写入题目
for (String title : titles) {Cell cell = row.createCell(titleInext++);
cell.setCellValue(title);
}
Cell cell = null;
//5. 写入单元格
for (user report : list) {Row dataRow = sheet.createRow(titleInext++);
// 编号
cell = dataRow.createCell(0);
cell.setCellValue(report.getUserId());
// 姓名
cell = dataRow.createCell(1);
cell.setCellValue(report.getUsername());
// 手机
cell = dataRow.createCell(2);
cell.setCellValue(report.getMobile());
}
//6. 输入文件下载
String fileName = URLEncoder.encode(month+"人员信息.xlsx", "UTF-8");
response.setContentType("application/octet-stream");
response.setHeader("content-disposition", "attachment;filename=" + new
String(fileName.getBytes("ISO8859-1")));
response.setHeader("filename", fileName);
workbook.write(response.getOutputStream());
}
参考资料
黑马程序员:基于 SaaS 平台的 iHRM 刷脸登录实战开发(报表相干视频)