SpringBoot + Vue 如何實現導入Excel操作,這篇文章幫你解決!

題外話

1.所用框架

  • 後端技術棧 Spring Boot
  • 前端技術棧 Vue

2.後端接口實現

  • 導入 POI 依賴
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>4.1.2</version>
</dependency>
  • 創建導入 Excel 接口
  • 導入 Excel 操作我們可以分爲3個步驟:
  1. 首先獲取到用戶上傳的 Excel 文件
  2. 解析 Excel 文件,將 Excel 解析成數據庫所需要的數據
  3. 進行數據庫添加操作
  • 後端接口如何設計,代碼如下:
	/**
     * 導入 Excel 數據
     *
     * @param file 你要導入的 Excel 文件
     * @return
     * @throws IOException
     */
	@PostMapping("/import")
    public RespBean importData(MultipartFile file) throws IOException {
    	// 1.自定義一個工具類拿到要解析的文件並解析成要存儲的數據
        List<Employee> list = POIUtils.excel2Employee(file);
        // 2.遍歷輸出你解析的數據格式是否正確
        for (Employee employee : list) {
            System.out.println(employee.toString());
        }
        // 3.進行數據庫添加操作
        if (employeeService.addEmp(list) == 1) {
            return RespBean.ok("上傳成功!");
        }
        return RespBean.error("上傳失敗!");
    }
  • 上文中出現的 RespBean 返回值是我項目中自定義的響應類,目的就是爲了告訴前端成功或者失敗而定義的一個工具類,代碼如下:
/**
 * 響應結果類
 */
public class RespBean {
	// 自定義狀態碼
    private Integer status;
    // 自定義響應消息內容
    private String msg;
    // 自定義返回的對象
    private Object obj;

    public static RespBean build() {
        return new RespBean();
    }
	
	// 響應成功返回 200 正確消息 msg
    public static RespBean ok(String msg) {
        return new RespBean(200,msg,null);
    }

	// 相應成功返回 200 正確消息 msg 以及要返回的對象 obj
    public static RespBean ok(String msg,Object obj) {
        return new RespBean(200,msg,obj);
    }

	// 響應成功返回 500 錯誤消息 msg
    public static RespBean error(String msg) {
        return new RespBean(500,msg,null);
    }

	// 相應成功返回 500 錯誤消息 msg 以及要返回的對象 obj
    public static RespBean error(String msg,Object obj) {
        return new RespBean(500,msg,obj);
    }

    private RespBean() {

    }

    private RespBean(Integer status, String msg, Object obj) {
        this.status = status;
        this.msg = msg;
        this.obj = obj;
    }

    public Integer getStatus() {
        return status;
    }

    public RespBean setStatus(Integer status) {
        this.status = status;
        return this;
    }

    public String getMsg() {
        return msg;
    }

    public RespBean setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    public Object getObj() {
        return obj;
    }

    public RespBean setObj(Object obj) {
        this.obj = obj;
        return this;
    }
}
  • POIUtils工具類方法代碼實現:
	/**
     * Excel 解析成數據集合
     *
     * @return
     */
    public static List<Employee> excel2Employee(MultipartFile file) {
        List<Employee> list = new ArrayList<>();
        Employee employee = null;
        try {
            //1. 創建一個 workbook 對象
            HSSFWorkbook workbook = new HSSFWorkbook(file.getInputStream());
            //2. 獲取 workbook 中表單的數量
            int numberOfSheets = workbook.getNumberOfSheets();
            for (int i = 0; i < numberOfSheets; i++) {
                //3. 獲取表單
                HSSFSheet sheet = workbook.getSheetAt(i);
                //4. 獲取表單中的行數
                int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
                for (int j = 0; j < physicalNumberOfRows; j++) {
                    //5. 跳過標題行
                    if (j == 0) {
                        continue;//跳過標題行
                    }
                    //6. 獲取行
                    HSSFRow row = sheet.getRow(j);
                    if (row == null) {
                        continue;//防止數據中間有空行
                    }
                    //7. 獲取列數
                    int physicalNumberOfCells = row.getPhysicalNumberOfCells();
                    employee = new Employee();
                    for (int k = 0; k < physicalNumberOfCells; k++) {
                        HSSFCell cell = row.getCell(k);
                        switch (cell.getCellType()) {
                        	// 類型是 String 進入此 case 塊
                            case STRING:
                                String cellValue = cell.getStringCellValue();
                                switch (k) {
                                    case 1:
                                        employee.setName(cellValue);
                                        break;
                                    case 2:
                                        employee.setWorkID(cellValue);
                                        break;
                                    case 3:
                                        employee.setGender(cellValue);
                                        break;
                                    case 5:
                                        employee.setIdCard(cellValue);
                                        break;
                                    case 6:
                                        employee.setWedlock(cellValue);
                                        break;
                                    case 7:
                                        employee.setNationId(cellValue);
                                        break;
                                    case 8:
                                        employee.setNativePlace(cellValue);
                                        break;
                                    case 9:
                                        employee.setPoliticId(cellValue);
                                        break;
                                    case 10:
                                        employee.setPhone(cellValue);
                                        break;
                                    case 11:
                                        employee.setAddress(cellValue);
                                        break;
                                    case 12:
                                        employee.setDepartmentId(cellValue);
                                        break;
                                    case 13:
                                        employee.setJobLevelId(cellValue);
                                        break;
                                    case 14:
                                        employee.setPosId(cellValue);
                                        break;
                                    case 15:
                                        employee.setEngageForm(cellValue);
                                        break;
                                    case 16:
                                        employee.setTiptopDegree(cellValue);
                                        break;
                                    case 17:
                                        employee.setSpecialty(cellValue);
                                        break;
                                    case 18:
                                        employee.setSchool(cellValue);
                                        break;
                                    case 20:
                                        employee.setWorkState(cellValue);
                                        break;
                                    case 21:
                                        employee.setEmail(cellValue);
                                        break;
                                }
                                break;
                            // 類型是 Date或者數字 進入此 case 塊    
                            default: {
                                switch (k) {
                                    case 4:
                                        employee.setBirthday(cell.getDateCellValue());
                                        break;
                                    case 19:
                                        employee.setBeginDate(cell.getDateCellValue());
                                        break;
                                    case 23:
                                        employee.setBeginContract(cell.getDateCellValue());
                                        break;
                                    case 24:
                                        employee.setEndContract(cell.getDateCellValue());
                                        break;
                                    case 22:
                                        employee.setContractTerm(cell.getNumericCellValue());
                                        break;
                                    case 25:
                                        employee.setConversionTime(cell.getDateCellValue());
                                        break;
                                }
                            }
                            break;
                        }
                    }
                    // 最後將解析後的數據添加到員工集合中
                    list.add(employee);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

3.前端實現

  • 前端使用的樣式是 Element-UI 中的 upload 上傳組件,頁面製作代碼如下:
    1. :show-file-list 是否顯示已上傳文件列表
    2. :before-upload 上傳文件前的調用事件
    3. :on-success 上傳成功後的調用事件
    4. :on-error 上傳成功後的調用事件
    5. :disabled 是否禁用上傳組件
    6. action 要上傳的路徑
					<el-upload
                        :show-file-list="false"
                        :before-upload="beforeUpload"
                        :on-success="onSuccess"
                        :on-error="onError"
                        :disabled="importDisabled"
                        style="display: inline-flex;margin-right: 10px;"
                        action="這裏面填寫剛剛寫好的服務端接口路徑">
                    <el-button size="small" :disabled="importDisabled" type="success" :icon="importDataIcon">
                        {{importDataText}}
                    </el-button>
                </el-upload>
  • 數據定義,瞭解 Vue 的朋友們應該都知道這段代碼的含義,就是自定義幾個變量用來使用,這裏不過多解釋。大家不懂得可以去看 Vue 官網。
data(){
	return{
		// 導入按鈕的文本
		importDataText: '導入數據',
		// 導入按鈕的圖標
		importDataIcon: 'el-icon-upload2',
		// 導入按鈕是否被禁用
		importDisabled: false
	}
}
  • 方法實現,代碼如下:
methods: {
            // 導入文件失敗後回調
            onError() {
                this.importDataText = '導入數據';
                this.importDataIcon = 'el-icon-upload2';
                this.importDisabled = false;
                this.initEmps();
                this.$message.success("導入失敗!");
            },
            // 導入文件成功後回調
            onSuccess() {
            	// 成功後文本修改爲原來的導入數據
                this.importDataText = '導入數據';
                // 圖標修改
                this.importDataIcon = 'el-icon-upload2';
                // 將上傳組件改爲允許使用
                this.importDisabled = false;
                // 調用刷新數據的方法
                this.initEmps();
                // message 彈出消息
                this.$message.success("導入成功!");
            },
            // 上傳文件調用
            beforeUpload() {
            	// 將文本修改爲正在導入
                this.importDataText = '正在導入';
                // 修改其圖標
                this.importDataIcon = 'el-icon-loading';
                // 將其上傳組件暫時禁用
                this.importDisabled = true;
            }
}

4.結果截圖

  • 頁面中的上傳按鈕製作如圖:
    在這裏插入圖片描述
  • 選擇要上傳的 Excel 文件,大家可以自己作判斷上傳的文件是不是 Excel,由於我這裏沒有做判斷,大家可別學我,在真實的項目中還是要做的,前端做提升用戶體驗,後端做防止出錯。
    在這裏插入圖片描述
  • 正在導入中的按鈕也是不可以點擊的,這裏我們在事件中已經定義過了,圖標也顯示成正在加載的樣式,UI 界面還是非常不錯的。
    在這裏插入圖片描述
  • 導入成功的顯示導入成功,這裏我們可以去看下服務端接口打印的結果。
    在這裏插入圖片描述
  • 服務端打印的結果是正確的,這裏我們就完成了簡單的 Excel 導入功能。
    在這裏插入圖片描述

5.結語

  • 文中所用技術或許與你所用的技術不一樣,但是稍稍修改也是也可實現Excel導入功能的,這個其實沒有什麼技術點,代碼又不需要死記硬背,要用的時候拿過來用即可,如果各位看官有什麼問題,評論區留言或者私信我,我都會回覆你的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章