如何在Excel中设置基础值与覆盖值,实现可恢复的销售数据调整
嘿,我给你整了个完全贴合需求的实现方案,用原生HTML/CSS/JS就能搞定,不用依赖任何框架,直接看代码和说明就行:
核心思路
咱们的核心需求是保留原始数据、支持手动覆盖、删除覆盖值自动恢复、实时计算总计,所以关键点是:
- 把原始销售值存在DOM元素的自定义属性里(比如
data-original),这样就算覆盖值被清空,也能随时拉取原始数据,不用重新请求接口 - 监听手动覆盖输入框的变化,实时更新当前生效的计算值
- 每次值变化时重新计算总计,保证数据实时同步
完整代码实现
HTML结构
先搭好表格的基本框架,包含公司名称、原始值、手动覆盖输入框、当前计算值,最后加总计行:
<div class="sales-container"> <h2>销售数据管理</h2> <table id="salesTable"> <thead> <tr> <th>公司名称</th> <th>原始销售额</th> <th>手动覆盖值</th> <th>当前计算值</th> </tr> </thead> <tbody> <!-- 示例数据,实际可以从接口动态生成 --> <tr> <td>公司A</td> <td class="original-value">15000</td> <td><input type="number" class="override-input" data-original="15000" placeholder="输入覆盖值"></td> <td class="current-value">15000</td> </tr> <tr> <td>公司B</td> <td class="original-value">22000</td> <td><input type="number" class="override-input" data-original="22000" placeholder="输入覆盖值"></td> <td class="current-value">22000</td> </tr> <tr> <td>公司C</td> <td class="original-value">18500</td> <td><input type="number" class="override-input" data-original="18500" placeholder="输入覆盖值"></td> <td class="current-value">18500</td> </tr> </tbody> <tfoot> <tr> <td colspan="3" class="total-label">总计:</td> <td id="total-value">55500</td> </tr> </tfoot> </table> </div>
CSS美化
给表格加一点样式,让它看起来更舒服:
.sales-container { max-width: 800px; margin: 2rem auto; padding: 0 1rem; } #salesTable { width: 100%; border-collapse: collapse; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } #salesTable th, #salesTable td { padding: 12px; text-align: right; border-bottom: 1px solid #eee; } #salesTable th:first-child, #salesTable td:first-child { text-align: left; } #salesTable thead th { background-color: #f5f5f5; font-weight: bold; } .override-input { width: 100px; padding: 6px; border: 1px solid #ddd; border-radius: 4px; } .total-label { font-weight: bold; text-align: right !important; } #total-value { font-weight: bold; color: #2c3e50; }
JavaScript逻辑
实现核心功能:监听输入变化、恢复原始值、计算总计:
// 获取所有覆盖输入框和总计元素 const overrideInputs = document.querySelectorAll('.override-input'); const totalElement = document.getElementById('total-value'); // 计算总计的函数 function calculateTotal() { let total = 0; document.querySelectorAll('.current-value').forEach(el => { total += parseInt(el.textContent) || 0; }); totalElement.textContent = total.toLocaleString(); // 格式化数字,显示千分位 } // 监听每个覆盖输入框的变化 overrideInputs.forEach(input => { input.addEventListener('input', function() { const originalValue = this.dataset.original; const currentValueEl = this.closest('tr').querySelector('.current-value'); if (this.value.trim() === '') { // 输入为空,恢复原始值 currentValueEl.textContent = originalValue; } else { // 有输入值,更新当前计算值 currentValueEl.textContent = this.value; } // 重新计算总计 calculateTotal(); }); }); // 初始计算一次总计 calculateTotal();
关键细节说明
- 原始数据存储:咱们把原始销售额存在输入框的
data-original属性里,这样就算页面刷新(如果是静态数据)或者覆盖值被删除,都能直接从DOM里拿到原始值,不用重新请求接口。 - 实时响应:用
input事件监听输入框的每一次变化,包括键盘输入、粘贴、删除,保证数据实时更新。 - 总计计算:每次值变化都调用
calculateTotal函数,遍历所有当前计算值求和,并且用toLocaleString()格式化数字,显示千分位更直观。 - 动态数据适配:如果你的原始数据是从接口获取的,只需要循环接口返回的数据,动态创建表格行,给每个
override-input设置对应的data-original属性就行,比如:
// 假设接口返回的salesData是数组:[{company: '公司A', value: 15000}, ...] const salesData = [/* 接口数据 */]; const tbody = document.querySelector('#salesTable tbody'); salesData.forEach(item => { const tr = document.createElement('tr'); tr.innerHTML = ` <td>${item.company}</td> <td class="original-value">${item.value}</td> <td><input type="number" class="override-input" data-original="${item.value}" placeholder="输入覆盖值"></td> <td class="current-value">${item.value}</td> `; tbody.appendChild(tr); }); // 别忘了重新获取overrideInputs并绑定事件,或者在创建行的时候直接绑定
这样整个功能就完全实现啦,你可以直接复制代码运行,测试一下删除覆盖值会不会恢复原始值,总计是不是实时更新~
内容的提问来源于stack exchange,提问作者Joaquin Grech




