如何在.NET Core MVC项目中用JavaScript解析月度网格格式Excel餐单数据
JavaScript解析非通用网格型月度餐单Excel方案

前置依赖
推荐使用SheetJS (xlsx)库,是目前JS生态里兼容性最好、支持格式最全的Excel解析工具,纯前端即可完成解析,无需依赖后端服务。
核心实现步骤
- 第一步:全量读取Excel原始数据
先将上传的Excel文件转为ArrayBuffer格式,读取为工作簿对象后,提取目标工作表,转为二维数组格式(相比直接转JSON更方便按行列坐标定位非结构化数据)
import * as XLSX from 'xlsx'; // 文件上传监听示例 document.querySelector('#excel-file').addEventListener('change', async (e) => { const file = e.target.files[0]; const buf = await file.arrayBuffer(); const workbook = XLSX.read(buf, { type: 'array' }); // 取第一个工作表(餐单通常只有一个工作表) const worksheet = workbook.Sheets[workbook.SheetNames[0]]; // 转为二维数组,header:1表示不自动生成表头,raw:false表示读格式化后的文本而非原始值 const rawGrid = XLSX.utils.sheet_to_json(worksheet, { header: 1, raw: false, blankrows: true }); })
- 第二步:处理合并单元格
月度餐单通常大量使用合并单元格(比如周表头、餐次表头),SheetJS默认仅在合并区域的左上角单元格存储值,其余位置为空,需要提前补全:
const merges = worksheet['!merges'] || []; merges.forEach(mergeRange => { // 取合并区域左上角的值 const fillValue = rawGrid[mergeRange.s.r][mergeRange.s.c]; // 遍历合并区域所有单元格赋值 for (let row = mergeRange.s.r; row <= mergeRange.e.r; row++) { for (let col = mergeRange.s.c; col <= mergeRange.e.c; col++) { rawGrid[row][col] = fillValue; } } })
第三步:定位有效数据边界
打印rawGrid查看完整行列结构,根据你的餐单模板特征(比如找「早餐」「1日」「周一」这类固定关键词),确定有效餐单数据的起始行、起始列、结束行、结束列,过滤掉表头、备注、空白行等无关内容。
示例:如果你的餐单是日历网格结构,行是周、列是星期,第一行是星期表头,从第二行开始是每周的餐单内容,就可以定位起始行是1(索引从0开始)第四步:按规则映射为结构化数据
根据餐单的排布规则编写映射逻辑,最终输出你需要的结构化数据格式,比如按日期存储的餐单列表:
const menuResult = []; const daysInMonth = 31; // 也可以动态计算当月天数 let currentDay = 1; // 假设有效数据起始行是1,每行7列对应周一到周日 for (let row = 1; row < rawGrid.length; row++) { for (let col = 1; col <= 7; col++) { if (currentDay > daysInMonth) break; menuResult.push({ date: `2024-01-${currentDay.toString().padStart(2, '0')}`, content: rawGrid[row][col] || '无餐食安排' }); currentDay++; } }
可选后端配合方案
如果文件过大、前端解析性能不足,也可以将文件上传到.NET Core后端,使用EPPlus或NPOI库执行相同的定位+映射解析逻辑,处理完成后返回结构化JSON给前端即可。
内容的提问来源于stack exchange,提问作者hkyaaa
相关产品推荐
相关产品推荐

