Add a button on pubhtml pages to download the sheet as an XLSX file.
// ==UserScript==
// @license MIT
// @name Published Google Sheets pubhtml link to XLSX file
// @namespace ViolentmonkeyScripts
// @match https://docs.google.com/spreadsheets/d/e/*/pubhtml*
// @grant none
// @version 1.0
// @description Add a button on pubhtml pages to download the sheet as an XLSX file.
// ==/UserScript==
(function () {
'use strict';
const ID = 'vm-download-xlsx-btn';
if (document.getElementById(ID)) return;
function buildDownloadUrl(href) {
// Replace trailing /pubhtml and any query string with /pub?output=xlsx
return href.replace(/\/pubhtml(\?.*)?$/, '/pub?output=xlsx');
}
function createButton() {
const btn = document.createElement('button');
btn.id = ID;
btn.type = 'button';
btn.textContent = 'Download XLSX';
Object.assign(btn.style, {
position: 'fixed',
top: '12px',
right: '12px',
zIndex: 99999,
padding: '8px 12px',
borderRadius: '6px',
border: 'none',
boxShadow: '0 2px 6px rgba(0,0,0,0.15)',
background: '#1a73e8',
color: '#fff',
fontSize: '13px',
cursor: 'pointer',
});
btn.addEventListener('click', (e) => {
e.preventDefault();
const downloadUrl = buildDownloadUrl(location.href);
window.open(downloadUrl, '_blank');
});
document.body.appendChild(btn);
}
// Some pubhtml pages may load late; try to insert immediately and also after load.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', createButton, { once: true });
} else {
createButton();
}
// If page dynamically replaces body, re-add button if needed.
const mo = new MutationObserver(() => {
if (!document.getElementById(ID) && location.href.includes('/pubhtml')) createButton();
});
mo.observe(document.documentElement, { childList: true, subtree: true });
})();