Greasy Fork 还支持 简体中文。

Web表格导出助手

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

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==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();
    }
})();