文章目錄
- 前言
- 使用
- 在vue文件中的使用
前言
最近寫小組官網涉及到了excel文件導入的功能 場景是導入小組成員年級 班級 郵箱 組別 姓名等基本信息的excel表格用于展示各組信息
使用
先下載js庫
npm install xlsx
為了提高代碼的復用性 我將它寫成了一個通用的函數
import apiClient from "@/api/axios";
import * as XLSX from "xlsx";interface UserData {姓名: string;學號: string;郵箱: string;班級: string;年級: string;組別: string;電話: string;QQ: string;
}// 驗證文件后綴
function validateFileExtension(fileName: string): boolean {return fileName.toLowerCase().endsWith(".xlsx");
}// 驗證Excel字段
async function validateExcelFields(file: File): Promise<string | boolean> {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = (e) => {try {const data = new Uint8Array(e.target?.result as ArrayBuffer);const workbook = XLSX.read(data, { type: "array" });const firstSheet = workbook.Sheets[workbook.SheetNames[0]];const jsonData = XLSX.utils.sheet_to_json<UserData>(firstSheet);if (jsonData.length === 0) {reject("Excel文件內容為空");return;}const requiredFields = ["姓名","學號","班級","年級","組別","電話","QQ",];const missingFields = requiredFields.filter((field) => !(field in jsonData[0]),);if (missingFields.length > 0) {reject(`文件缺少必要字段`);return;}resolve(true);} catch (error) {reject("文件解析失敗");}};reader.onerror = () => reject("文件讀取失敗");reader.readAsArrayBuffer(file);});
}//批量導入
export async function processFiles(file: File) {if (!validateFileExtension(file.name)) {throw "請上傳.xlsx格式的文件";}try {const validationResult = await validateExcelFields(file);if (validationResult !== true) {throw validationResult as string;}const formData = new FormData();formData.append("file", file);return await apiClient.post("/userManager/teamInfo/addUsers", formData, {headers: {"Content-Type": "multipart/form-data",},});} catch (error) {// 修改此處:將返回改為拋出if (error instanceof Error) {throw error.message;}throw typeof error === "string" ? error : "未知錯誤";}
}// 模擬非.xlsx 文件
const nonXlsxFile = new File([], "example.txt", { type: "text/plain" });
processFiles(nonXlsxFile).then((result) => {console.log(result);
});
該文件可以在用戶上傳時檢查上傳的文件后綴是否為xlsx 以及如果上傳的文件后綴是xlsx
那么檢查表格中是否有該有的字段 如果沒有則直接攔截不發送請求
在vue文件中的使用
const handleXlsx = (e: Event) => {const target = e.target as HTMLInputElement;if (target.files) {processFiles(target.files[0]).then((response) => {showAlert("上傳成功", "pass");updateData(grade.value, group.value);target.value = "";}).catch((error) => {showAlert(error, "error");});}
};