Spring Boot通過Ajax上傳Excel並將資料批量讀取到資料庫中
適合場景:需要通過excel表格批量向資料庫中匯入資訊
操作流程
【1】前端上傳一個excel表格
【2】 後端接收這個excel表格,將表格中的資料存入List集合中
【3】後端通過這個List集合將資料批量填入資料庫中
原始碼地址:https://gitee.com/residual-temperature/import-excel-demo
實現過程
1、pom檔案中要加入的jar包
<!-- 匯入excel相關 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
因為加入這兩個jar包application.yml檔案中沒有新增配置,所以這裡就不展示
2、實體類User
@Repository
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private long id;
private String account;
private String password;
private String username;
private String address;
}
3、UserMapper檔案
@Mapper
@Repository
public interface UserMapper {
// 批量新增使用者資料
public int addBatchUser(List<User> userList);
// 根據使用者賬號查詢使用者資料
public User findUserByAccount(String account);
// 根據使用者賬號修改使用者資訊
public int updateUserByAccount(User user);
}
4、UserMapper.xml檔案的配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace= "com.yuwen.mapper.UserMapper" >
<!-- 批量匯入的實現 -->
<insert id="addBatchUser">
insert into user(account,password,username,address)
values
<foreach collection="userList" item="item" separator=",">
(
#{item.account},
#{item.password},
#{item.username},
#{item.address}
)
</foreach>
</insert>
<select id="findUserByAccount" resultType="com.yuwen.pojo.User">
select * from user where account = #{account}
</select>
<update id="updateUserByAccount">
update user set account = #{account},password = #{password},username = #{username},address = #{address}
where account = #{account}
</update>
</mapper>
因為UserService只有方法沒有實現,所以直接看UserService的實現類UserServiceImpl檔案
5、UserServiceImpl檔案
@Service
public class UserServiceImpl implements UserService {
@Resource
UserMapper userMapper;
@Resource
ImportExcelUtils excelUtils;
/**
* 批量新增使用者資訊
* @param userList 使用者資訊
* @return 使用者資訊是否新增成功
*/
@Override
public boolean addBatchUser(List<User> userList) {
return userMapper.addBatchUser(userList) > 0;
}
/**
* 根據使用者賬號檢視使用者是否存在
* @param account 使用者賬號
* @return 查詢到的使用者資訊
*/
@Override
public User findUserByAccount(String account) {
return userMapper.findUserByAccount(account);
}
/**
* 根據使用者賬號修改使用者資訊
* @param user 使用者資訊
* @return 是否修改成功
*/
@Override
public boolean updateUserByAccount(User user) {
return userMapper.updateUserByAccount(user) > 0;
}
/**
* 批量匯入使用者資訊
* @param fileName 匯入的表名
* @param is 匯入表的輸入流
* @return 是否匯入成功
*/
@Override
public boolean importUserInfo(String fileName, InputStream is){
try {
List<User> userList = excelUtils.upload(fileName, is);
for (int i = 0; i < userList.size(); i++) {
User user = findUserByAccount(userList.get(i).getAccount()); // 查詢資料庫中看這個使用者資訊是否存在
if (user != null){
updateUserByAccount(userList.get(i)); // 更新資料庫中的使用者資訊
userList.remove(i); // 移除更新後的使用者
i = i - 1; // 因為移除了,所以userList大小減了一而迴圈加了一,所以要減回去
}
}
return addBatchUser(userList); // 批量新增
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
6、UserController檔案
@RestController
public class UserController {
@Resource
UserService userService;
// 批量新增資料
@PostMapping("/upload")
public Map<String,String> upload(MultipartFile excelFile) throws Exception{
Map<String,String> map = new HashMap<>();
if (excelFile.isEmpty()){
map.put("mag","資料夾為空,重新上傳");
return map;
}else {
String fileName = excelFile.getOriginalFilename();
InputStream is = excelFile.getInputStream();
if (userService.importUserInfo(fileName,is)){
map.put("msg","資料新增成功");
return map;
}else {
map.put("msg","資料新增失敗,請重新新增");
return map;
}
}
}
}
7、匯入excel的工具類ImportExcelUtils的編寫
批量匯入的主要程式碼,主要呈現在這個工具類和上面UserMapper.xml中的批量匯入
@Component
public class ImportExcelUtils {
// 將表格中的資料新增到List集合中
public List<User> upload(String fileName, InputStream is) throws Exception{
Workbook workbook = getWorkbook(fileName,is);
List<User> userList = new ArrayList<>();
int number = workbook.getNumberOfSheets(); // 獲取sheet值
for (int i = 0; i < number; i++) {
Sheet sheet = workbook.getSheetAt(i); // 獲取表格頁碼
if (sheet != null){
int rowNum = sheet.getLastRowNum(); // 獲取該頁表共有多少行
for (int j = 1; j <= rowNum; j++) { // 一般來說第一行是標題,所以第二行開始讀取
Row row = sheet.getRow(j); // 獲取表格行
User user = new User();
row.getCell(0).setCellType(Cell.CELL_TYPE_STRING); // 將該單元格獲取出來的值設為String型別
user.setAccount(row.getCell(0).getStringCellValue()); // 獲取表格單元格並給User設定值
row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
user.setPassword(row.getCell(1).getStringCellValue());
row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
user.setUsername(row.getCell(2).getStringCellValue());
row.getCell(3).setCellType(Cell.CELL_TYPE_STRING);
user.setAddress(row.getCell(3).getStringCellValue());
System.out.println(user);
userList.add(user);
}
}
}
return userList;
}
// 判斷傳入的檔案是哪種型別的excel檔案
public Workbook getWorkbook(String fileName,InputStream is) throws Exception{
Workbook workbook = null;
String name = fileName.substring(fileName.lastIndexOf("."));
System.out.println(name);
if (".xls".equals(name)){
workbook = new HSSFWorkbook(is);
}else if (".xlsx".equals(name)){
workbook = new XSSFWorkbook(is);
}else {
throw new Exception(" 請上傳.xls/.xlsx格式檔案!");
}
return workbook;
}
}
8、html頁面的編寫
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上傳檔案</title>
<script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
<script>
function upload(){
var formData = new FormData(); //建立一個formData物件例項
var excelFile = $("#uploadFile").get(0).files[0];
formData.append("excelFile",excelFile)
$.ajax({
url: 'http://localhost:8081/upload',
data: formData,
type: 'post',
contentType:false, // 必須false才會自動加上正確的Content-Type
processData: false, // 必須false才會避開jQuery對 formdata 的預設處理,XMLHttpRequest會對 formdata 進行正確的處理
success: function (resp){
console.log(resp);
// 後續的操作
}
})
}
</script>
</head>
<body>
<p>上傳的檔案</p>
<input multiple="multiple" type="file" id="uploadFile">
<br>
<br>
<button onclick="upload()">上傳</button>
</body>
</html>
因為這個專案主要是為了excel的讀取和匯入到資料庫,所以就沒有進行後續的操作了
專案測試
匯入前的資料庫和excel表格要匯入的資料
資料庫初始資料
要插入的表格資料
網頁匯入表格
結果
返回的資訊
新增後的資料庫資訊
小結
特別注意一點 UserController檔案中獲取檔名的方法,千萬不要寫成了 String fileName = excelFile.getName(),而是要用excelFile.getOriginalFilename()方法,這樣才能獲得檔名