老规矩,先看效果图
选择excel菜品
导入数据成功
之前有看过我课程的同学肯定知道,我之前是没有批量导入的类目的,不错,这个类目就是我们今天新加的功能。
实现步骤很简单:
- 1,点击导入按钮选择excel
- 2,导入成功后调转到商品列表页。
下面我们就来具体讲解下实现步骤
一,引入excel操作类库
我们这里主要用到了下面红框里的两个类库
类库写在pom.xml里,不要忘记做ReImport操作
二,添加导入excel的后台网页
添加菜品类目导入页
添加商品(菜品)导入页
上面的代码,我会加入到点餐系统里,有购买点餐系统课程的同学,去刷新下之前的网盘链接即可获取最新代码。
三,编写ExcelUtil工具类
把完整代码给大家贴出来,其实很简单,就是在工具类里定义一个导入菜品类目和菜品的方法。
注意:对应的导入方法是解析excel里的数据,所以你的excel数据必须和我的保持一致,就是第几列是什么数据,要和我的对应起来。要不然会导致数据存错的问题。
package com.qcl.utils; import com.qcl.dataobject.ProductCategory; import com.qcl.dataobject.ProductInfo; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import java.io.InputStream; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import lombok.extern.slf4j.Slf4j; /* * 操作excel * */ @Slf4j public class ExcelUtils { /* * 菜品类目批量导入 * 要求 * 1,必须以.xlsx结尾的excel文件 * 2,表格内容必须按照下面顺序 * 0:类目名,1:type值 * * */ public static List<ProductCategory> excelToProductCategoryList(InputStream inputStream) { List<ProductCategory> list = new ArrayList<>(); Workbook workbook = null; try { workbook = WorkbookFactory.create(inputStream); inputStream.close(); //工作表对象 Sheet sheet = workbook.getSheetAt(0); //总行数 int rowLength = sheet.getLastRowNum(); System.out.println("总行数有多少行" + rowLength); //工作表的列 Row row = sheet.getRow(0); //总列数 int colLength = row.getLastCellNum(); System.out.println("总列数有多少列" + colLength); //得到指定的单元格 Cell cell = row.getCell(0); for (int i = 1; i <= rowLength; i++) { ProductCategory goodInfo = new ProductCategory(); row = sheet.getRow(i); for (int j = 0; j < colLength; j++) { cell = row.getCell(j); if (cell != null) { cell.setCellType(Cell.CELL_TYPE_STRING); String data = cell.getStringCellValue(); data = data.trim(); //列:0:类目名,1:type值 if (j == 0) { goodInfo.setCategoryName(data); } else if (j == 1) { goodInfo.setCategoryType(Integer.parseInt(data)); } } } list.add(goodInfo); // log.error("每行数据={}", menuInfo); } } catch (Exception e) { log.error("excel导入抛出的错误={}", e); } return list; } /* * 菜品(商品)批量导入 * 要求 * 1,必须以.xlsx结尾的excel文件 * 2,表格内容必须按照下面顺序 * 0商品名,1单价,2库存,3类目,4描述,5图片链接 * * */ public static List<ProductInfo> excelToProductInfoList(InputStream inputStream) { List<ProductInfo> list = new ArrayList<>(); Workbook workbook = null; try { workbook = WorkbookFactory.create(inputStream); inputStream.close(); //工作表对象 Sheet sheet = workbook.getSheetAt(0); //总行数 int rowLength = sheet.getLastRowNum(); //工作表的列 Row row = sheet.getRow(0); //总列数 int colLength = row.getLastCellNum(); //得到指定的单元格 Cell cell = row.getCell(0); for (int i = 1; i <= rowLength; i++) { ProductInfo goodInfo = new ProductInfo(); row = sheet.getRow(i); for (int j = 0; j < colLength; j++) { cell = row.getCell(j); if (cell != null) { cell.setCellType(Cell.CELL_TYPE_STRING); String data = cell.getStringCellValue(); data = data.trim(); //列: 0商品名,1单价,2库存,3类目,4描述,5图片链接 if (j == 0) { goodInfo.setProductId(KeyUtil.genUniqueKey()); goodInfo.setProductName(data); } else if (j == 1) { goodInfo.setProductPrice(new BigDecimal(data)); } else if (j == 2) { goodInfo.setProductStock(Integer.parseInt(data)); } else if (j == 3) { goodInfo.setCategoryType(Integer.parseInt(data)); } else if (j == 4) { goodInfo.setProductDescription(data); } else if (j == 5) { goodInfo.setProductIcon(data); } } } list.add(goodInfo); } } catch (Exception e) { log.error("excel导入抛出的错误={}", e); } return list; } }
四,编写对应的接口
上面的工具类封装好以后,我们接下来就需要在对应的Controller类里添加导入数据的方法了。
1,导入菜品类目
主要编写上图所示的两个方法 一个是打开导入的网页,另外一个是实现导入数据的功能。完整代码贴出来给大家
/* * excel导入网页 * */ @GetMapping("/excel") public ModelAndView excel(Map<String, Object> map) { return new ModelAndView("category/excel", map); } /* * 批量导入excel里的菜品类目到数据库 * */ @RequestMapping("/uploadExcel") @ResponseBody public ModelAndView uploadExcel(@RequestParam("file") MultipartFile file, Map<String, Object> map) { String name = file.getOriginalFilename(); if (name.length() < 6 || !name.substring(name.length() - 5).equals(".xlsx")) { map.put("msg", "文件格式错误"); map.put("url", "/sell/seller/category/excel"); return new ModelAndView("common/error", map); } List<ProductCategory> list; try { list = ExcelUtils.excelToProductCategoryList(file.getInputStream()); log.info("excel导入的list={}", list); if (list == null || list.size() <= 0) { map.put("msg", "导入失败"); map.put("url", "/sell/seller/category/excel"); return new ModelAndView("common/error", map); } //excel的数据保存到数据库 try { for (ProductCategory excel : list) { if (excel != null) { //如果类目type值已存在,就不再导入 List typeList = categoryService.findOneByType(excel.getCategoryType()); log.info("查询类目type是否存在typeList={}", typeList); if (typeList == null || typeList.size() < 1) { System.out.println("保存成功"); categoryService.save(excel); } } } } catch (Exception e) { log.error("某一行存入数据库失败={}", e); } } catch (Exception e) { e.printStackTrace(); map.put("msg", e.getMessage()); map.put("url", "/sell/seller/category/excel"); return new ModelAndView("common/error", map); } map.put("url", "/sell/seller/category/list"); return new ModelAndView("common/success", map); }
2,导入菜品数据
代码也给大家贴出来
/* * excel导入网页 * */ @GetMapping("/excel") public ModelAndView excel(Map<String, Object> map) { return new ModelAndView("product/excel", map); } /* * 批量导入excel里的菜品(商品)到数据库 * */ @RequestMapping("/uploadExcel") @ResponseBody public ModelAndView uploadExcel(@RequestParam("file") MultipartFile file, Map<String, Object> map) { String name = file.getOriginalFilename(); if (name.length() < 6 || !name.substring(name.length() - 5).equals(".xlsx")) { map.put("msg", "文件格式错误"); map.put("url", "/sell/seller/product/excel"); return new ModelAndView("common/error", map); } List<ProductInfo> list; try { list = ExcelUtils.excelToProductInfoList(file.getInputStream()); log.info("excel导入的list={}", list); if (list == null || list.size() <= 0) { map.put("msg", "导入失败"); map.put("url", "/sell/seller/product/excel"); return new ModelAndView("common/error", map); } //excel的数据保存到数据库 try { for (ProductInfo excel : list) { if (excel != null) { //如果类目type值已存在,就不再导入 productService.save(excel); } } } catch (Exception e) { log.error("某一行存入数据库失败={}", e); } } catch (Exception e) { e.printStackTrace(); map.put("msg", e.getMessage()); map.put("url", "/sell/seller/product/excel"); return new ModelAndView("common/error", map); } map.put("url", "/sell/seller/product/list"); return new ModelAndView("common/success", map); }
到这里我们就完整的实现了点餐系统批量导入菜品数据到数据库的功能了。