1. 程式人生 > >Spring-Boot實現Excel表資料匯入資料庫

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檔案就可以了

因為用的原生態程式碼,所以效率不高,不支援大量資料的匯入;如果想匯入大檔案,見下一篇文章
至此,有建議的歡迎留言討論
結束