Table to Excel Downloader

Detect tables and add a download button to export them to Excel

  1. // ==UserScript==
  2. // @name Table to Excel Downloader
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Detect tables and add a download button to export them to Excel
  6. // @author yazhangya
  7. // @match http*://*/*
  8. // @grant none
  9. // @require https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.0/xlsx.full.min.js
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. function getCurrentDateTime() {
  17. const now = new Date();
  18. const year = now.getFullYear().toString().slice(-2);
  19. const month = (now.getMonth() + 1).toString().padStart(2, '0');
  20. const day = now.getDate().toString().padStart(2, '0');
  21. const hours = now.getHours().toString().padStart(2, '0');
  22. const minutes = now.getMinutes().toString().padStart(2, '0');
  23. const seconds = now.getSeconds().toString().padStart(2, '0');
  24.  
  25. return `${year}${month}${day}${hours}${minutes}${seconds}`;
  26. }
  27.  
  28.  
  29. // Function to create and download the Excel file
  30. function downloadTableAsExcel(table, index) {
  31. const wb = XLSX.utils.book_new();
  32. const ws = XLSX.utils.table_to_sheet(table, {raw: true});
  33. console.log(ws);
  34. XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
  35. const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
  36.  
  37. function s2ab(s) {
  38. const buf = new ArrayBuffer(s.length);
  39. const view = new Uint8Array(buf);
  40. for (let i = 0; i < s.length; i++) {
  41. view[i] = s.charCodeAt(i) & 0xFF;
  42. }
  43. return buf;
  44. }
  45.  
  46. const blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });
  47. const url = URL.createObjectURL(blob);
  48. const a = document.createElement('a');
  49. a.href = url;
  50. a.download = 'table_'+index+'_'+getCurrentDateTime()+".xlsx";
  51. document.body.appendChild(a);
  52. a.click();
  53. document.body.removeChild(a);
  54. URL.revokeObjectURL(url);
  55. }
  56.  
  57. // Function to create the download button
  58. function createDownloadButton(table, index) {
  59. const button = document.createElement('button');
  60. button.textContent = `[${index}]下载`;
  61. button.style.position = 'absolute';
  62. button.style.zIndex = 1000;
  63. button.style.padding = '5px 10px';
  64. button.style.backgroundColor = '#4CAF50';
  65. button.style.color = 'white';
  66. button.style.border = 'none';
  67. button.style.borderRadius = '5px';
  68. button.style.cursor = 'pointer';
  69. button.style.fontSize = '12px';
  70.  
  71. button.addEventListener('click', () => downloadTableAsExcel(table,index));
  72.  
  73. document.body.appendChild(button);
  74.  
  75. // Position the button based on table width and viewport width
  76. const rect = table.getBoundingClientRect();
  77. const viewportWidth = window.innerWidth;
  78. const buttonWidth = button.offsetWidth;
  79.  
  80. let left, top;
  81.  
  82. if (rect.width < viewportWidth) {
  83. // Table width is less than viewport width, position button above table in the center
  84. left = rect.left + (rect.width - buttonWidth) / 2 + window.scrollX;
  85. top = rect.top - button.offsetHeight - 5 + window.scrollY;
  86. } else {
  87. // Table width is greater than or equal to viewport width, position button in the center of the viewport
  88. left = (viewportWidth - buttonWidth) / 2 + window.scrollX;
  89. top = rect.top - button.offsetHeight - 5 + window.scrollY;
  90. }
  91.  
  92. button.style.left = `${left}px`;
  93. button.style.top = `${top}px`;
  94. }
  95.  
  96. // Function to detect tables and add the download button
  97. function detectTables() {
  98. const tables = document.querySelectorAll('table');
  99. console.log(`Found ${tables.length} tables`);
  100.  
  101. if (tables.length > 0) {
  102. for(var i=0; i< tables.length ; i++){
  103. createDownloadButton(tables[i],i);
  104. }
  105. return true; // Indicate that a table was found
  106. }
  107. return false; // Indicate that no table was found
  108. }
  109.  
  110. // Use MutationObserver to detect when the DOM is fully loaded and rendered
  111. const observer = new MutationObserver((mutations, obs) => {
  112. if (detectTables()) {
  113. obs.disconnect(); // Stop observing after a table is found
  114. }
  115. });
  116.  
  117. observer.observe(document, {
  118. childList: true,
  119. subtree: true
  120. });
  121.  
  122. // Also run the detection function when the page is fully loaded
  123. window.addEventListener('load', detectTables);
  124. })();