| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- // 供应商交货计划分析工具
- // 用于分析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 = '<p class="placeholder">正在分析Excel文件,请稍候...</p>';
- 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 = '<p class="placeholder">Excel文件中没有数据</p>';
- 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 = `<h3>${fieldName}</h3><div class="field-details">`;
- content += `<div class="field-detail">数据类型: ${stats.dataType}</div>`;
- content += `<div class="field-detail">总记录数: ${stats.totalCount}</div>`;
- content += `<div class="field-detail">非空值数: ${stats.nonEmptyCount} (${((stats.nonEmptyCount / stats.totalCount) * 100).toFixed(2)}%)</div>`;
- content += `<div class="field-detail">空值数: ${stats.emptyCount} (${((stats.emptyCount / stats.totalCount) * 100).toFixed(2)}%)</div>`;
- content += `<div class="field-detail">唯一值数量: ${stats.uniqueValues}</div>`;
-
- // 添加数值类型的统计信息
- if (stats.min !== undefined) {
- content += `<div class="field-detail">最小值: ${stats.min}</div>`;
- }
- if (stats.max !== undefined) {
- content += `<div class="field-detail">最大值: ${stats.max}</div>`;
- }
- if (stats.average !== undefined) {
- content += `<div class="field-detail">平均值: ${stats.average.toFixed(2)}</div>`;
- }
-
- // 添加样本值
- if (stats.sampleValues && stats.sampleValues.length > 0) {
- content += `<div class="field-detail">样本值: ${stats.sampleValues.join(', ')}</div>`;
- }
-
- content += '</div>';
- card.innerHTML = content;
-
- return card;
- }
- // 显示数据预览
- function showDataPreview(data) {
- if (!data || data.length === 0) {
- dataPreview.innerHTML = '<p class="placeholder">Excel文件中没有数据</p>';
- 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);
- }
- }
- });
|