您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Agrega un botón a cada tabla HTML para exportarla a Excel usando ExcelJS
// ==UserScript== // @name Exportar Tablas HTML a Excel (con ExcelJS + Observer) // @namespace http://tampermonkey.net/ // @version 1.2 // @description Agrega un botón a cada tabla HTML para exportarla a Excel usando ExcelJS // @match *://*/* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; function injectScript(fn) { const script = document.createElement('script'); script.textContent = `(${fn})();`; document.body.appendChild(script); } function mainScript() { const exceljsSrc = 'https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.3.0/exceljs.min.js'; function loadExcelJS() { return new Promise((resolve) => { const script = document.createElement('script'); script.src = exceljsSrc; script.onload = resolve; document.head.appendChild(script); }); } function observeDOMForTables() { const observer = new MutationObserver(() => { const tables = document.querySelectorAll('table:not([data-excel-ready])'); if (tables.length > 0) { console.clear(); console.log('tables encontradas:', tables); } tables.forEach((table, index) => { table.setAttribute('data-excel-ready', 'true'); addExportButton(table, index + 1); }); }); observer.observe(document.body, { childList: true, subtree: true }); } function addExportButton(table, index) { const btn = document.createElement('button'); btn.textContent = '📥 Excel'; btn.style.position = 'absolute'; btn.style.fontSize = '12px'; btn.style.padding = '4px'; btn.style.background = '#4CAF50'; btn.style.color = '#fff'; btn.style.border = 'none'; btn.style.cursor = 'pointer'; btn.style.zIndex = 9999; const rect = table.getBoundingClientRect(); btn.style.top = `${window.scrollY + rect.top + 5}px`; btn.style.left = `${window.scrollX + rect.right - 80}px`; document.body.appendChild(btn); btn.addEventListener('click', () => exportTableToExcel(table, index)); } function exportTableToExcel(table, tableIndex) { const workbook = new ExcelJS.Workbook(); const sheet = workbook.addWorksheet(`Tabla ${tableIndex}`); const cellMap = {}; const rows = Array.from(table.rows); for (let rowIndex = 0, excelRowIndex = 1; rowIndex < rows.length; rowIndex++, excelRowIndex++) { const row = rows[rowIndex]; const cells = Array.from(row.cells); let colIndex = 1; cells.forEach(cell => { while (cellMap[`${excelRowIndex}:${colIndex}`]) colIndex++; const excelCell = sheet.getCell(excelRowIndex, colIndex); excelCell.value = cell.innerText.trim(); const colspan = parseInt(cell.getAttribute('colspan') || '1', 10); const rowspan = parseInt(cell.getAttribute('rowspan') || '1', 10); if (colspan > 1 || rowspan > 1) { const endCol = colIndex + colspan - 1; const endRow = excelRowIndex + rowspan - 1; sheet.mergeCells(excelRowIndex, colIndex, endRow, endCol); for (let r = excelRowIndex; r <= endRow; r++) { for (let c = colIndex; c <= endCol; c++) { cellMap[`${r}:${c}`] = true; } } } else { cellMap[`${excelRowIndex}:${colIndex}`] = true; } colIndex += colspan; }); } workbook.xlsx.writeBuffer().then((buffer) => { const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = `tabla_${tableIndex}.xlsx`; link.click(); }); } window.addEventListener('load', async () => { await loadExcelJS(); observeDOMForTables(); }); } injectScript(mainScript); })();