异步 Buffer 处理
利用 FileReader.readAsArrayBuffer 异步读取文件,避免大文件解析阻塞主线程(UI Thread)。
FileUpload.vue 作为一个独立的数据预处理单元,核心职责是将非结构化的 Office 文件(XLSX/CSV)转换为标准化的二维数值矩阵 number[][],并执行初步的 ETL(提取、转换、加载)逻辑。
该组件采用无状态设计,通过 Props 注入配置,通过 Emits 回传清洗后的数据。
异步 Buffer 处理
利用 FileReader.readAsArrayBuffer 异步读取文件,避免大文件解析阻塞主线程(UI Thread)。
Drag & Drop 增强
封装原生 HTML5 Drag API,通过状态变量 isDragging 实现交互样式的动态反馈。
类型预测与清洗
在渲染前执行 parseFloat 强制类型转换,并结合 filter 算子过滤脏数据。
xlsx 库的 sheet_to_json 将 Sheet 对象转换为二维数组。emit 将结构化数据推送至父级作用域。/** * @description 处理 File 对象的读取与解析逻辑 * @param file 原始 File 对象,支持 input 触发或 drop 触发 */const onFileChange = (file?: File) => { if (!file) return;
// 后缀名二次校验 (Runtime Check) const ext = file.name.split('.').pop()?.toLowerCase(); if (!['xlsx', 'xls', 'csv'].includes(ext || '')) { Swal.fire({ ...props.swalConfig, icon: 'error', title: 'Invalid Format' }); return; }
const reader = new FileReader(); reader.onload = (e) => { try { // 采用 ArrayBuffer 处理,兼顾多端编码兼容性 const data = new Uint8Array(e.target?.result as ArrayBuffer); const workbook = XLSX.read(data, { type: 'array' }); const worksheet = workbook.Sheets[workbook.SheetNames[0]]; // 默认取第一个 Sheet
// 获取原始二维矩阵 const rawData: any[][] = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); if (!rawData?.length) throw new Error('EMPTY_SHEET');
// 执行数据清洗流水线 processRawData(rawData); } catch (err) { handleParseError(err); } }; reader.readAsArrayBuffer(file);};/** * @description 执行行列过滤,确保输出数据为 number[][] 格式 * @param rawData 原始行列数组 */const processRawData = (rawData: any[][]) => { const cleanData = rawData .map(row => [ parseFloat(row[0]), // 转换坐标 X parseFloat(row[1]) // 转换坐标 Y ]) .filter(row => !isNaN(row[0]) && !isNaN(row[1]) // 严格过滤非数值行(自动剔除表头) );
// 事件分发:将清洗后的数据传递给订阅者 emit('upload-success', cleanData);
Swal.fire({ ...props.swalConfig, icon: 'success', text: `Successfully loaded ${cleanData.length} data points.` });};/** * @description 封装 DND 交互逻辑 */const handleDrop = (e: DragEvent) => { isDragging.value = false; // 重置视觉状态 // 提取 DataTransfer 对象中的首个文件 onFileChange(e.dataTransfer?.files[0]);};| 属性名 | 类型 | 描述 |
|---|---|---|
label | string | 上传区域的占位文本 |
hasData | boolean | 父组件透传的数据存在状态 |
swalConfig | object | 注入的全局样式配置对象 |
| 事件名 | 载荷类型 | 触发逻辑 |
|---|---|---|
upload-success | number[][] | 完成 ETL 清洗后的数据矩阵 |
clear | void | 清空内部缓存触发 |