Download Table as CSV

Add a download / copy button at the top of every html table to download / export it as a CSV file

当前为 2020-12-05 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Download Table as CSV
  3. // @namespace https://greasyfork.org/en/scripts/418114-download-table-as-csv
  4. // @match *://*/*
  5. // @grant GM_registerMenuCommand
  6. // @grant unsafeWindow
  7. // @version 2.01
  8. // @author igorlogius & drshajul
  9. // @description Add a download / copy button at the top of every html table to download / export it as a CSV file
  10. // ==/UserScript==
  11.  
  12. (function(){
  13.  
  14. // simulate click event
  15. function simulateClick(elem) {
  16. var evt = new MouseEvent('click', {
  17. bubbles: true,
  18. cancelable: true,
  19. view: unsafeWindow
  20. });
  21. var canceled = !elem.dispatchEvent(evt);
  22. }
  23.  
  24. // get closest table parent
  25. function getTableParent(node){
  26. while ( node = node.parentNode, node !== null && node.tagName !== 'TABLE' );
  27. return node;
  28. }
  29.  
  30. // assemble csv data
  31. function getTblData(tbl){
  32. // csv store
  33. var csv = [];
  34. // get all rows inside the table
  35. tbl.querySelectorAll('tr').forEach(function(trRow) {
  36. // Only process direct tr children
  37. if( ! tbl.isEqualNode(getTableParent(trRow))){
  38. return;
  39. }
  40. // assemble row content
  41. var row = [];
  42. trRow.querySelectorAll('td, th').forEach(function(col) {
  43. // remove multiple spaces and linebreaks (breaks csv)
  44. var data = col.innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ')
  45. // escape double-quote with double-double-quote
  46. data = data.replace(/"/g, '""');
  47. row.push('"' + data + '"');
  48. });
  49. csv.push(row.join(','));
  50. });
  51. return csv.join('\n');
  52. }
  53.  
  54. // add button + click action
  55. function add_btn(tbl){
  56. tbl.style.border = "2px solid yellow";
  57. var btn = document.createElement('img');
  58. btn.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAADsAAAA7AF5KHG9AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAARdJREFUWIXtlj0KwkAQhb8YELSxtfH3EpJC7yLY6ynEwttZS1BPICgkNrHIbIqQJZl1g00evGKT3XkfCZkM6HUCUiArOQWODvXUqgo3TrTFAgeAzGfNngOAV3UAHUAH0AHYAHbAm+p2W6eqM29gqwHYAMMGYU01BNaaAzMgxv7T0ToGplrqKXD1EH4DFtpwXxA/hf8K4SXcFcJruBbiBix9hzeFaDW8DsI53Dbllv0EIjlT7hMxMJd7keytq1dM0U3CbRAXsTbcOEGx2fhF3qrL0oYbOzWYF7AHxuKDXFPXCgzFv9TmPPAQ29aFXF5Bne/AQHyvWBd7/z4RBeSfYb+F2uZxTyxrgDQkn1ZWQOgZYCS2rT/A+Qu+RBVvAUbgRQAAAABJRU5ErkJggg==";
  59. btn.alt = btn.title = "Download Table";
  60. var btnCopy = document.createElement('img');
  61. btnCopy.src = " data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAACXBIWXMAAAsTAAALEwEAmpwYAAACFklEQVRIie2Wv6riQBTGjzEJin/wgiCKiNppJWgrdjYWFpaCYKGd6CP4DBYWplOEFD6BZcROFExhbBIQxFJEEM1oZovZzb13NZp13WbxVx3IzPedMzM5MxaMMfxLaD06HA4cx02nU03TTE622Wy5XC6fz1ssFsNBGGOM8eFwSKVSz+XYaDSwMRayRK1Wq16vA0AoFHK73Sal1+v1drulKEoUxXg8fq+CcrkMAMFgECF0J53fmM/nRKTf7xuNociIy+UCAC6Xi6bp24nc4uPjgwR3tu2B3HA4FAQBIXTz636/JwHP86IoAgDDMOl0OpvNfm47KaRUKgFALBbTS9M0rVqtmq/mK5VKRdM0omNYgSAInU4HAFiWtdlsJqWPx6OqqhzHFYvFTCYDd5ZoPB4DAMMwsiz7/X6TBpvNJhKJIIRGo9EDg/P5DAA0Tft8PoqiTBr4fD6aphFC5NQAgNmZT/M2eBu8DfQ/mTReRVHa7bbH4wEA0h1fAOl5k8nk5k1gt9v/6ApCCNntdgBoNpvfLpxkMsnzfCAQeE3WX/jcg0KhsFqtFEWRJEmSpFqt9hKDb8titVrD4TCJvV7vSwz+m2N6jcPhAABVVQeDQTQaNSkny/LpdNKnA/w6ptcsl0uWZZ/LmmXZxWJBdAwNMMa9Xs/8K0/H6XR2u11d5OfT0YjdbjebzYzeRdcwDJNIJEgvIDww+Ht+AFt8q8cWNQVnAAAAAElFTkSuQmCC";
  62. btnCopy.alt = btnCopy.title = "Copy Table";
  63. btn.classList.add("drshajul-download");
  64. btnCopy.classList.add("drshajul-download");
  65. // Process Table on Click
  66. var csv_string = getTblData(tbl);
  67. btn.onclick = function() {
  68. csvlink.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv_string));
  69. simulateClick(csvlink);
  70. };
  71. btnCopy.onclick = function() {
  72. var copy_string = csv_string.replace(/","/gm,"\t").replace(/"/gm,'');
  73. var dummy = document.createElement("textarea");
  74. document.body.appendChild(dummy);
  75. dummy.value = copy_string;
  76. dummy.select();
  77. dummy.setSelectionRange(0, 99999); /*For mobile devices*/
  78. document.execCommand("copy");
  79. document.body.removeChild(dummy);
  80. };
  81. // Insert before Table
  82. tbl.parentNode.insertBefore(btn,tbl);
  83. tbl.parentNode.insertBefore(btnCopy,tbl);
  84. }
  85.  
  86.  
  87. /* * *
  88. * M A I N *
  89. * */
  90.  
  91. GM_registerMenuCommand('Show Table Downloads', () => {
  92. document.querySelectorAll('table').forEach(function(tbl){
  93. add_btn(tbl);
  94. });
  95. });
  96.  
  97. var style = document.createElement('style');
  98. style.innerHTML = `
  99. .drshajul-download {
  100. display: inline-block;
  101. width: 24px;
  102. height: 24px;
  103. cursor: pointer;
  104. opacity: 0.5;
  105. background-color: white;
  106. margin: 5px;
  107. }
  108. .drshajul-download:hover {
  109. opacity: 1;
  110. }
  111. `;
  112. document.head.appendChild(style);
  113.  
  114. // add link
  115. var csvlink = document.createElement('a');
  116. csvlink.style.display = 'none';
  117. csvlink.setAttribute('target', '_blank');
  118. csvlink.setAttribute('download', 'data.csv');
  119. document.body.append(csvlink);
  120.  
  121. // add buttons - moved to the tampermonkey menu
  122. // document.querySelectorAll('table').forEach(function(tbl){add_btn(tbl)});
  123. }());