Web表格导出助手

从网页中提取表格并导出为Excel

// ==UserScript==
// @name         Web表格导出助手
// @namespace    http://tampermonkey.net/
// @version      1.31
// @description  从网页中提取表格并导出为Excel
// @match        *://*/*
// @grant        none
// @license      All Rights Reserved
// @require      https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.5/xlsx.full.min.js
// ==/UserScript==

(function() {
    'use strict';

    // 创建菜单按钮
    function createMenuButton() {
        const button = document.createElement('div');
        button.innerHTML = '📊';
        button.style.cssText = `
            position: fixed;
            top: 20px;
            left: 20px;
            background-color: #4CAF50;
            color: white;
            padding: 1px 2px;
            border-radius: 5px;
            cursor: pointer;
            z-index: 9999;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
        `;
        button.onclick = extractTables;
        document.body.appendChild(button);
    }

    // 生成随机文件名
    function generateRandomFileName() {
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        const randomString = Array.from(
            {length: 6},
            () => chars[Math.floor(Math.random() * chars.length)]
        ).join('');
        const date = new Date();
        const dateStr = `${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}`;
        return `${document.title || randomString}_${dateStr}`;
    }

    // 导出Excel
    function exportToExcel(tables, index = null) {
        if (index !== null) {
            // 导出特定表格
            const table = tables[index];
            const wb = XLSX.utils.book_new();
            const ws = XLSX.utils.aoa_to_sheet(table);
            XLSX.utils.book_append_sheet(wb, ws, `Table ${index + 1}`);

            const fileName = `${generateRandomFileName()}_table${index + 1}.xlsx`;
            XLSX.writeFile(wb, fileName);
        } else {
            // 导出所有表格
            tables.forEach((table, idx) => {
                const wb = XLSX.utils.book_new();
                const ws = XLSX.utils.aoa_to_sheet(table);
                XLSX.utils.book_append_sheet(wb, ws, `Table ${idx + 1}`);

                const fileName = `${generateRandomFileName()}_table${idx + 1}.xlsx`;
                XLSX.writeFile(wb, fileName);
            });
        }
    }

    // 提取表格数据
    function extractTables() {
        const tables = Array.from(document.querySelectorAll('table')).map(table => {
            // 提取表格数据
            return Array.from(table.rows).map(row =>
                Array.from(row.cells).map(cell => cell.innerText.trim())
            );
        });

        if (tables.length === 0) {
            alert('未找到任何表格');
            return;
        }

        // 创建对话框
        const previewHtml = tables.map((table, index) => `
            <div id="tablePreview${index}" style="
                margin-bottom: 15px;
                background-color: #f9f9f9;
                border-radius: 10px;
                overflow: hidden;
                box-shadow: 0 4px 6px rgba(0,0,0,0.1);
                transition: transform 0.3s, box-shadow 0.3s;
            ">
                <div style="
                    background-color: #2196F3;
                    color: white;
                    padding: 10px 15px;
                    display: flex;
                    align-items: center;
                    justify-content: space-between;
                ">
                    <h5 style="margin: 0;">表格 ${index + 1}</h5>
                    <button onclick="document.dispatchEvent(new CustomEvent('exportSpecificTable', {detail: ${index}}))"
                        style="
                            background-color: white;
                            color: #2196F3;
                            border: none;
                            padding: 5px 10px;
                            border-radius: 5px;
                            cursor: pointer;
                            transition: background-color 0.3s;
                        "
                        onmouseover="this.style.backgroundColor='#f0f0f0'"
                        onmouseout="this.style.backgroundColor='white'"
                    >
                        导出
                    </button>
                </div>
                <div style="
                    max-height: 200px;
                    overflow-y: auto;
                    padding: 10px;
                ">
                    <table style="
                        width: 100%;
                        border-collapse: collapse;
                    ">
                        ${table.slice(0, 5).map(row => `
                            <tr style="border-bottom: 1px solid #e0e0e0;">
                                ${row.map(cell => `
                                    <td style="
                                        padding: 8px;
                                        text-align: left;
                                        max-width: 150px;
                                        overflow: hidden;
                                        text-overflow: ellipsis;
                                        white-space: nowrap;
                                    ">${cell}</td>
                                `).join('')}
                            </tr>
                        `).join('')}
                    </table>
                </div>
            </div>
        `).join('');

        const dialogHtml = `
            <div id="tableExportDialog" style="
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: white;
                border-radius: 15px;
                box-shadow: 0 15px 50px rgba(0,0,0,0.2);
                max-width: 600px;
                width: 95%;
                max-height: 100%;
                overflow: auto;
                z-index: 10001;
                padding: 20px;
            ">
                <div style="
                    background: linear-gradient(135deg, #2196F3, #1565c0);
                    color: white;
                    padding: 15px;
                    border-radius: 10px 10px 0 0;
                    margin: -20px -20px 20px;
                    text-align: center;
                ">
                    <h3 style="margin: 0;">选择要导出的表格</h3>
                </div>

                <div id="tablePreviewContainer">
                    ${previewHtml}
                </div>

                <div style="
                    display: flex;
                    justify-content: center;
                    margin-top: 20px;
                    gap: 15px;
                ">
                    <button id="exportAllBtn" style="
                        background-color: #4CAF50;
                        color: white;
                        border: none;
                        padding: 10px 20px;
                        border-radius: 8px;
                        cursor: pointer;
                        transition: background-color 0.3s;
                    "
                    onmouseover="this.style.backgroundColor='#45a049'"
                    onmouseout="this.style.backgroundColor='#4CAF50'"
                    >
                        导出所有表格
                    </button>
                    <button id="cancelBtn" style="
                        background-color: #f44336;
                        color: white;
                        border: none;
                        padding: 10px 20px;
                        border-radius: 8px;
                        cursor: pointer;
                        transition: background-color 0.3s;
                    "
                    onmouseover="this.style.backgroundColor='#d32f2f'"
                    onmouseout="this.style.backgroundColor='#f44336'"
                    >
                        取消
                    </button>
                </div>
            </div>
            <div id="tableExportOverlay" style="
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.5);
                backdrop-filter: blur(5px);
                z-index: 10000;
            "></div>
        `;

        // 创建对话框
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = dialogHtml;
        document.body.appendChild(tempDiv.firstElementChild);
        document.body.appendChild(tempDiv.lastElementChild);

        // 添加悬停效果
        const previews = document.querySelectorAll('[id^="tablePreview"]');
        previews.forEach(preview => {
            preview.addEventListener('mouseenter', () => {
                preview.style.transform = 'scale(1.02)';
                preview.style.boxShadow = '0 6px 12px rgba(0,0,0,0.15)';
            });
            preview.addEventListener('mouseleave', () => {
                preview.style.transform = 'scale(1)';
                preview.style.boxShadow = '0 4px 6px rgba(0,0,0,0.1)';
            });
        });

        // 添加事件监听
        document.getElementById('exportAllBtn').onclick = () => {
            exportToExcel(tables);
            closeDialog();
        };

        document.getElementById('cancelBtn').onclick = closeDialog;
        document.getElementById('tableExportOverlay').onclick = closeDialog;

        // 监听导出特定表格事件
        document.addEventListener('exportSpecificTable', (e) => {
            exportToExcel(tables, e.detail);
            closeDialog();
        });
    }

    // 关闭对话框
    function closeDialog() {
        const dialog = document.getElementById('tableExportDialog');
        const overlay = document.getElementById('tableExportOverlay');
        if (dialog) dialog.remove();
        if (overlay) overlay.remove();
    }

    // 初始化
    function init() {
        createMenuButton();
    }

    // 等待页面加载完成
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址