SpringBoot通過Ajax批量將excel中數據導入數據庫


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表格要導入的數據

數據庫初始數據
添加前的數據庫
要插入的表格數據
要插入的表格數據

網頁導入表格

導入excel表格

結果

返回的信息
返回的信息
添加后的數據庫信息

導入后的數據庫信息

小結

特別注意一點 UserController文件中獲取文件名的方法,千萬不要寫成了 String fileName = excelFile.getName(),而是要用excelFile.getOriginalFilename()方法,這樣才能獲得文件名


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM