本文參考於:https://zhuanlan.zhihu.com/p/83965845
我這里用的是springBoot來寫的,用的依賴在下面:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--引入web依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--引入數據庫連接驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--引入java操作excel的api-->
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
<!--引入poi-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<!--引入上傳文件的依賴-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!--引入mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!--導入lang的工具包-->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
//ps:第一部分:controller層
@RestController
@RequestMapping("/user")
public class UploadExcelController {
@Resource
TestImportMapper testImportMapper;
/**
* 導入Excel
* @param userInformation
* @return
*/
@RequestMapping("/uploadExcel")
public String uploadExcel(UserInformation userInformation){
MultipartFile file = userInformation.getSelectExcel();
String type = userInformation.getSelectType();
String flag = userInformation.getFlag();
System.out.println("type為:" + type);
System.out.println("flag為:" + flag);
String errorMsg ="";
System.out.println(file.getOriginalFilename());
if (StringUtils.isNotBlank(type) && type.equals("excel") && StringUtils.isNotBlank(flag) && flag.equals("1")){
ReadExcel readExcel = new ReadExcel();
List<User> userList = null;
try {
userList = readExcel.getExcelInfo(file);
errorMsg = readExcel.getErrorMsg();
//如果沒有返回出錯信息,保存導入的信息
if (errorMsg.equals("")) {
testImportMapper.insertUser(userList);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(errorMsg);
//System.out.println(userList.toString());
}
return errorMsg;
}
//ps:這里我是參考上邊鏈接那里,把讀取Excel這部分獨立出來,單獨寫了一個類,在下面:
package com.example.testimport.tool;
import com.example.testimport.entity.User;
import org.apache.poi.hssf.usermodel.HSSFCell;
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.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* 讀取導入的Excel
*/
public class ReadExcel {
//總行數
private int totalRows = 0;
//總列數
private int totalCells = 0;
//錯誤信息
private String errorMsg = "";
public int getTotalRows() {
return totalRows;
}
public int getTotalCells() {
return totalCells;
}
public String getErrorMsg() {
return errorMsg;
}
/**
* 獲取導入的Excel,進行轉換
* @param file
* @return
*/
public List<User> getExcelInfo(MultipartFile file) {
List<User> userList = null;
String filename = file.getOriginalFilename();//獲取文件名稱
try {
if(!validateExcel(filename)){//校驗文件
return null;
}
//校驗是否是2003的Excel文件
boolean isExcel2003 = true;
if (isExcel2007(filename)) {
isExcel2003 = false;
}
//創建Excel
userList = creatExcel(file.getInputStream(), isExcel2003);
} catch (Exception e) {
e.printStackTrace();
}
return userList;
}
/**
* 創建Excel,並把值賦給實體類
* @param stream
* @param isExcel2003
* @return
*/
private List<User> creatExcel (InputStream stream, boolean isExcel2003) {
List<User> userList = null;
try {
Workbook workbook;
//判斷是否是2003Excel,還是2007Excel
if(isExcel2003){//為true,創建2003Excel
workbook = new HSSFWorkbook(stream);
} else {
workbook = new XSSFWorkbook(stream);
}
//讀取Excel里面的信息,並付給實體類
userList = readeExcelValue(workbook);
} catch (Exception e) {
e.printStackTrace();
}
return userList;
}
/**
* 讀取Excel內的數據,並寫入到實體類中
* @param workbook
* @return
*/
private List<User> readeExcelValue (Workbook workbook) {
List<User> userList = new ArrayList<>();
//獲取第一個sheet頁
Sheet sheet = workbook.getSheetAt(0);
//獲取第一個sheet總行數
this.totalRows = sheet.getPhysicalNumberOfRows();
//獲取列數(前提得有行以及行中有數據)
if(totalRows > 1 && null != sheet.getRow(0)){
this.totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
}else {
this.errorMsg = "請輸入您要錄入的信息!";
return null;
}
//循環遍歷行數
for(int i = 1; i < totalRows; i++) {
//獲取每一行
Row row = sheet.getRow(i);
if(row == null){//如果行為空,退出本次循環
continue;
}
//循環遍歷列
User user = new User();
for(int j = 0; j < totalCells; j++) {
Cell cell = row.getCell(j);//獲取每一行對應的列
if(null != cell) {//如果每一列有數據
//每一行第一條數據
if(j == 0){
//判斷數據格式,如果是純數字,比如你寫的是25,cell.getNumericCellValue()獲得的是25.0
if(cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
String value = String.valueOf(cell.getNumericCellValue());
user.setName(value.substring(0, value.length()-2 > 0?value.length()-2:1));
}else if(cell.getCellType() == HSSFCell.CELL_TYPE_BLANK){//若單元格為空
this.errorMsg = "第" + i + "行,第一列數據為空,請輸入數據后在重新導入!";
return null;
} else {
user.setName(cell.getStringCellValue());
}
}
//每一行第二條數據
else if(j == 1) {
//純數字類型,需要截取
if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
String value = String.valueOf(cell.getNumericCellValue());
user.setName(value.substring(0, value.length()-2 > 0?value.length()-2:1));
} else if (cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {//若單元格為空
this.errorMsg = "第" + i + "行,第二列數據為空,請輸入數據后在重新導入!";
return null;
} else {
user.setSex(cell.getStringCellValue());
}
} else if (j == 2) {
if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
String value = String.valueOf(cell.getNumericCellValue());
int age = Integer.parseInt(value);
user.setAge(age);
} else if (cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {//若單元格為空
this.errorMsg = "第" + i + "行,第三列數據為空,請輸入數據后在重新導入!";
return null;
} else {
user.setAge(0);
}
}
}
}
//保存到集合中
userList.add(user);
}
return userList;
}
/**
* 校驗文件是否是Excel格式
* @param filePath
* @return
*/
private boolean validateExcel(String filePath) {
//校驗格式是否正確,只要是Excel任意一種格式即可
if(filePath != null && isExcel2003(filePath) || isExcel2007(filePath)) {
return true;
} else {
this.errorMsg = "請上傳Excel格式的文件";
return false;
}
}
/**
* 是否是2003的Excel,返回true是
* @param filePath
* @return
*/
private boolean isExcel2003(String filePath){
return filePath.matches("^.+\\.(?i)(xls)$");
}
/**
* 是否是2007的Excel,返回true是
* @param filePath
* @return
*/
private boolean isExcel2007(String filePath){
return filePath.matches("^.+\\.(?i)(xlsx)$");
}
}
//application.properties配置文件中的配置,如下:
#指定應用名稱和端口號
spring.application.name=Test_Import
server.port=8888
#指定靜態資源路徑
spring.resources.static-locations=classpath:/
#配置數據源
spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8&&serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#設置上傳文件的大小和請求頭的大小
spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=20MB
#設置上傳的路徑,和編碼方式
spring.servlet.multipart.location=D:/home/data/temp
#設置xml的路徑
mybatis.mapper-locations=classpath:mapper/*.xml
//下面就是頁面代碼,寫的有點亂
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上傳Excel文件</title>
</head>
<body>
<form id="form" action="/user/uploadExcel" method="post" enctype="multipart/form-data">
<label>請選擇你要上傳的Excel</label>
<input id="uploadFile" type="file" name="selectExcel" />
<input type="button" onclick="submitExcel()" value="提交" />
<input type="hidden" id="selectType" name="selectType" value="excel" />
<input type="hidden" id="flag" name="flag" value="1" />
<br>
<label style="background-color: red;"><a href="#" id="downLoadTemplate" style="text-decoration: none;cursor:pointer" onclick="downLoadTemplate()">下載模板</a></label>
<label style="background-color: red;"><a href="/static/模板.xlsx" style="text-decoration: none;cursor:pointer">下載模板</a></label>
</form>
</body>
<script type="text/javascript">
//導入Excel
function submitExcel() {
var form = document.getElementById('form');
var uploadFile = document.getElementById("uploadFile");
var selectType = document.getElementById("selectType").value;
var flag = document.getElementById("flag").value;
var url = "/user/uploadExcel"
var formData = new FormData(form);
if(uploadFile.value == null || uploadFile.value.trim() == '') {
alert("請選擇您要上傳的文件!");
return;
}
if(uploadFile.value.lastIndexOf(".xls") < 0 || uploadFile.value.lastIndexOf(".xlsx") < 0) {
alert("只能上傳Excel文件!");
uploadFile.value = "";
return;
}
//判斷游覽器是否是IE7 8,不是的話用第一個request 是的話用第二個request
var xmlHttp = null;
if (XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
};
xmlHttp.open('POST',url);//打開請求的后台
//請求頭不要設置,使用默認的,服務器解析會自動選擇與之匹配的
//xmlHttp.setRequestHeader('Content-Type','multipart/form-data;boundary=ebf9f03029db4c2799ae16b5428b06bd');//設置請求頭
xmlHttp.send(formData);//發送數據
//請求的狀態
xmlHttp.onreadystatechange = function () {
//根據狀態,判斷是否請求成功
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
alert(JSON.parse(xmlHttp.responseText));
}
};
}
//下載Excel模板
function downLoadTemplate() {
var downLoadTemplate = document.getElementById("downLoadTemplate");
//window.location="/static/模板.xlsx";
//測試js移除點擊事件,以及設置點擊事件
downLoadTemplate.removeAttribute('onclick');
downLoadTemplate.setAttribute("onclick","sendMessage('1')");
//發送請求下載模板
//判斷游覽器是否是IE7 8,不是的話用第一個request 是的話用第二個request
var xmlHttp = null;
if (XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');//IE游覽器訪問
};
var url = '/user/downloadExcelTemplate';
var method = 'get';
xmlHttp.open(method,url);
xmlHttp.onreadystatechange = function () {
//判斷請求是否成功
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
alert(JSON.parse(xmlHttp.responseText));
}
}
}
function sendMessage(infor) {
alert(infor);
}
</script>
</html>