點餐小程序,點餐系統(tǒng),管理后臺批量導(dǎo)入excel菜品數(shù)據(jù)
點餐系統(tǒng)上線這段時間,有好多同學(xué)反饋,是否可以添加一個菜品批量導(dǎo)入的功能。由于平時比較忙,一直沒有時間把菜品批量導(dǎo)入的功能加進(jìn)來。今天正好空出來時間了,就來教大家實現(xiàn)下菜品批量導(dǎo)入的功能。 后面會把這節(jié)功能錄制成視頻放到點餐系統(tǒng)的課程里。
傳送門:點餐系統(tǒng),java后臺+點餐小程序
老規(guī)矩,先看效果圖
選擇excel菜品

導(dǎo)入數(shù)據(jù)成功

之前有看過我課程的同學(xué)肯定知道,我之前是沒有批量導(dǎo)入的類目的,不錯,這個類目就是我們今天新加的功能。
實現(xiàn)步驟很簡單:
1,點擊導(dǎo)入按鈕選擇excel
2,導(dǎo)入成功后調(diào)轉(zhuǎn)到商品列表頁。
下面我們就來具體講解下實現(xiàn)步驟
一,引入excel操作類庫
我們這里主要用到了下面紅框里的兩個類庫

類庫寫在pom.xml里,不要忘記做ReImport操作

二,添加導(dǎo)入excel的后臺網(wǎng)頁
添加菜品類目導(dǎo)入頁
添加商品(菜品)導(dǎo)入頁
上面的代碼,我會加入到點餐系統(tǒng)里,有購買點餐系統(tǒng)課程的同學(xué),去刷新下之前的網(wǎng)盤鏈接即可獲取最新代碼。
三,編寫ExcelUtil工具類
把完整代碼給大家貼出來,其實很簡單,就是在工具類里定義一個導(dǎo)入菜品類目和菜品的方法。
注意:對應(yīng)的導(dǎo)入方法是解析excel里的數(shù)據(jù),所以你的excel數(shù)據(jù)必須和我的保持一致,就是第幾列是什么數(shù)據(jù),要和我的對應(yīng)起來。要不然會導(dǎo)致數(shù)據(jù)存錯的問題。
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 {
? ? /*
? ? ?* 菜品類目批量導(dǎo)入
? ? ?* 要求
? ? ?* 1,必須以.xlsx結(jié)尾的excel文件
? ? ?* 2,表格內(nèi)容必須按照下面順序
? ? ?* 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);
? ? ? ? ? ? //總行數(shù)
? ? ? ? ? ? int rowLength = sheet.getLastRowNum();
? ? ? ? ? ? System.out.println("總行數(shù)有多少行" + rowLength);
? ? ? ? ? ? //工作表的列
? ? ? ? ? ? Row row = sheet.getRow(0);
? ? ? ? ? ? //總列數(shù)
? ? ? ? ? ? int colLength = row.getLastCellNum();
? ? ? ? ? ? System.out.println("總列數(shù)有多少列" + 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("每行數(shù)據(jù)={}", menuInfo);
? ? ? ? ? ? }
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? log.error("excel導(dǎo)入拋出的錯誤={}", e);
? ? ? ? }
? ? ? ? return list;
? ? }
? ? /*
? ? ?* 菜品(商品)批量導(dǎo)入
? ? ?* 要求
? ? ?* 1,必須以.xlsx結(jié)尾的excel文件
? ? ?* 2,表格內(nèi)容必須按照下面順序
? ? ?* 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);
? ? ? ? ? ? //總行數(shù)
? ? ? ? ? ? int rowLength = sheet.getLastRowNum();
? ? ? ? ? ? //工作表的列
? ? ? ? ? ? Row row = sheet.getRow(0);
? ? ? ? ? ? //總列數(shù)
? ? ? ? ? ? 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導(dǎo)入拋出的錯誤={}", e);
? ? ? ? }
? ? ? ? return list;
? ? }
}
四,編寫對應(yīng)的接口
上面的工具類封裝好以后,我們接下來就需要在對應(yīng)的Controller類里添加導(dǎo)入數(shù)據(jù)的方法了。
1,導(dǎo)入菜品類目
主要編寫上圖所示的兩個方法 一個是打開導(dǎo)入的網(wǎng)頁,另外一個是實現(xiàn)導(dǎo)入數(shù)據(jù)的功能。完整代碼貼出來給大家
/*
? ? ?* excel導(dǎo)入網(wǎng)頁
? ? ?* */
? ? @GetMapping("/excel")
? ? public ModelAndView excel(Map<String, Object> map) {
? ? ? ? return new ModelAndView("category/excel", map);
? ? }
? ? /*
? ? ?* 批量導(dǎo)入excel里的菜品類目到數(shù)據(jù)庫
? ? ?* */
? ? @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導(dǎo)入的list={}", list);
? ? ? ? ? ? if (list == null || list.size() <= 0) {
? ? ? ? ? ? ? ? map.put("msg", "導(dǎo)入失敗");
? ? ? ? ? ? ? ? map.put("url", "/sell/seller/category/excel");
? ? ? ? ? ? ? ? return new ModelAndView("common/error", map);
? ? ? ? ? ? }
? ? ? ? ? ? //excel的數(shù)據(jù)保存到數(shù)據(jù)庫
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? for (ProductCategory excel : list) {
? ? ? ? ? ? ? ? ? ? if (excel != null) {
? ? ? ? ? ? ? ? ? ? ? ? //如果類目type值已存在,就不再導(dǎo)入
? ? ? ? ? ? ? ? ? ? ? ? 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("某一行存入數(shù)據(jù)庫失敗={}", 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,導(dǎo)入菜品數(shù)據(jù)
代碼也給大家貼出來
?/*
? ? ?* excel導(dǎo)入網(wǎng)頁
? ? ?* */
? ? @GetMapping("/excel")
? ? public ModelAndView excel(Map<String, Object> map) {
? ? ? ? return new ModelAndView("product/excel", map);
? ? }
? ? /*
? ? ?* 批量導(dǎo)入excel里的菜品(商品)到數(shù)據(jù)庫
? ? ?* */
? ? @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導(dǎo)入的list={}", list);
? ? ? ? ? ? if (list == null || list.size() <= 0) {
? ? ? ? ? ? ? ? map.put("msg", "導(dǎo)入失敗");
? ? ? ? ? ? ? ? map.put("url", "/sell/seller/product/excel");
? ? ? ? ? ? ? ? return new ModelAndView("common/error", map);
? ? ? ? ? ? }
? ? ? ? ? ? //excel的數(shù)據(jù)保存到數(shù)據(jù)庫
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? for (ProductInfo excel : list) {
? ? ? ? ? ? ? ? ? ? if (excel != null) {
? ? ? ? ? ? ? ? ? ? ? ? //如果類目type值已存在,就不再導(dǎo)入
? ? ? ? ? ? ? ? ? ? ? ? productService.save(excel);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } catch (Exception e) {
? ? ? ? ? ? ? ? log.error("某一行存入數(shù)據(jù)庫失敗={}", 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);
? ? }
到這里我們就完整的實現(xiàn)了點餐系統(tǒng)批量導(dǎo)入菜品數(shù)據(jù)到數(shù)據(jù)庫的功能了。
完整的代碼我會放到點餐系統(tǒng)里,購買我點餐系統(tǒng)課程的同學(xué),記得去刷新下之前的網(wǎng)盤鏈接,就可以獲取最新的代碼了
演示視頻也已經(jīng)錄制出來了,大家可以去看下

https://study.163.com/course/courseMain.htm?courseId=1209428915
完整的點餐系統(tǒng),包含Java后臺和掃碼點餐小程序,效果圖如下。
