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