You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python生成购物清单HTML的JS功能异常排查求助

购物清单HTML生成脚本错误排查与修复

我有一份每日更新的多类别Excel清单,转成CSV后用Python脚本生成带交互功能的HTML购物清单,需求是:

  • 每个商品配备加减按钮,调整购买数量
  • 每个清单自动计算商品数量×单价的小计
  • 页面末尾生成所有清单的总计

但生成的HTML中JavaScript功能异常:加减按钮操作后数值计算错误,小计和总计都不对。以下是我的Python代码,请帮忙排查修复:

import csv

# Define the CSV file path 
csv_file = 'test.csv'

# Read data from the CSV file into a list of dictionaries
data = []
with open(csv_file, 'r', newline='') as file:
    csv_reader = csv.DictReader(file)
    for row in csv_reader:
        data.append(row)

# Initialize a dictionary to store shopping lists and their items
shopping_lists = {}

# Group items by shopping list
for row in data:
    list_name = row['List']
    item_name = row['Item']
    price = float(row['Price'])

    if list_name not in shopping_lists:
        shopping_lists[list_name] = {'items': [], 'total': 0.0}

    shopping_lists[list_name]['items'].append({'name': item_name, 'price': price})
    shopping_lists[list_name]['total'] += price

# Define the HTML template
html_template = """
<!DOCTYPE html>
<html>
<head>
    <title>Shopping Lists</title>
    <style>
        ul {
            list-style-type: none;
            padding: 0;
        }

        li {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 10px;
        }

        .item {
            flex: 1;
        }

        .price {
            margin-right: 10px;
        }

        button {
            padding: 5px 10px;
            background-color: #007bff;
            color: #fff;
            border: none;
            cursor: pointer;
        }

        .list-total {
            margin-top: 10px;
            text-align: right;
        }

        #total {
            margin-top: 20px;
            text-align: right;
        }
    </style>
</head>
<body>
    <h1>Shopping Lists</h1>
"""

# Generate HTML for each shopping list
for list_name, list_data in shopping_lists.items():
    list_html = f"""
    <div id="list-container-{list_name.replace(' ', '-')}">
        <h2>{list_name}</h2>
        <ul class="shopping-list">
    """

    for item in list_data['items']:
        item_html = f"""
            <li data-price="{item['price']}">
                <div class="item">{item['name']}</div>
                <div class="price">${item['price']}</div>
                <button class="add">+</button>
                <span class="quantity">0</span>
                <button class="subtract">-</button>
            </li>
        """
        list_html += item_html

    list_total_html = f"""
        </ul>
        <div class="list-total">
            <strong>List Total: $<span class="list-grand-total">0.00</span></strong>
        </div>
    </div>
    <script>
        const listContainer = document.querySelector('#list-container-{list_name.replace(' ', '-')}');
        const items = listContainer.querySelectorAll("li");
        const listTotalElement = listContainer.querySelector(".list-grand-total");

        items.forEach((item) => {{
            const addButton = item.querySelector(".add");
            const subtractButton = item.querySelector(".subtract");
            const quantityElement = item.querySelector(".quantity");
            const price = parseFloat(item.dataset.price);

            let quantity = 0;

            addButton.addEventListener("click", () => {{
                quantity++;
                quantityElement.textContent = quantity;
                updateListTotal();
            }});

            subtractButton.addEventListener("click", () => {{
                if (quantity > 0) {{
                    quantity--;
                    quantityElement.textContent = quantity;
                    updateListTotal();
                }}
            }});
        }});

        function updateListTotal() {{
            let listTotal = 0;
            items.forEach(item => {{
                const qty = parseInt(item.querySelector('.quantity').textContent);
                const price = parseFloat(item.dataset.price);
                listTotal += qty * price;
            }});
            listTotalElement.textContent = listTotal.toFixed(2);
            updateCombinedTotal();
        }}
    </script>
    """

    html_template += list_html + list_total_html

# Add global script and combined total section
html_template += """
    <script>
        function updateCombinedTotal() {
            const combinedTotalElement = document.getElementById("grand-total");
            let combinedTotal = 0;
            document.querySelectorAll('.list-grand-total').forEach((listTotal) => {
                combinedTotal += parseFloat(listTotal.textContent);
            });
            combinedTotalElement.textContent = combinedTotal.toFixed(2);
        }
    </script>
    <div id="total">
        <strong>Combined Total: $<span id="grand-total">0.00</span></strong>
    </div>
</body>
</html>
"""

# Save the generated HTML to a file
output_file = 'output.html'
with open(output_file, 'w') as file:
    file.write(html_template)

print(f"HTML file '{output_file}' has been generated.")

错误原因与修复说明

  1. 后端变量非法引用:原代码直接把Python的list_data.total写入JS,浏览器无法识别该变量,修复后改为在JS中实时计算列表总计。
  2. 总计逻辑错误:原代码每次点击都累加当前商品金额,导致数值持续叠加,修复后改为每次重新计算整个列表的所有商品金额总和。
  3. 重复函数定义:原代码每个列表都定义一次updateCombinedTotal,导致函数被重复覆盖,修复后移到全局脚本只定义一次。
  4. 数据解析冗余:原代码从价格文本中截取$符号解析数值,修复后给商品元素添加data-price属性直接存储数值,避免解析错误。
  5. 数量显示优化:购买数量改为整数显示,去掉不必要的两位小数格式。

内容的提问来源于stack exchange,提问作者Kagazwala

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 17:28:14