酒店通报最终版edit icon

Fork(复制)
下载
嵌入
设置
BUG反馈
index.html
style.css
index.js
现在支持上传本地图片了!
            
            <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>拜访情况通报</title>
<style>
    body {
        font-family: Arial, sans-serif;
        background: linear-gradient(135deg, #f8f8f8, #e0e0e0);
        margin: 0;
        padding: 20px;
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        box-sizing: border-box;
    }
    .container {
        background-color: #ffffff;
        padding: 30px;
        border-radius: 15px;
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
        width: 90%;
        max-width: 1200px;
        position: relative;
        overflow-x: auto;
    }
    h2 {
        color: #d32f2f;
        text-align: center;
        margin-bottom: 20px;
        font-size: 28px;
        font-weight: bold;
    }
    .upload-section {
        background-color: #fff3e0;
        padding: 20px;
        border-radius: 10px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
        margin-bottom: 20px;
        text-align: center;
    }
    .file-upload {
        background-color: #d32f2f;
        color: white;
        padding: 10px 20px;
        border-radius: 5px;
        cursor: pointer;
        display: inline-block;
        margin: 10px 0;
        font-size: 16px;
        transition: background-color 0.3s ease;
    }
    .file-upload:hover {
        background-color: #b71c1c;
    }
    .progress-bar {
        width: 100%;
        background-color: #e0e0e0;
        border-radius: 5px;
        overflow: hidden;
        margin: 10px 0;
        display: none;
    }
    .progress-bar-inner {
        width: 0;
        height: 10px;
        background-color: #d32f2f;
        transition: width 0.3s ease;
    }
    .success-message {
        color: #388e3c;
        font-weight: bold;
        margin: 10px 0;
        display: none;
    }
    .buttons {
        display: flex;
        justify-content: center;
        gap: 20px;
        margin: 20px 0;
        flex-wrap: wrap;
    }
    button {
        background-color: #d32f2f;
        color: white;
        padding: 12px 24px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-size: 16px;
        transition: background-color 0.3s ease;
    }
    button:hover {
        background-color: #b71c1c;
    }
    #downloadBtn {
        background-color: #ffa000;
    }
    #downloadBtn:hover {
        background-color: #e65100;
    }
    table {
        width: 100%;
        border-collapse: collapse;
        margin-top: 20px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
    }
    th, td {
        border: 1px solid #ddd;
        padding: 12px;
        text-align: center;
        white-space: nowrap;
    }
    th {
        background-color: #d32f2f;
        color: white;
        font-weight: bold;
    }
    td {
        background-color: #fff3e0;
    }
</style>
</head>
<body>
<div class="container">
    <h2>拜访情况通报</h2>
    <div class="upload-section">
        <label for="excelFile极" class="file-upload">上传 Excel 文件</label>
        <input type="file" id="excelFile" accept=".xlsx, .xls" style="display: none;"/>
        <div class="progress-bar">
            <div class="progress-bar-inner"></div>
        </div>
        <div class="success-message">文件上传成功!</div>
    </div>
    <div class="buttons">
        <button onclick="processExcel()">生成通报</button>
        <button id="downloadBtn" onclick="downloadExcel()" disabled>下载 Excel</button>
    </div>
    <table id="reportTable">
        <thead>
            <tr>
                <th>分公司</th>
                <th>清单客户拜访次数</th>
                <th>非清单客户拜访次数</th>
                <th>清单客户数量</th>
                <th>非清单客户数量</th>
                <th>二次拜访客户数量</th>
                <th>添加微信</th>
                <th>获取商机</th>
            </tr>
        </thead>
        <tbody>
            <!-- 数据将在这里插入 -->
        </tbody>
    </table>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.9/xlsx.full.min.js"></script>
<script>
// 分公司名称映射关系
const branchMapping = {
    "碑林区分公司": "碑林",
    "高新区分公司": "高新",
    "莲湖区分公司": "莲湖",
    "未央区分公司": "未央",
    "新城区分公司": "新城",
    "雁塔区分公司": "雁塔",
    "浐灞区分公司": "浐灞",
    "航天新区分公司": "航天",
    "经开区分公司": "经开",
    "曲江新区分公司": "曲江",
    "灞桥区分公司": "灞桥",
    "沣东新区分公司": "沣东",
    "长安区分公司": "长安",
    "高陵分公司": "高陵",
    "鄠邑区分公司": "鄠邑",
    "蓝田县分公司": "蓝田",
    "临潼区分公司": "临潼",
    "阎良区分公司": "阎良",
    "周至县分公司": "周至"
};
// 分公司名称固定顺序
const branchOrder = [
    "碑林", "高新", "莲湖", "未央", "新城", "雁塔", "浐灞", "航天", "经开", "曲江",
    "灞桥", "沣东", "长安", "高陵", "鄠邑", "蓝田", "临潼", "阎良", "周至"
];
let tableData = []; // 存储表格数据,用于生成 Excel
// 文件上传逻辑
const fileInput = document.getElementById('excelFile');
const progressBar = document.querySelector('.progress-bar');
const progressBarInner = document.querySelector('.progress-bar-inner');
const successMessage = document.querySelector('.success-message');
fileInput.addEventListener('change', function() {
    if (fileInput.files.length > 0) {
        const reader = new FileReader();
        // 显示进度条
        progressBar.style.display = 'block';
        progressBarInner.style.width = '0';
        successMessage.style.display = 'none';
        reader.onprogress = function(e) {
            if (e.lengthComputable) {
                const percent = (e.loaded / e.total) * 100;
                progressBarInner.style.width = percent + '%';
            }
        };
        reader.onload = function(e) {
            // 上传完成
            progressBarInner.style.width = '100%';
            setTimeout(() => {
                progressBar.style.display = 'none';
                successMessage.style.display = 'block';
            }, 500);
        };
        reader.readAsArrayBuffer(fileInput.files[0]);
    }
});
function processExcel() {
    if (fileInput.files.length === 0) {
        alert('请先上传文件!');
        return;
    }
    const reader = new FileReader();
    reader.onload = function(e) {
        const data = new Uint8Array(e.target.result);
        const workbook = XLSX.read(data, {type: 'array'});
        const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
        const json = XLSX.utils.sheet_to_json(firstSheet, {header:1});
        let stats = {}; // 用于存储分公司统计数据
        let visitCounts = {}; // 用于记录每个客户的拜访次数
        json.slice(1).forEach(row => { // 忽略标题行
            if (row[5] === '已结束') { // F列是流程状态
                const branchFullName = row[8]; // I列是分公司全称
                const branchShortName = branchMapping[branchFullName]; // 映射为简称
                if (!branchShortName) return; // 如果找不到映射则跳过
                const hotelName = row[1]; // B列是酒店名称
                stats[branchShortName] = stats[branchShortName] || {
                    清单客户拜访次数: 0,
                    非清单客户拜访次数: 0,
                    添加微信: 0,
                    获取商机: 0,
                    清单客户数量: new Set(),
                    非清单客户数量: new Set(),
                    二次拜访客户数量: 0
                };
                // 统计拜访次数
                if (!visitCounts[branchShortName]) visitCounts[branchShortName] = {};
                if (!visitCounts[branchShortName][hotelName]) visitCounts[branchShortName][hotelName] = 0;
                visitCounts[branchShortName][hotelName]++;
                // 统计清单/非清单客户
                if (row[11] === '是') { // L列是否清单客户
                    stats[branchShortName].清单客户拜访次数++;
                    stats[branchShortName].清单客户数量.add(hotelName); // 添加到清单客户集合
                } else if (row[11] === '否') {
                    stats[branchShortName].非清单客户拜访次数++;
                    stats[branchShortName].非清单客户数量.add(hotelName); // 添加到非清单客户集合
                }
                if (row[30] === '是') stats[branchShortName].添加微信++; // AE列是否添加微信
                if (row[32] === '是') stats[branchShortName].获取商机++; // AG列是否获取商机
            }
        });
        // 计算二次拜访客户数量
        for (const branch in visitCounts) {
            let count = 0;
            for (const hotel in visitCounts[branch]) {
                if (visitCounts[branch][hotel] >= 2) count++;
            }
            stats[branch].二次拜访客户数量 = count;
        }
        // 生成表格
        const tbody = document.querySelector('#reportTable tbody');
        tbody.innerHTML = '';
        tableData = []; // 重置表格数据
        branchOrder.forEach(branch => {
            const data = stats[branch] || {
                清单客户拜访次数: 0,
                非清单客户拜访次数: 0,
                添加微信: 0,
                获取商机: 0,
                清单客户数量: new Set(),
                非清单客户数量: new Set(),
                二次拜访客户数量: 0
            };
            const row = `<tr>
                <td>${branch}</td>
                <td>${data.清单客户拜访次数}</td>
                <td>${data.非清单客户拜访次数}</td>
                <td>${data.清单客户数量.size}</td>
                <td>${data.非清单客户数量.size}</td>
                <td>${data.二次拜访客户数量}</td>
                <td>${data.添加微信}</td>
                <td>${data.获取商机}</td>
            </tr>`;
            tbody.innerHTML += row;
            tableData.push([
                branch,
                data.清单客户拜访次数,
                data.非清单客户拜访次数,
                data.清单客户数量.size,
                data.非清单客户数量.size,
                data.二次拜访客户数量,
                data.添加微信,
                data.获取商机
            ]);
        });
        document.getElementById('downloadBtn').disabled = false; // 启用下载按钮
    };
    reader.readAsArrayBuffer(fileInput.files[0]);
}
function downloadExcel() {
    const wsData = [
        ['分公司', '清单客户拜访次数', '非清单客户拜访次数', '清单客户数量', '非清单客户数量', '二次拜访客户数量', '添加微信', '获取商机'],
        ...tableData
    ]; // 添加表头
    const ws = XLS极X.utils.aoa_to_sheet(wsData);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "拜访情况通报");
    XLSX.writeFile(wb, "拜访情况通报.xlsx");
}
</script>
</body>
</html>

        
预览
控制台
清空