近期公司需要搞一套suuuuuuuuuuuper先进的员工管理系统,以取代原来的原始办公室办公。其中涉及到了【将Excel表数据批量输入MySQL数据库】的操作,所以酸某鱼打算用springboot搞一个工具来实现这个功能。
org.apache.poi
poi
3.16
org.apache.poi
poi-ooxml
3.14
org.apache.tomcat.embed
tomcat-embed-jasper
provided
<%@ 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>
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;
}
}
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 type="file" name="file">
这是因为eclipse默认认为使用4版本及以上的poi包,此博客用的是3.16版本的poi包,不会影响程序的运行。
".“符号属于正则表达式的一部分,如果在split函数里需要识别“.”符号,需要利用“\”符号进行转义。同时注意符号”"也是正则表达式的一部分,因此需要双重转义。正确的写法是:“\\.”
原因出现在controller层里service层对象的创建,如果是手动new出来的service对象,service层@Autowired标签创建的对象不会进入库中,因此也无法通过标签创建。正确的做法是:在controller层里也用@Autowired标签创建service层对象。