vue文件上傳讀取文件數(shù)據(jù)進(jìn)行格式校驗(yàn)方式
概要
文件上傳這里用的是 element-Ui 的 el-upload 在文件上傳前 前端讀取文件內(nèi)容 進(jìn)行內(nèi)容數(shù)據(jù)格式的校驗(yàn) 通過才可以進(jìn)行上傳 否則給出 異常提示
整體架構(gòu)流程代碼
<el-upload
:on-success="onSucess"
:on-error="uploadError"
:before-upload="beforeUpload"
:multiple="false"
class="upload-demo"
action="/api/ZTMM/ntmm-mmacct/upload"
:headers="headersParam"
:data="tbmmacct"
:show-file-list="false"
>
<el-tooltip
class="item"
effect="light"
content="請上傳.xls格式文件"
placement="right"
>
<el-button size="small" v-if="uploadBtn"
><span style="color: #66b1ff">選取文件</span></el-button
>
</el-tooltip>
</el-upload>
beforeUpload(file) {
this.loading = true;
const isXLS = file.type === "application/vnd.ms-excel";
if (!isXLS) {
this.$message.error("上傳文件只能是xls格式!");
this.loading = false;
return false;
}
// this.loading = true;
// 使用 FileReader 讀取文件內(nèi)容進(jìn)行校驗(yàn)
const reader = new FileReader();
reader.onload = async (e) => {
const fileContent = e.target.result;
// 解析 Excel 文件內(nèi)容
const workbook = XLSX.read(fileContent, { type: "array" });
const sheet = workbook.Sheets[workbook.SheetNames[0]]; // 獲取第一個 sheet
const data = XLSX.utils.sheet_to_json(sheet); // 將 sheet 轉(zhuǎn)為 JSON 數(shù)組
// 進(jìn)行自定義的文件內(nèi)容校驗(yàn)
if (await this.validateFileContent(data)) {
this.$message.success("文件內(nèi)容校驗(yàn)通過");
this.loading = false;
this.uploadFile(file);
} else {
this.$message.error("文件為空或內(nèi)容格式不符合要求, 請重新檢查上傳!");
this.loading = false;
return false; // 校驗(yàn)失敗,阻止上傳
}
};
// 讀取文件內(nèi)容
reader.readAsArrayBuffer(file);
// 返回 false,表示文件上傳暫時被阻止,等待校驗(yàn)完成
return false;
},
uploadFile(file) {
// 手動觸發(fā)上傳,這里可以通過修改 `action` 或直接調(diào)用 `upload` 方法上傳
const formData = new FormData();
formData.append("file", file);
// 進(jìn)行自定義的上傳請求
this.$axios
.post("/api/ZTMM/ntmm-mmacct/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
...this.headersParam, // 如果有額外的頭部信息
},
params: this.tbmmacct, // 如果有額外的請求數(shù)據(jù)
})
.then((response) => {
this.$message.success("文件上傳成功");
this.getFiles();
// 處理成功邏輯
})
.catch((error) => {
this.$message.error("文件上傳失敗");
// 處理錯誤邏輯
});
},
async validateFileContent(data) {
console.log(data, "daat");
if (data && data.length > 0) {
let newArr = data.slice(1);
// 轉(zhuǎn)換數(shù)據(jù)格式
const transformedData = newArr.map((item) => ({
itemId: item["盤條到貨記錄導(dǎo)入模版"],
itemName: item["__EMPTY"],
arrivalQuantity: item["__EMPTY_1"],
expectedArrivalTime: item["__EMPTY_2"],
creUser: item["__EMPTY_3"],
creTime: item["__EMPTY_4"],
}));
return this.validateData(transformedData);
}
return false; // 如果文件沒有符合的內(nèi)容,返回 false
},
validateData(data) {
if (data.length === 0) {
return false;
}
for (const item of data) {
// 校驗(yàn) itemId
if (
typeof item.itemId !== "string" ||
item.itemId.length < 1 ||
item.itemId.length > 14 ||
item.itemId === null ||
item.itemId === undefined
) {
return false;
}
// 校驗(yàn) itemName
if (
typeof item.itemName !== "string" ||
item.itemName.length < 1 ||
item.itemName.length > 10 ||
item.itemName === null ||
item.itemName === undefined
) {
return false;
}
// 校驗(yàn) arrivalQuantity
const arrivalQuantity = parseInt(item.arrivalQuantity, 10);
if (
isNaN(arrivalQuantity) ||
arrivalQuantity < 1 ||
item.arrivalQuantity.length < 1 ||
item.arrivalQuantity.length > 2 ||
item.arrivalQuantity === null ||
item.arrivalQuantity === undefined
) {
return false;
}
// 校驗(yàn) expectedArrivalTime
const expectedArrivalTime = new Date(item.expectedArrivalTime);
if (
isNaN(expectedArrivalTime.getTime()) ||
item.expectedArrivalTime === null ||
item.expectedArrivalTime === undefined
) {
return false;
}
// // 校驗(yàn) creUser
// if (typeof item.creUser !== "string" || item.creUser.length < 1 || item.creUser === null || item.creUser === undefined) {
// return false;
// }
// // 校驗(yàn) creTime
// if (typeof item.creTime !== "string" || item.creTime.length < 1 || item.creTime === null || item.creTime === undefined) {
// return false;
// }
}
return true; // 所有校驗(yàn)通過
},
技術(shù)細(xì)節(jié)
主要是在 beforeUpload 屬性方法里實(shí)現(xiàn) 文件的校驗(yàn)與抓取,
?// 使用 FileReader 讀取文件內(nèi)容進(jìn)行校驗(yàn)
? ? ? const reader = new FileReader();
? ? ? reader.onload = async (e) => {
? ? ? ? const fileContent = e.target.result;
? ? ? ? // 解析 Excel 文件內(nèi)容
? ? ? ? const workbook = XLSX.read(fileContent, { type: "array" });
? ? ? ? const sheet = workbook.Sheets[workbook.SheetNames[0]]; // 獲取第一個 sheet
? ? ? ? const data = XLSX.utils.sheet_to_json(sheet); // 將 sheet 轉(zhuǎn)為 JSON 數(shù)組
? ? ? ? // 進(jìn)行自定義的文件內(nèi)容校驗(yàn)
? ? ? ? if (await this.validateFileContent(data)) {
? ? ? ? ? this.$message.success("文件內(nèi)容校驗(yàn)通過");
? ? ? ? ? this.loading = false;
? ? ? ? ? this.uploadFile(file);
? ? ? ? } else {
? ? ? ? ? this.$message.error("文件為空或內(nèi)容格式不符合要求, 請重新檢查上傳!");
? ? ? ? ? this.loading = false;
? ? ? ? ? return false; // 校驗(yàn)失敗,阻止上傳
? ? ? ? }
? ? ? };
? ? ? // 讀取文件內(nèi)容
? ? ? reader.readAsArrayBuffer(file);
? ? ? // 返回 false,表示文件上傳暫時被阻止,等待校驗(yàn)完成
? ? ? return false;校驗(yàn)成功后需要手動去 拋送一下 uploadFile 以上代碼有展示。
小結(jié)
組件結(jié)構(gòu)
<el-upload> 組件:
:on-success和:on-error用于處理上傳成功和失敗的回調(diào)。:before-upload是一個鉤子函數(shù),在文件上傳之前進(jìn)行校驗(yàn)。:multiple設(shè)置為false,表示只允許上傳一個文件。action指定文件上傳的接口地址。:headers和:data用于傳遞額外的請求頭和數(shù)據(jù)。:show-file-list設(shè)置為false,表示不顯示文件列表。
<el-tooltip> 和 <el-button>:
- 提供用戶界面,提示用戶上傳
.xls格式的文件。
方法解析
beforeUpload(file):
- 在文件上傳之前被調(diào)用。
- 檢查文件類型是否為
.xls,如果不是,則顯示錯誤信息并停止上傳。 - 使用
FileReader讀取文件內(nèi)容,并在讀取完成后解析 Excel 文件。 - 調(diào)用
validateFileContent(data)方法對文件內(nèi)容進(jìn)行校驗(yàn),如果通過,則調(diào)用uploadFile(file)方法進(jìn)行上傳。
uploadFile(file):
- 創(chuàng)建一個
FormData對象,將文件添加到其中。 - 使用 Axios 發(fā)送 POST 請求上傳文件,并處理成功和失敗的回調(diào)。
validateFileContent(data):
- 對解析后的 Excel 數(shù)據(jù)進(jìn)行校驗(yàn)。
- 將數(shù)據(jù)轉(zhuǎn)換為特定格式,并調(diào)用
validateData(transformedData)方法進(jìn)行詳細(xì)校驗(yàn)。
validateData(data):
- 對每一項(xiàng)數(shù)據(jù)進(jìn)行校驗(yàn),包括
itemId、itemName、arrivalQuantity和expectedArrivalTime。 - 檢查數(shù)據(jù)的類型、長度和有效性,確保符合要求。
總結(jié)
代碼實(shí)現(xiàn)了一個完整的文件上傳功能,包含了文件類型檢查、內(nèi)容校驗(yàn)和上傳請求。通過這些方法,確保用戶上傳的文件符合預(yù)期的格式和內(nèi)容要求,從而提高了數(shù)據(jù)的準(zhǔn)確性和可靠性。
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue中數(shù)據(jù)不響應(yīng)的問題及解決
這篇文章主要介紹了vue中數(shù)據(jù)不響應(yīng)的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
VUE Error: getaddrinfo ENOTFOUND localhost
這篇文章主要介紹了VUE Error: getaddrinfo ENOTFOUND localhost,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05
crypto-js對稱加密解密的使用方式詳解(vue與java端)
這篇文章主要介紹了如何在Vue前端和Java后端使用crypto-js庫進(jìn)行AES加密和解密,前端通過創(chuàng)建AES.js文件來實(shí)現(xiàn)加密解密功能,并在Vue文件或JavaScript中使用,后端則可以直接使用Java代碼進(jìn)行AES加密和解密操作,需要的朋友可以參考下2025-01-01
vue基于Element按鈕權(quán)限實(shí)現(xiàn)方案
這篇文章主要介紹了vue基于Element按鈕權(quán)限實(shí)現(xiàn)方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Vue pages.json頁面路由中g(shù)lobalStyle的各個屬性詳解
文章總結(jié)介紹小程序頁面配置屬性,包括導(dǎo)航欄背景色(限十六進(jìn)制)、標(biāo)題顏色(支持white/black)、標(biāo)題文字(頁面級覆蓋全局)、導(dǎo)航欄顯示隱藏(default/custom)、下拉刷新設(shè)置(微信專用)及觸底函數(shù)觸發(fā)距離,感興趣的朋友一起看看吧2025-07-07
vue實(shí)現(xiàn)自定義公共組件及提取公共的方法
這篇文章主要介紹了vue實(shí)現(xiàn)自定義公共組件及提取公共的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05

