1.业务描述
利用HTML导入excel表中的全部数据到数据库
最好先把准备插入的excel表的格式改一下(如代表和价格)
2.导入maven依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.0.0</version>
</dependency>
3.前端代码
创建merch-upload前端页面来作为上传数据测试页面,具体就是需要注意的是:
①路径;②文件的类型为file; ③提交的type为submit属性
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="multipart/form-data"; charset="UTF-8">
<title>上传商品信息文件</title>
</head>
<body>
<h1 th:inlines="text">文件上传</h1>
<form th:action="@{/exceImport}" method="post" enctype="multipart/form-data">
<p>选择文件: <input type="file" name="file"/></p>
<p><input type="submit" value="提交"/></p >
</form>
</body>
</html>
</body>
</html>
4.后端代码
首先我们需要一个封装数据的pojo对象(这里用的注解还要导入lombok依赖)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@ToString
public class Merch {
private Integer id;
private String name;
private String packaging; //商品包装类型
private String factory; //厂家名称
private Double price; //价格
private String code; //代码
private Integer stock; //库存数
}
4.1.后端业务实现:其一
前端刚才提交的文件会找对应的路径进行提交
@Autowired
private MerchService merchService;
/*
导入excel全部的数据到数据库
*/
@RequestMapping(value = {"/exceImport"},method = RequestMethod.POST)
@ResponseBody
controller 具体业务(这是我同事的代码,好像是没问题的)
public String uploadImg(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
file.getContentType();
file.getOriginalFilename();
if (file.isEmpty()) {
return "文件为空!";
}
try {
//根据路径获取这个操作excel的实例
HSSFWorkbook wb = new HSSFWorkbook(file.getInputStream());
//根据页面index 获取sheet页
HSSFSheet sheet = wb.getSheetAt(0);
//实体类集合
List<Merch> importDatas = new ArrayList<>();
HSSFRow row = null;
//循环sesheet页中数据从第二行开始,第一行是标题
for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {
//获取每一行数据
row = sheet.getRow(i);
Merch data = new Merch();
// data.setId(Integer.valueOf((int) row.getCell(0).getNumericCellValue()));
data.setName(row.getCell(1).getStringCellValue());
data.setCode(row.getCell(2).getStringCellValue());
data.setFactory(row.getCell(3).getStringCellValue());
data.setPrice(row.getCell(4).getNumericCellValue());
data.setPackaging(row.getCell(5).getStringCellValue());
data.setStock(Integer.valueOf((int) row.getCell(6).getNumericCellValue()));
importDatas.add(data);
}
//循环展示导入的数据,实际应用中应该校验并存入数据库
for (Merch imdata : importDatas) {
merchService.saveMerch(imdata);
System.out.println("ID:"+imdata.getId()+" name:"+imdata.getName()+" Code:"+imdata.getCode()+" Factory:"+imdata.getFactory()
+"Pagkage:"+imdata.getPackaging()+"Price:"+imdata.getPrice()+"Stock:"+imdata.getStock());
}
} catch (Exception e) {
e.printStackTrace();
}
return "导入成功!";
}
4.2.后台业务实现:其二
controller 具体业务(这段代码是我的,但是有个小bug,生成的临时文件不能删除!)
id 我数据库设置的是自增所以不需要写上,避免混乱
public String uploadAndBatchImport(@RequestParam("file")MultipartFile file, HttpServletRequest request) {
FileInputStream is;
File myFile;
try {
myFile = new File("G:\\Google" + UUID.randomUUID() + file.getOriginalFilename());
file.transferTo(myFile);
is = new FileInputStream(myFile);
List<Merch> merchs = new ArrayList<>();
//编写解析代码逻辑
//基于 .xls 格式解析 HSSF
//1. 加载Excel文件对象
HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);
//2. 读取一个sheet
HSSFSheet sheet = hssfWorkbook.getSheetAt(0);//获取第一个sheet对象
//3. 读取sheet中每一行,一行数据对应一个区域对象
for (Row row : sheet) {
//3.1 第一行表头 跳过
if (row.getRowNum() == 0) {
//第一行 跳过
continue;
}
//跳过空值的行,要求此行作废
// if (row.getCell(0) == null
// || StringUtils.isBlank(row.getCell(0).getStringCellValue())) {
// continue;
// }
Merch merch = new Merch();
//3.2 封装数据
//获取单元格
// Cell cell = row.getCell(0);
Cell cell6 = row.getCell(6);
Cell cell2 = row.getCell(2);
//设置单元格类型
// cell.setCellType(CellType.STRING);
cell2.setCellType(CellType.STRING);
cell6.setCellType(CellType.STRING);
// merch.setId(Integer.valueOf(cell.getStringCellValue())); //序号Id
merch.setName(row.getCell(1).getStringCellValue()); //名称
merch.setCode(row.getCell(2).getStringCellValue()); //代表
merch.setPackaging(row.getCell(3).getStringCellValue()); //包装
merch.setPrice(row.getCell(4).getNumericCellValue()); //价格
merch.setFactory(row.getCell(5).getStringCellValue()); //生产厂家
merch.setStock(Integer.valueOf(cell6.getStringCellValue())); //库存
merchs.add(merch);
}
//System.out.println(merchs);
//4. 调用业务层,添加数据
for (Merch data: merchs){
merchService.saveMerch( data);
}
//5. 删除文件
myFile.delete();
return "导入成功";
// return new ResponseEntity<Void>(HttpStatus.OK);
} catch (Exception e) {
//服务器错误
// return new ResponseEntity<Void>(HttpStatus.INTERNAL_SERVER_ERROR);
e.printStackTrace();
}
return "导入失败";
}
4.3.serviceImpl层(这里就直接实现类了,都是基本的添加操作)
@Autowired
private MerchDao merchDao;
@Override
public int saveMerch(Merch merch) {
int rows = merchDao.insertMerch(merch);
return rows;
}
4.4.dao层或mapper层
int insertMerch(Merch merch);
与之对应的mapper.xml,写mapper.xml需要注意
①namespace的对应空间为你的mapper层
②id为你的方法名
③增删改的resultType的返回值大都是int,可以不写
<insert id="insertMerch">
insert into merch
(name,code,factory,packaging,price,stock)
values
(#{name},#{code},#{factory},#{packaging},#{price},#{stock})
</insert>
5.总结
都是先获取这个操作excel的实例,然后再获取第一个sheet对象,循环遍历将得到的数据封装到List集合里。
再将List集合遍历插入到数据库进行持久化操作。