本次工作总结
- 完成Excel导入通用实现类
包括:ExcelUtil实现、通过文件数据导入新闻接口。
相关代码实现
ExcelUtil通用类
在pom.xml中导入所需依赖
<!--用于导入Excel文件数据-->
<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>
ExcelUtil类
/**
* @author lmh
* @desc 可以解析任何Excel文件并封装相应实体类,再放入List集合中
* @date 2022/5/28
*/
public class ExcelUtils<T> {
//泛型,通用任何实体类
private T t;
public ExcelUtils(T t){
this.t = t;
}
/**
*@author lmh
*@date 2022/5/28
*@desc 传入EXCEL并解析,提取出信息
*/
public List<Map> analysisExcel(InputStream inputStream,String fileName) throws IOException{
List<Map> list = new ArrayList<>();
Workbook workbook = createWorkbookByExcelType(inputStream, fileName); // 创建工作簿
Sheet sheet = workbook.getSheetAt(0);
Row row = null;
// 获取最大行数
int maxRowNum = sheet.getLastRowNum();
// 获取第一行
row = sheet.getRow(0);
// 获取最大列数
int maxColNum = row.getLastCellNum();
List<String> arrayList = new ArrayList<>();
Field[] declaredFields = t.getClass().getDeclaredFields();
// 把需要封装的实体类的属性名存入arrayList
for (int i = 0; i < declaredFields.length; i++) {
String name = declaredFields[i].getName();
arrayList.add(name);
}
// 循环遍历excel表格,把每条数据封装成 map集合,再放入list集合中
for (int i = 1; i <= maxRowNum; i++) {
Map<String, String> map = new HashMap<>();
row = sheet.getRow(i);
if (row != null){
for (int j = 0; j < maxColNum; j++) {
String cellData = (String)getCellFormatValue(row.getCell(j));
map.put(arrayList.get(j), cellData); // map 封装
}
list.add(map); // map存入list
}
}
return list;
}
public static Workbook createWorkbookByExcelType(InputStream inputStream,String fileName){
Workbook wb = null;
if(fileName == null){
return null;
}
String extString = fileName.substring(fileName.lastIndexOf("."));
InputStream is = null;
try {
is = inputStream;
if(".xls".equals(extString)){
return wb = new HSSFWorkbook(is); // 2003版本 .xls
}else if(".xlsx".equals(extString)){
return wb = new XSSFWorkbook(is); // 2007版本 .xlsx
}else{
return wb = null;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return wb;
}
// 用于获取表格中的数据方法
public static Object getCellFormatValue(Cell cell){
Object cellValue = null;
if(cell!=null){
//判断cell类型
switch(cell.getCellType()){
case NUMERIC:{
cellValue = String.valueOf(cell.getNumericCellValue());
break;
}
case FORMULA:{
//判断cell是否为日期格式
if(DateUtil.isCellDateFormatted(cell)){
//转换为日期格式YYYY-mm-dd
cellValue = cell.getDateCellValue();
}else{
//数字
cellValue = String.valueOf(cell.getNumericCellValue());
}
break;
}
case STRING:{
cellValue = cell.getRichStringCellValue().getString();
break;
}
default:
cellValue = "";
}
}else{
cellValue = "";
}
return cellValue;
}
}
ExcelUtil使用实例如下👇
新闻批量导入
这边通过Excel批量导入到数据库中,需要保证excel中列属性和实体类对应。
Controller层
/**
*@author lmh
*@date 2022/5/30
*@desc 文章批量导入
*/
@PostMapping("/uplodaNews")
public Result uploadNews(@RequestParam("file") MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename(); // 获取文件名
InputStream is = null;
try{
is = file.getInputStream();
List<Map> paperList = newsService.getListByExcel(is,fileName);// 获取解析后的List集合
System.out.println(paperList.toString());
Boolean result = newsService.batchImportStuInfo(paperList); // 把数据插入数据库
if (result){
return Result.success("上传成功");
}else {
return Result.fail(403,"上传失败");
}
}catch (Exception e){
e.printStackTrace();
} finally {
is.close();
}
return Result.fail(403,"文件出错");
}
Service层
从Excel中获取数据并封装成List列表形式
@Override
public List<Map> getListByExcel(InputStream is, String fileName) {
try{
List<Map> newsList = new ExcelUtils(new News()).analysisExcel(is, fileName);
return newsList;
}catch (Exception e){
e.printStackTrace();
}
return new ArrayList<>();
}
将List数据批量加入到数据库中
@Override
public Boolean batchImportStuInfo(List<Map> newslist) {
Integer flag = newsMapper.batchImportInfo(newslist);
if (flag > 0){
return true;
} else return false;
}
Mapper层
<insert id="batchImportInfo" parameterType="java.util.List">
insert into t_news values
<foreach item="item" collection="list" separator=",">
(#{item.id},#{item.title},#{item.content},#{item.time},#{item.link})
</foreach>
</insert>
测试实例
这里自己写了个小的demo来测试这个接口。
测试demo结构如下:
导入效果:
总结
- ExcelUtil的编写既可以方便的导入Excel数据,又可以支撑后续的后台管理系统的更新数据的相应功能实现。
- 再次更行新闻的话不需要直接操作数据库了。