毕设IDEA2019之ssmExcel文件导入(POI)

文件导入导出应该是管理后台比较常见的功能,批量导入数据主要用于批量新增、批量查询等功能,相对于单条数据执行效率肯定是高不少的,但对系统的性能有一定要求,高峰期的时候最好控制一定量的批量数据。废话不多说,直接进入正文。
前置条件:耐性100%;IDEA2019;MYSQL5.7;Maven; ssm框架

Maven导入需要的包

<!--  poi文件上传-->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.8</version>
      <exclusions>
        <exclusion>
          <artifactId>commons-codec</artifactId>
          <groupId>commons-codec</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.8</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.2.1</version>

配置SpringMVC.xml

    <!--    配置文件上传-->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"></property>
        <property name="maxUploadSize" value="10485760000"></property>
        <property name="maxInMemorySize" value="40960"></property>
    </bean>

数据库创建表(菜单管理为例)

这里还是用介绍模糊查询时建的Menu表
在这里插入图片描述

创建对应实体类

package com.qiang.domain;

import lombok.Data;
import java.sql.Timestamp;
import java.util.List;

/**
 1. @author Mr.锵
 2. date 2020-02-21
 */
@Data
public class Menu {
    private String menuid;
    private String menuname;
    private Float price;
    private String Image;
    private Timestamp createtime;
    private Timestamp updatetime;
    private Integer sell_num;
    private String status;
    private String description;
    private Integer kucun;
}

梳理导入流程

  1. Excel文件写好要导入的数据;
  2. 点击上传按钮选择文件;
  3. 点击提交按钮将文件传给后台控制器;
  4. 控制器调用service方法处理接收到的文件;
  5. service实现类调用工具类解析Excel文件,获取文件内容;
  6. service实现类获取文件内容后调用Dao方法访问数据库查询是否有该数据,存在更新,不存在则新增,并返回处理结果;
    在这里插入图片描述
    在这里插入图片描述

准备Excel文件及数据

在这里插入图片描述

创建工具类(ReadExcel)

package com.qiang.utils;

import com.qiang.domain.Menu;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 1. @author Mr.锵
 2. date 2020-03-13
 */
public class ReadExcel {
    //总行数
    private int totalRows = 0;
    //总条数
    private int totalCells = 0;
    //错误信息接收器
    private String errorMsg;

    //构造方法
    public ReadExcel() {
    }

    //获取总行数
    public int getTotalRows() {
        return totalRows;
    }

    //获取总列数
    public int getTotalCells() {
        return totalCells;
    }

    //获取错误信息
    public String getErrorInfo() {
        return errorMsg;
    }

    /**
     * 读EXCEL文件,获取信息集合
     *
     * @param
     * @return
     */
    public List<Menu> getExcelInfo(MultipartFile mFile) throws Exception {
        String fileName = mFile.getOriginalFilename();//获取文件名
        System.out.println("文件名:" + fileName);
        List<Menu> menuList = null;
        try {
            if (!validateExcel(fileName)) {// 验证文件名是否合格
                return null;
            }
            boolean isExcel2003 = true;// 根据文件名判断文件是2003版本还是2007版本
            if (isExcel2007(fileName)) {
                isExcel2003 = false;
            }
            menuList = createExcel(mFile.getInputStream(), isExcel2003);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return menuList;
    }

    /**
     * 根据excel里面的内容读取客户信息
     *
     * @param is          输入流
     * @param isExcel2003 excel是2003还是2007版本
     * @return
     * @throws IOException
     */
    public List<Menu> createExcel(InputStream is, boolean isExcel2003) {
        List<Menu> menuList = null;
        try {
            Workbook wb = null;
            if (isExcel2003) {// 当excel是2003时,创建excel2003
                wb = new HSSFWorkbook(is);
            } else {// 当excel是2007时,创建excel2007
                wb = new XSSFWorkbook(is);
            }
            menuList = readExcelValue(wb);// 读取Excel里面客户的信息
        } catch (IOException e) {
            e.printStackTrace();
        }
        return menuList;
    }

    /**
     * 读取Excel里面客户的信息
     *
     * @param wb
     * @return
     */
    private List<Menu> readExcelValue(Workbook wb) {
        // 得到第一个shell
        Sheet sheet = wb.getSheetAt(0);
        // 得到Excel的行数
        this.totalRows = sheet.getPhysicalNumberOfRows();
        System.out.println("行数:" + this.totalRows);
        // 得到Excel的列数(前提是有行数)
        if (totalRows > 1 && sheet.getRow(0) != null) {
            this.totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
            System.out.println("总列数:" + this.totalCells);
        }
        List<Menu> menuList = new ArrayList<Menu>();
        // 循环Excel行数
        for (int r = 1; r < totalRows; r++) {
            Row row = sheet.getRow(r);
            if (row == null) {
                continue;
            }
            Menu menu = new Menu();
            // 循环Excel的列
            for (int c = 0; c < this.totalCells; c++) {
                Cell cell = row.getCell(c);
                if (null != cell) {
                    if(c==0){
                        if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                            String name = String.valueOf(cell.getNumericCellValue());
                            menu.setMenuname(name);
                        } else {
                            menu.setMenuname(cell.getStringCellValue());
                        }
                    }else if(c==1){
                        //如果是纯数字,比如你写的是25,cell.getNumericCellValue()获得是25.0,通过截取字符串去掉.0获得25
                        if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                            try {
                                menu.setPrice(Float.valueOf((float) cell.getNumericCellValue()));
                            } catch (NumberFormatException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                System.out.println("if false");
                            }
                        } else {
                            try {
                                menu.setPrice(Float.valueOf(cell.getStringCellValue()));
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                System.out.println("类型不匹配");
                            }
                        }
                    }else if(c==2){
                        if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                            String image = String.valueOf(cell.getNumericCellValue());
                            menu.setImage(image);
                        } else {
                            menu.setImage(cell.getStringCellValue());
                        }
                    }else if(c==3){
                        if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                            String description = String.valueOf(cell.getNumericCellValue());
                            menu.setDescription(description);
                        } else {
                            menu.setDescription(cell.getStringCellValue());
                        }
                    }else if(c==4){
                        if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                            try {
                                menu.setKucun(Integer.valueOf((int) cell.getNumericCellValue()));
                            } catch (NumberFormatException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                System.out.println("if false");
                            }
                        } else {
                            try {
                                menu.setKucun(Integer.valueOf(cell.getStringCellValue()));
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                System.out.println("类型不匹配");
                            }
                        }
                    }
                }
                }
            // 添加到list
            menuList.add(menu);
        }
        return menuList;
    }

    /**
     * 验证EXCEL文件
     *
     * @param filePath
     * @return
     */
    public boolean validateExcel(String filePath) {
        if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))) {
            errorMsg = "文件名不是excel格式";
            return false;
        }
        return true;
    }

    /**
     * 是否是2003的excel,返回true是2003
     * @param filePath
     * @return
     */
    public static boolean isExcel2003(String filePath) {
        return filePath.matches("^.+\\.(?i)(xls)$");
    }

    /**
     * 是否是2007的excel,返回true是2007
     * @param filePath
     * @return
     */
    public static boolean isExcel2007(String filePath) {
        return filePath.matches("^.+\\.(?i)(xlsx)$");
    }
}

编写Dao接口

根据梳理的流程,得:

  1. 根据菜名查询id的方法;
  2. 根据id更新数据库的方法;
  3. 新增数据的方法;
package com.qiang.dao;

import com.qiang.domain.Menu;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @author Mr.锵
 * date 2020-02-21
 */
@Repository
public interface IMenuDao {

    /**
     * 根据menuname查询菜单id
     * @param menuname
     */
    @Select("select menuid from menu where menuname=#{menuname}")
    String findIdByMenuname(String menuname);

    /**
     * 更新菜单
     * @param menu
     */
    @Update("update menu set menuname=#{menuname},image=#{image},status=#{status},kucun=#{kucun},price=#{price},description=#{description} where menuid=#{menuid}")
    void updateMenu(Menu menu);

    /**
     * 保存菜单
     * @param menu
     */
    @Insert("insert into menu(menuname,image,kucun,description,price)values(#{menuname},#{image},#{kucun},#{description},#{price})")
    void saveMenu(Menu menu);
}

编写service接口及实现类

package com.qiang.service;

import com.github.pagehelper.PageInfo;
import com.qiang.domain.Menu;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author Mr.锵
 * date 2020-02-21
 */
public interface IMenuService {
     /**
     * 批量保存菜谱信息
     * @param file
     * @return
     */
    String readExcelFile(MultipartFile file);

实现类

package com.qiang.service.impl;

import com.qiang.dao.IMenuDao;
import com.qiang.domain.Menu;
import com.qiang.service.IMenuService;
import com.qiang.utils.ReadExcel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Mr.锵
 * date 2020-02-21
 */
@Service("menuService")
public class IMenuServiceImpl implements IMenuService {
    @Autowired
    private IMenuDao menuDao;
    @Override
    public String readExcelFile(MultipartFile file) {
        //创建处理EXCEL的类
        ReadExcel readExcel=new ReadExcel();
        //解析excel,获取上传的事件单
        List<Menu> menuList = null;
        int insertResult = 0;
        String insertMsg = "";
        try {
            menuList = readExcel.getExcelInfo(file);
            //将excel中的数据转换到list里面
            //数据库插入
            for(Menu menu:menuList) {
                String menuid = menuDao.findIdByMenuname(menu.getMenuname());
                if(menuid==null){
                menuDao.saveMenu(menu);
                }else{
                    menu.setMenuid(menuid);
                    menu.setStatus("上架");
                    menuDao.updateMenu(menu);
                }
                insertResult=insertResult+1;
            }
            if(insertResult ==0) {
                insertMsg = "All insert false";
            }else if(insertResult == menuList.size()){
                insertMsg = "All insert success";
            }else {
                insertMsg = "Part insert success";
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("接受excel表格中的数据失败!!!");
        }
        return insertMsg;
    }
}

编写控制器

package com.qiang.controller;

import com.qiang.domain.Menu;
import com.qiang.service.IMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.github.pagehelper.PageInfo;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * @author Mr.锵
 * date 2020-02-21
 */
@Controller
@RequestMapping("/menu")
public class MenuController {
    @Autowired
    private IMenuService menuService;
    @RequestMapping(value="uploadMenu",method= {RequestMethod.POST})
    public void uploadMenu(@RequestParam(value="file_excel") MultipartFile file,HttpServletRequest request, HttpServletResponse response)throws Exception{
        String readResult =null;
        try {
            readResult = menuService.readExcelFile(file);
            System.out.println(readResult);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("upload falure");
        }
    }
}

编写jsp页面

原生的 < input >标签file类型比较丑,所以我们自己写一个然后调用原生的标签提交表单实现功能

<body>
	<div>
		<input class="form-control" id="fliename" disabled/>
		<input class="btn btn-primary" type="button" onclick="$('#file_excel').click();" value="上传文件"/>
		<input class="btn btn-success" type="button" onclick="$('#btn_excel').click();" value="提交"/>
	</div>
	<div id="hidden_file_div" style="display:none">
    	<form id="form_excel" name="form_excel"  action="../menu/uploadMenu" method="post" enctype="multipart/form-data">
        	<input type="file" id="file_excel" name="file_excel" onchange="$('#fliename').val($('#file_excel').val())" />
        	<input type="submit" class="btn btn-success" id="btn_excel"/>
    	</form>
    </div>
</body>

简单下载

最简单的下载文件就是把文件放到静态目录下,通过a标签访问
在这里插入图片描述

<a class="btn btn-info" href="../file/饭店菜谱模板.xlsx">下载模板</a>

在这里插入图片描述
在这里插入图片描述

结尾

主要原理就是工具类解析完Excel文件后把数据封装到List中,然后就可以用List中的数据做各种操作了,增加更新删除查询,甚至Excel中导入的数据可以涉及多表,例如菜的类型,在导入的时候就要查询有没有该类型,进行新增/更新操作等等。

感觉有用就点个赞呗~

下一篇Echarts框架图表统计

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值