You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在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();
关键细节说明
  1. 原始数据存储:咱们把原始销售额存在输入框的data-original属性里,这样就算页面刷新(如果是静态数据)或者覆盖值被删除,都能直接从DOM里拿到原始值,不用重新请求接口。
  2. 实时响应:用input事件监听输入框的每一次变化,包括键盘输入、粘贴、删除,保证数据实时更新。
  3. 总计计算:每次值变化都调用calculateTotal函数,遍历所有当前计算值求和,并且用toLocaleString()格式化数字,显示千分位更直观。
  4. 动态数据适配:如果你的原始数据是从接口获取的,只需要循环接口返回的数据,动态创建表格行,给每个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

火山引擎 最新活动