一篇读懂springboot用poi导入excel表全部的数据到数据库

1.业务描述

利用HTML导入excel表中的全部数据到数据库
最好先把准备插入的excel表的格式改一下(如代表和价格)
一篇读懂springboot用poi导入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集合遍历插入到数据库进行持久化操作。

上一篇:POI导出


下一篇:Solution -「CF 1073G」Yet Another LCP Problem