Greasy Fork

来自缓存

Greasy Fork is available in English.

Web表格导出助手

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

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 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();
    }
})();