@sparta-utils/excel-validate-helper
Version:
Excel 读取、校验、错误标注和导出工具库
77 lines (76 loc) • 3.08 kB
JavaScript
import ExcelJS from 'exceljs';
export class ExcelReader {
static async read(file, options = {}) {
const { dataStartRow = 4, sheetIndex = 0, onProgress, mapHeaders, mapRow, filterEmptyRows = true, progressStep = 5 } = options;
if (!file) {
throw new Error('未传入文件');
}
if (!file.name.toLowerCase().endsWith('.xlsx')) {
throw new Error('请上传一个 .xlsx 格式的 Excel 文件');
}
if (dataStartRow < 1) {
throw new Error('数据起始行必须大于等于 1');
}
if (sheetIndex < 0) {
throw new Error('工作表索引不能为负');
}
try {
const workbook = new ExcelJS.Workbook();
const buffer = await file.arrayBuffer();
await workbook.xlsx.load(buffer);
const worksheet = workbook.worksheets[sheetIndex];
if (!worksheet) {
throw new Error(`Excel 中未找到第 ${sheetIndex + 1} 个工作表`);
}
const totalRows = worksheet.actualRowCount;
// 读取表头
const headerRow = worksheet.getRow(dataStartRow - 1);
let headers = [];
if (Array.isArray(headerRow.values)) {
headers = headerRow.values
.slice(1)
.map((v) => (v != null ? v.toString() : ''));
}
if (mapHeaders) {
headers = headers.map(mapHeaders);
}
const data = [];
let lastProgress = -1;
worksheet.eachRow((row, rowNumber) => {
if (rowNumber >= dataStartRow) {
let rowData = Array.isArray(row.values) ? row.values.slice(1) : [];
// 过滤空行
if (filterEmptyRows) {
const isEmpty = rowData.every((v) => v === null || v === undefined || v === '');
if (isEmpty) {
return;
}
}
if (mapRow) {
rowData = mapRow(rowData);
}
rowData.unshift(rowNumber); // 加行号
data.push(rowData);
if (onProgress) {
const currentProgress = Math.floor((rowNumber / totalRows) * 100);
if (currentProgress - lastProgress >= progressStep) {
lastProgress = currentProgress;
onProgress(currentProgress);
}
}
}
});
return {
headers,
data,
totalRows,
sheetName: worksheet.name,
fileName: file.name
};
}
catch (error) {
console.error('Excel 读取失败:', error);
throw new Error('读取 Excel 文件失败,请确认文件格式是否正确');
}
}
}