代码如下

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>JSON 转 Excel风格表格</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fira+Mono&display=swap" rel="stylesheet">
<style>
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    body {
        width: 100%;
        font-family: Arial, sans-serif;
        background: #fff;
    }
    .container {
        width: 100%;
        height: 100%;
        padding: 24px;
        box-sizing: border-box;
        display: flex;
        flex-direction: column;
        align-items: stretch;
    }
    h2 {
        margin-top: 0;
        font-size: 2rem;
        color: #2a4d7a;
        letter-spacing: 1px;
        text-align: center;
    }
    p {
        color: #666;
        margin-bottom: 8px;
        text-align: center;
    }
    textarea {
        width: 100%;
        height: 180px;
        font-family: 'Fira Mono', monospace;
        font-size: 15px;
        border: 1.5px solid #b5c9e2;
        border-radius: 6px;
        padding: 10px;
        resize: vertical;
        background: #f5f8fc;
        transition: border 0.2s;
        margin-bottom: 10px;
        box-sizing: border-box;
    }
    textarea:focus {
        border-color: #5b9bd5;
        outline: none;
        background: #fff;
    }
    .btn-group {
        display: flex;
        flex-wrap: wrap;
        gap: 12px;
        justify-content: center;
        margin-bottom: 10px;
    }
    button {
        padding: 10px 24px;
        font-size: 15px;
        border: none;
        border-radius: 6px;
        background: linear-gradient(90deg, #5b9bd5 60%, #3e6fa9 100%);
        color: #fff;
        font-weight: 500;
        cursor: pointer;
        box-shadow: 0 2px 8px rgba(91,155,213,0.08);
        transition: background 0.2s, transform 0.1s;
    }
    button:hover, button:focus {
        background: linear-gradient(90deg, #3e6fa9 60%, #5b9bd5 100%);
        transform: translateY(-2px) scale(1.03);
    }
    button:active {
        transform: translateY(0) scale(1);
    }
    button:disabled,
    button:disabled:hover,
    button:disabled:focus {
        background: #c9d3e0;
        cursor: not-allowed;
        transform: none;
        box-shadow: none;
    }
    #copyButton {
        background: linear-gradient(90deg, #70ad47 60%, #548235 100%);
    }
    #copyButton:hover, #copyButton:focus {
        background: linear-gradient(90deg, #548235 60%, #70ad47 100%);
    }
    #clearButton {
        background: linear-gradient(90deg, #ed7d31 60%, #c55a11 100%);
    }
    #clearButton:hover, #clearButton:focus {
        background: linear-gradient(90deg, #c55a11 60%, #ed7d31 100%);
    }
    .table-wrapper {
        width: 100%;
        overflow-x: auto;
        margin-top: 24px;
        border-radius: 8px;
        box-shadow: 0 1px 8px rgba(91,155,213,0.07);
        background: #fff;
        flex-grow: 1; /* 让表格区域填充剩余空间 */
        display: flex; /* 确保内部 table 也能正确处理高度 */
    }
    table {
        border-collapse: collapse;
        width: 100%;
        min-width: 600px;
        background: #fff;
    }
    th, td {
        border: 1px solid #b5c9e2;
        padding: 10px 8px;
        text-align: left;
        font-size: 15px;
        word-break: break-all;
    }
    th {
        background-color: #eaf1fb;
        color: #2a4d7a;
        font-weight: 600;
        position: sticky; /* 使表头在滚动时固定 */
        top: 0;           /* 固定在顶部 */
        z-index: 1;       /* 确保在其他内容之上 */
    }
    th[contenteditable="true"] {
        cursor: text;
    }
    th[contenteditable="true"]:focus {
        background-color: #dce6f1;
        outline: 2px solid #5b9bd5;
        outline-offset: -2px;
    }
    tr:nth-child(even) td {
        background-color: #f5f8fc;
    }
    tr:hover td {
        background: #e2ecfa;
        transition: background 0.15s;
    }
    /* 响应式 */
    @media (max-width: 600px) {
        .container {
            padding: 12px;
        }
        table {
            min-width: 400px;
            font-size: 13px;
        }
        textarea {
            height: 120px;
            font-size: 13px;
        }
        button {
            font-size: 13px;
            padding: 8px 12px;
        }
    }
    /* 顶部浮动提示 */
    .toast {
        position: fixed;
        top: 24px;
        left: 50%;
        transform: translateX(-50%);
        background: #5b9bd5;
        color: #fff;
        padding: 12px 32px;
        border-radius: 8px;
        font-size: 16px;
        box-shadow: 0 2px 12px rgba(91,155,213,0.12);
        z-index: 9999;
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.3s;
    }
    .toast.show {
        opacity: 1;
        pointer-events: auto;
    }
</style>
</head>
<body>
<div class="container">
    <h2>JSON 数组转表格(支持一键复制)</h2>
    <p>请输入 JSON 数组(例如 <code>[{"姓名":"Alice","age":20},{"姓名":"Bob","age":22}]</code> )</p>
    <textarea id="jsonInput" placeholder='在这里输入 JSON 数组'></textarea>
    <div class="btn-group">
        <button onclick="generateTable()">生成表格</button>
        <button id="copyButton" onclick="copyTableToClipboard()" disabled>一键复制表格</button>
        <button onclick="loadSampleData()">加载示例</button>
        <button id="clearButton" onclick="clearAll()">清空内容</button>
    </div>
    <div class="table-wrapper" id="tableContainer"></div>
</div>
<div id="toast" class="toast" role="status" aria-live="polite"></div>
<script>
function showToast(msg, color = "#5b9bd5") {
    const toast = document.getElementById('toast');
    toast.textContent = msg;
    toast.style.background = color;
    toast.classList.add('show');
    setTimeout(() => {
        toast.classList.remove('show');
    }, 1800);
}

function generateTable() {
    const container = document.getElementById("tableContainer");
    container.innerHTML = ""; // 清空

    let jsonText = document.getElementById("jsonInput").value.trim();

    if (!jsonText) {
        showToast("请输入 JSON 数据!", "#e67c73");
        return;
    }

    let data;
    try {
        data = JSON.parse(jsonText);
    } catch (e) {
        showToast("JSON 格式错误,请检查!", "#e67c73");
        return;
    }

    if (!Array.isArray(data)) {
        showToast("请输入 JSON 数组(例如:[{},{}])", "#e67c73");
        return;
    }

    // 收集所有表头
    let headers = [];
    data.forEach(row => {
        Object.keys(row).forEach(key => {
            if (!headers.includes(key)) {
                headers.push(key);
            }
        });
    });

    if (headers.length === 0 && data.length > 0) {
        showToast("JSON 数组中的对象为空!", "#e67c73");
        return;
    }

    // 创建表格
    let table = document.createElement("table");

    // 表头
    let thead = document.createElement("thead");
    let headerRow = document.createElement("tr");
    headers.forEach(h => {
        let th = document.createElement("th");
        th.textContent = h;
        th.contentEditable = true; // 允许编辑表头
        headerRow.appendChild(th);
    });
    thead.appendChild(headerRow);
    table.appendChild(thead);

    // 表内容
    let tbody = document.createElement("tbody");
    data.forEach(row => {
        let tr = document.createElement("tr");
        headers.forEach(h => {
            let td = document.createElement("td");
            td.textContent = row[h] !== undefined ? row[h] : "";
            tr.appendChild(td);
        });
        tbody.appendChild(tr);
    });
    table.appendChild(tbody);

    container.appendChild(table);
    document.getElementById('copyButton').disabled = false; // 启用复制按钮
}

function copyTableToClipboard() {
    const table = document.querySelector("#tableContainer table");
    if (!table) {
        showToast("没有可复制的表格。", "#e67c73");
        return;
    }

    let dataString = "";
    const rows = table.querySelectorAll("tr");

    rows.forEach(row => {
        const rowData = [];
        const cells = row.querySelectorAll("th, td");
        cells.forEach(cell => {
            rowData.push(cell.textContent);
        });
        dataString += rowData.join("\t") + "\n";
    });

    if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(dataString).then(() => {
            showToast("表格内容已成功复制到剪贴板!", "#70ad47");
        }, (err) => {
            showToast("复制失败,请手动复制。", "#e67c73");
            console.error('无法复制: ', err);
        });
    } else {
        // 兼容旧版浏览器
        const textarea = document.createElement("textarea");
        textarea.value = dataString;
        document.body.appendChild(textarea);
        textarea.select();
        try {
            document.execCommand("copy");
            showToast("表格内容已成功复制到剪贴板!", "#70ad47");
        } catch (err) {
            showToast("复制失败,请手动复制。", "#e67c73");
        }
        document.body.removeChild(textarea);
    }
}

function loadSampleData() {
    const sample = [
        { "id": 1, "product": "笔记本电脑", "quantity": 10, "price": 8000 },
        { "id": 2, "product": "智能手机", "quantity": 25, "price": 4500 },
        { "id": 3, "product": "无线耳机", "quantity": 50, "price": 1200, "brand": "BrandX" }
    ];
    document.getElementById('jsonInput').value = JSON.stringify(sample, null, 2);
    showToast("示例数据已加载!");
}

function clearAll() {
    document.getElementById('jsonInput').value = '';
    document.getElementById('tableContainer').innerHTML = '';
    document.getElementById('copyButton').disabled = true; // 禁用复制按钮
    showToast("内容已清空", "#ed7d31");
}
</script>
</body>
</html>

演示地址:https://www.zanglikun.com/static-web/jsonArrayToExcel.html

特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤

免责声明:
本站文章旨在总结学习互联网技术过程中的经验与见解。任何人不得将其用于违法或违规活动!所有违规内容均由个人自行承担,与作者无关。