// 供应商交货计划分析工具 // 用于分析Excel文件中的字段信息,包括数据类型、空值统计等 // 确保DOM加载完成后执行代码 document.addEventListener('DOMContentLoaded', function() { // 获取DOM元素 const fileUpload = document.getElementById('file-upload'); const fileName = document.getElementById('file-name'); const fieldAnalysis = document.getElementById('field-analysis'); const dataPreview = document.getElementById('data-preview'); const analyzeBtn = document.getElementById('analyze-btn'); // 存储当前选择的文件 let selectedFile = null; // 监听文件上传事件 fileUpload.addEventListener('change', function(e) { const file = e.target.files[0]; if (file) { fileName.textContent = file.name; selectedFile = file; analyzeBtn.disabled = false; // 启用分析按钮 } }); // 监听分析按钮点击事件 analyzeBtn.addEventListener('click', function() { if (selectedFile) { // 显示加载状态 fieldAnalysis.innerHTML = '

正在分析Excel文件,请稍候...

'; dataPreview.innerHTML = ''; parseExcelFile(selectedFile); } }); // 解析Excel文件 function parseExcelFile(file) { const reader = new FileReader(); reader.onload = function(e) { const data = new Uint8Array(e.target.result); const workbook = XLSX.read(data, { type: 'array' }); // 获取第一个工作表 const firstSheetName = workbook.SheetNames[0]; const worksheet = workbook.Sheets[firstSheetName]; // 转换为JSON格式 const jsonData = XLSX.utils.sheet_to_json(worksheet); // 分析字段 analyzeFields(jsonData); // 显示数据预览 showDataPreview(jsonData); }; reader.readAsArrayBuffer(file); } // 分析Excel中的每个字段 function analyzeFields(data) { if (!data || data.length === 0) { fieldAnalysis.innerHTML = '

Excel文件中没有数据

'; return; } fieldAnalysis.innerHTML = ''; // 获取所有字段名 const fields = Object.keys(data[0]); fields.forEach(field => { const fieldStats = analyzeField(data, field); const fieldCard = createFieldCard(field, fieldStats); fieldAnalysis.appendChild(fieldCard); }); } // 分析单个字段的统计信息 function analyzeField(data, fieldName) { const values = data.map(row => row[fieldName]).filter(val => val !== undefined && val !== null && val !== ''); const stats = { fieldName, totalCount: data.length, nonEmptyCount: values.length, emptyCount: data.length - values.length, dataType: values.length > 0 ? getDataType(values[0], fieldName) : 'unknown', uniqueValues: [...new Set(values)].length, sampleValues: values.slice(0, 5) // 显示前5个样本值 }; // 如果是数值类型,计算额外的统计信息 if (stats.dataType === 'number' || stats.dataType === 'date') { const numericValues = values.map(val => { if (stats.dataType === 'date') { // 处理日期类型 return new Date(val).getTime(); } return parseFloat(val); }).filter(val => !isNaN(val)); if (numericValues.length > 0) { stats.min = Math.min(...numericValues); stats.max = Math.max(...numericValues); stats.average = numericValues.reduce((sum, val) => sum + val, 0) / numericValues.length; // 如果是日期类型,格式化最小和最大值 if (stats.dataType === 'date') { stats.min = new Date(stats.min).toLocaleDateString(); stats.max = new Date(stats.max).toLocaleDateString(); } } } return stats; } // 特定字段名称列表(确保这些字段被识别为日期类型) const DATE_FIELDS = ['交货日期', '交期回复']; // 获取数据类型 function getDataType(value, fieldName = '') { if (value === null || value === undefined) return 'unknown'; // 对于特定的日期字段,强制识别为日期类型 if (DATE_FIELDS.includes(fieldName)) { // 尝试各种日期格式解析 const dateFormats = [ value, // 原值 value.replace(/\//g, '-'), // 将/替换为-(例如2023/05/20 -> 2023-05-20) value.replace(/\./g, '-') // 将.替换为-(例如2023.05.20 -> 2023-05-20) ]; for (const format of dateFormats) { const date = new Date(format); if (!isNaN(date.getTime()) && date.toISOString() !== '0001-01-01T00:00:00.000Z' && date.getFullYear() > 1900) { return 'date'; } } } // 尝试检查是否为日期 if (typeof value === 'string') { const date = new Date(value); if (!isNaN(date.getTime()) && date.toISOString() !== '0001-01-01T00:00:00.000Z' && date.getFullYear() > 1900) { return 'date'; } } // 检查是否为数字 if (typeof value === 'number' || !isNaN(parseFloat(value)) && isFinite(value)) { return 'number'; } // 检查是否为布尔值 if (typeof value === 'boolean' || value === 'true' || value === 'false') { return 'boolean'; } return 'string'; } // 创建字段分析卡片 function createFieldCard(fieldName, stats) { const card = document.createElement('div'); card.className = 'field-card'; let content = `

${fieldName}

`; content += `
数据类型: ${stats.dataType}
`; content += `
总记录数: ${stats.totalCount}
`; content += `
非空值数: ${stats.nonEmptyCount} (${((stats.nonEmptyCount / stats.totalCount) * 100).toFixed(2)}%)
`; content += `
空值数: ${stats.emptyCount} (${((stats.emptyCount / stats.totalCount) * 100).toFixed(2)}%)
`; content += `
唯一值数量: ${stats.uniqueValues}
`; // 添加数值类型的统计信息 if (stats.min !== undefined) { content += `
最小值: ${stats.min}
`; } if (stats.max !== undefined) { content += `
最大值: ${stats.max}
`; } if (stats.average !== undefined) { content += `
平均值: ${stats.average.toFixed(2)}
`; } // 添加样本值 if (stats.sampleValues && stats.sampleValues.length > 0) { content += `
样本值: ${stats.sampleValues.join(', ')}
`; } content += '
'; card.innerHTML = content; return card; } // 显示数据预览 function showDataPreview(data) { if (!data || data.length === 0) { dataPreview.innerHTML = '

Excel文件中没有数据

'; return; } // 获取所有字段名 const fields = Object.keys(data[0]); // 创建表格 const table = document.createElement('table'); table.className = 'data-table'; // 创建表头 const thead = document.createElement('thead'); const headerRow = document.createElement('tr'); fields.forEach(field => { const th = document.createElement('th'); th.textContent = field; headerRow.appendChild(th); }); thead.appendChild(headerRow); table.appendChild(thead); // 创建表体 const tbody = document.createElement('tbody'); // 只显示前10行数据 const previewData = data.slice(0, 10); previewData.forEach(row => { const tr = document.createElement('tr'); fields.forEach(field => { const td = document.createElement('td'); td.textContent = row[field] !== undefined && row[field] !== null ? row[field] : ''; tr.appendChild(td); }); tbody.appendChild(tr); }); table.appendChild(tbody); // 清空并添加表格 dataPreview.innerHTML = ''; dataPreview.appendChild(table); // 如果有更多数据,显示提示 if (data.length > 10) { const moreInfo = document.createElement('p'); moreInfo.className = 'placeholder'; moreInfo.textContent = `仅显示前10行数据,共 ${data.length} 行`; dataPreview.appendChild(moreInfo); } } });