Spring boot实现Excel文件数据导入MySQL数据库

  • 目录
    —背景
    —需要添加的依赖
    —源码
    —代码讲解
    —可能的问题

背景

近期公司需要搞一套suuuuuuuuuuuper先进的员工管理系统,以取代原来的原始办公室办公。其中涉及到了【将Excel表数据批量输入MySQL数据库】的操作,所以酸某鱼打算用springboot搞一个工具来实现这个功能。

需要添加的依赖

  1. org.apache.poi
 
        
            org.apache.poi
            poi
            3.16
        

        
   		 	org.apache.poi
   		 	poi-ooxml
   		 	3.14
		
  1. org.apache.tomcat.embed

		
			org.apache.tomcat.embed
			tomcat-embed-jasper
			provided
		

源码

项目结构:

Spring boot实现Excel文件数据导入MySQL数据库_第1张图片

前端页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传excel</title>
</head>
<body>
<h1>上传excel文件并存入到mysql数据库</h1>
<form action="uploadexcel.action" method="post" enctype="multipart/form-data">
    <p>文件上传</p>
    <input type="file" name="file">
    <p><input type="submit" value="上传"></p>
</form>
		<span style="color:red">${message}</span>

</body>
</html>

controller层:

package com.langsin.controller;

import java.io.File;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.langsin.service.ExcelService;



@Controller
public class ExcelCon {
	
	@Autowired
	ExcelService service;
	/**
	 * 初始界面
	 * @param request
	 * @param response
	 * @param session
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/exceltrans.action") //url
	public ModelAndView exceltrans(HttpServletRequest request, HttpServletResponse response, HttpSession session, Model  model) {
		ModelAndView modelAndView = new ModelAndView();  //视图对象
		modelAndView.setViewName("exceltrans");  //展示页面
		return modelAndView;
	}
	/**
	 * 上传Excel文件
	 * @param file
	 * @param request
	 * @param response
	 * @param session
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/uploadexcel.action") //url
	public ModelAndView uploadexcel(MultipartFile file,HttpServletRequest request, HttpServletResponse response, HttpSession session, Model  model) {
		ModelAndView modelAndView = new ModelAndView();   //视图对象
		Boolean flag = false;    //结果判断标记
		String fileName = file.getOriginalFilename();  //获取Excel文件名
		try {
			flag = service.batchImport(fileName, file);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (flag==false) {  //判断上传结果
			modelAndView.addObject("message","上传失败,请重试");
		}else {
			modelAndView.addObject("message","上传成功");
		}
		modelAndView.setViewName("exceltrans"); //视图名称
		return modelAndView;
	}
}

service层:

package com.langsin.service;

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

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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import org.springframework.web.multipart.MultipartFile;

import com.langsin.mapper.StuMapper;
import com.langsin.pojo.Stu;
import com.langsin.pojo.StuExample;



@Service
public class ExcelService {
	
	@Autowired
	StuMapper stuMapper;
	
	public boolean batchImport(String fileName, MultipartFile file) throws Exception {
		boolean notNull = false;    //文件非空判断标记
		List<Stu> stuList = new ArrayList<>();  //承载Excel文件数据的集合
		/*
		 * 判断文件名的合法性
		 * 判断文件是2003版or2007版
		 */
		String[] fullName =  fileName.split("\\.");
		System.out.println(fullName[1]);
		String suffix = fullName[1];
		if (suffix.equals("xls") && suffix.equals("xlsx")) {
            throw new Exception("上传不正确");
        }
		boolean isExcel2003 = true;
		if (suffix.equals("xlsx")) {
	            isExcel2003 = false;
	    }
		
		InputStream iStream = file.getInputStream(); //IO流
		Workbook workbook = null; //创建工作簿
		if (isExcel2003) {
			workbook = new HSSFWorkbook(iStream); //2003版
		}else {
			workbook = new XSSFWorkbook(iStream); //2007版
		}
		
		/*
		 * 读取工作簿里的表
		 * 检验文件是否为空
		 */
		Sheet sheet = workbook.getSheetAt(0);
		if (sheet!=null) {
			notNull = true;
		}
		
		/*
		 * 读取表里的数据行
		 */
		for (int r = 1; r <= sheet.getLastRowNum(); r++) { //r=1是从第二行开始读数据
			Row row = sheet.getRow(r); //读行
			if (row==null) { //规避空行
				continue;
			}
			
			Stu student = new Stu(); //行数据对象
			
			/*
			 * 获取整行信息
			 */
			row.getCell(0).setCellType(Cell.CELL_TYPE_STRING);
			String studentId = row.getCell(0).getStringCellValue();
			if (studentId==null || studentId.isEmpty()) {  //确保主键对应的信息不为空
				throw new Exception("导入失败,第"+(r+1)+"行,编号未填写");
			}
			row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
			row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
			row.getCell(3).setCellType(Cell.CELL_TYPE_STRING);
			row.getCell(4).setCellType(Cell.CELL_TYPE_STRING);
			row.getCell(5).setCellType(Cell.CELL_TYPE_STRING);
			row.getCell(6).setCellType(Cell.CELL_TYPE_STRING);
			row.getCell(7).setCellType(Cell.CELL_TYPE_STRING);
			String studentName = row.getCell(1).getStringCellValue();
			String studentAge = row.getCell(2).getStringCellValue();
			String studentSex = row.getCell(3).getStringCellValue();
			String studentTele = row.getCell(4).getStringCellValue();
			String studentEmail = row.getCell(5).getStringCellValue();
			String studentSchool = row.getCell(6).getStringCellValue();
			String studentGrade = row.getCell(7).getStringCellValue();
			/*
			 * 填充信息到行数据对象
			 */
			student.setSid(studentId);
			student.setSname(studentName);
			student.setSage(studentAge);
			student.setSex(studentSex);
			student.setTele(studentTele);
			student.setEmail(studentEmail);
			student.setSchool(studentSchool);
			student.setGrade(studentGrade);
			
			stuList.add(student); //行数据对象存入Excel数据集合
		}
		
		for (Stu stu : stuList) {
			/*
			 * 判断数据库里有无Excel表数据
			 * 无--->插入操作
			 * 有--->更新操作
			 */
			String stuId = stu.getSid();
			StuExample example = new StuExample();
			example.createCriteria().andSidEqualTo(stuId);
			List<Stu> stuInfo= stuMapper.selectByExample(example);
			int result = stuInfo.size();
			if (result == 0) {  //
				stuMapper.insert(stu);
				System.out.println("插入"+stu);
			}else {
				stuMapper.updateByPrimaryKeySelective(stu);
				System.out.println("更新"+stu);
			}
		}
		
		return notNull; 
		
	}
	
}

代码讲解

  • 前端页面:
    前端页面用了一个input标签,完成了前端向后端传输Excel文件
<input type="file" name="file">
  • controller层:
    controller层第一个方法负责展示基础页面,第二个方法负责承接前端上传的Excel文件,并完成对数据的解析与转储。并且在动作结束后向前端发送反馈信息。
  • service层:
    service层先对文件名进行了检验,检验通过后用org.apache.poi包里的方法,把Excel表的数据解析后转存到集合里。然后与数据库信息进行比对,分别插入或更新数据到MySQL。

可能的问题

为什么service层调用的cell方法会报警?

这是因为eclipse默认认为使用4版本及以上的poi包,此博客用的是3.16版本的poi包,不会影响程序的运行。

为什么我的正则表达式split函数无法识别“.”?

".“符号属于正则表达式的一部分,如果在split函数里需要识别“.”符号,需要利用“\”符号进行转义。同时注意符号”"也是正则表达式的一部分,因此需要双重转义。正确的写法是:“\\.”

为什么我service层用@Autowired标签创建的对象是Null?

原因出现在controller层里service层对象的创建,如果是手动new出来的service对象,service层@Autowired标签创建的对象不会进入库中,因此也无法通过标签创建。正确的做法是:在controller层里也用@Autowired标签创建service层对象。

你可能感兴趣的:(Spring,Boot开发)