Spring-Boot实现Excel表数据导入数据库

首先说一下用的工具:jdk8,mysql,mybatis,postman测试,
这次主要是实现历史学生信息导入功能,要求只是提示错误信息,将没错的导入;
好了,贴代码

pom导入依赖,貌似这个poi工具类不向下兼容

	<dependency>
	    <groupId>org.apache.poi</groupId>
	    <artifactId>poi-ooxml</artifactId>
	    <version>3.9</version>
	</dependency>

实体类就不贴代码了,很简单的几个字段
controller`package com.qhgctech.busi.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.qhgctech.busi.domain.StudentHist;
import com.qhgctech.busi.service.StudentHistService;
import com.qhgctech.core.controller.BaseController;

@RestController
@RequestMapping("/studenthist")
@Transactional(propagation = Propagation.REQUIRED)
public class StudentHistController extends BaseController {
private static Logger log = LoggerFactory.getLogger(StudentHistController.class);

@Autowired
private StudentHistService studentHistService;

/**
 * add by weiqs 20181203 导入历史学生信息
 */
@RequestMapping(value = "/import", method = RequestMethod.POST)
public Map<String, Object> exc(MultipartFile file, HttpServletRequest request) {

	Map<String, Object> res = new HashMap<String, Object>();

	// 判断文件是否为空
	if (file == null) {
		res.put("code", "10208");
		res.put("msg", "上传学生文件不能为空");
		return res;
	}

	// 2.判断上传内容是否符合要求
	String fileName = file.getOriginalFilename();

	// 判断是否是excel文件
	if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
		res.put("code", "10132");
		res.put("msg", "请上传正确格式的文件");
		return res;
	}

	String errMsg = studentHistService.batchImport(file);

	res.put("code", "10207");
	res.put("msg", errMsg);
	return res;
}

}
`
serviceImpl实现层,已忽略service层:

package com.qhgctech.busi.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.POIXMLDocument;
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.multipart.MultipartFile;

import com.qhgctech.busi.domain.StudentHist;
import com.qhgctech.busi.service.StudentHistService;
import com.qhgctech.core.service.impl.AbstractBaseService;

@Service
public class StudentHistServiceImpl extends AbstractBaseService<StudentHist> implements StudentHistService {

	@Autowired
	private StudentHistService studentHistService;

	/**
	 * 上传excel文件到临时目录后并开始解析
	 * 
	 * @param fileName
	 * @param file
	 * @param userName
	 * @return
	 */
	public String batchImport(MultipartFile mfile) {

		File uploadDir = new File("F:\\Users\\xzxy\\excel\\upload\\");
		// 创建一个目录 (它的路径名由当前 File 对象指定,包括任一必须的父路径。)
		if (!uploadDir.exists())
			uploadDir.mkdirs();
		// 新建一个文件
		File tempFile = new File("F:\\Users\\xzxy\\excel\\upload\\" + new Date().getTime() + ".xlsx");
		// 初始化输入流
		InputStream is = null;
		try {
			// 将上传的文件写入新建的文件中
			mfile.transferTo(tempFile);

			// 根据新建的文件实例化输入流
			is = new FileInputStream(tempFile);

			// 根据版本选择创建Workbook的方式
			Workbook wb = null;

			// 判断文件是2003版本还是2007版本
			if (!is.markSupported()) {
				is = new PushbackInputStream(is, 8);
			}
			if (POIXMLDocument.hasOOXMLHeader(is)) {
				System.out.println("2007及以上");
				wb = new XSSFWorkbook(is);
			} else {
				System.out.println("2003及以下");
				wb = new HSSFWorkbook(is);
			}
			// 根据excel里面的内容读取知识库信息
			return readExcelValue(wb, tempFile);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					is = null;
					e.printStackTrace();
				}
			}
		}
		return "导入出错!请检查数据格式!";
	}

	/**
	 * 解析Excel里面的数据
	 * 
	 * @param wb
	 * @return
	 */
	private String readExcelValue(Workbook wb, File tempFile) {

		// 错误信息接收器
		String errorMsg = "";

		List<StudentHist> StudentHist = new ArrayList<StudentHist>();
		// 历史学生实体类
		StudentHist sh;

		for (int numSheet = 0; numSheet < wb.getNumberOfSheets(); numSheet++) {
			Sheet sheet = wb.getSheetAt(numSheet);

			// 得到Excel的行数
			int totalRows = sheet.getPhysicalNumberOfRows();
			// 总列数
			int totalCells = 0;
			// 得到Excel的列数(前提是有行数),从第二行算起
			if (totalRows >= 2 && sheet.getRow(1) != null) {
				totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
			}

			String br = "<br/>";

			System.out.println("总行数:" + totalRows + "总列数:" + totalCells);

			// 循环Excel行数,从第二行开始。标题不入库
			for (int r = 1; r < totalRows; r++) {
				String rowMessage = "";
				Row row = sheet.getRow(r);
				if (row == null || 0 == row.getPhysicalNumberOfCells()) {
					errorMsg += br + "第" + (r + 1) + "行数据为空,请仔细检查!";
					continue;
				}
				sh = new StudentHist();

				String name = "";		//学生姓名
				String clientName = "";			//学校名称(我们叫客户))
				Long userId;		//用户id
				String idcardNo = "";		//身份证号

				// 循环Excel的列
				for (int c = 0; c < totalCells; c++) {
					Cell cell = row.getCell(c);
					if (null != cell) {
						if (c == 0) {
							name = cell.getStringCellValue();
							if (StringUtils.isEmpty(name)) {
								rowMessage += "第" + (c + 1) + "列不能为空;";
							} else if (name.length() > 20) {
								rowMessage += "第" + (c + 1) + "列字数不能超过20;";
							}
							sh.setName(name);
							sh.setUserId(Long.valueOf(10001));
							sh.setIdcardNo("4209817327434234");
						} else if (c == 1) {
							clientName = cell.getStringCellValue();
							if (StringUtils.isEmpty(clientName)) {
								rowMessage += "第" + (c + 1) + "列不能为空;";
							} else if (clientName.length() > 50) {
								rowMessage += "第" + (c + 1) + "列字数不能超过50;";
							}
							sh.setClientName(clientName);
						} else if (c == 2) {
							userId = Math.round(cell.getNumericCellValue());
							if (0==(userId)) {
								rowMessage += "第" + (c + 1) + "列不能为空且不能为0;";
							}
							sh.setUserId(userId);
						} else if (c == 3) {
							idcardNo = cell.getStringCellValue();
							if (StringUtils.isEmpty(idcardNo)) {
								rowMessage += "第" + (c + 1) + "列不能为空;";
							} else if (idcardNo.length() != 18) {
								rowMessage += "第" + (c + 1) + "列身份证号码必须是18位;";
							}
							sh.setClientName(idcardNo);
						}
					} else {
						rowMessage += "第" + (c + 1) + "列不能为空;";
					}
				}
				// 拼接每行的错误提示
				if (!StringUtils.isEmpty(rowMessage)) {
					errorMsg += br + "第" + (r + 1) + "行," + rowMessage;
				} else {
					StudentHist.add(sh);
				}
			}
		}

		// 删除上传的临时文件
		if (tempFile.exists())

		{
			tempFile.delete();
		}

		// 全部验证通过才导入到数据库
		// if (StringUtils.isEmpty(errorMsg)) {
		// 将没有问题的数据导入数据库
		for (StudentHist studentHist : StudentHist) {

			studentHistService.save(studentHist);

		}
		// }
		errorMsg = "本次共成功导入" + StudentHist.size() + "条数据!其中" + errorMsg;
		return errorMsg;
	}
}

postman测试:
在这里插入图片描述postman就不说啥了,很简单,选择个excel文件就可以了

因为用的原生态代码,所以效率不高,不支持大量数据的导入;如果想导入大文件,见下一篇文章
至此,有建议的欢迎留言讨论
结束

猜你喜欢

转载自blog.csdn.net/weixin_43428157/article/details/84827599
今日推荐