Created
January 30, 2026 22:59
-
-
Save jskherman/def6994d5be5b5d19a16674d401f9c07 to your computer and use it in GitHub Desktop.
Microsoft Script Lab Extension: Excel Cell Range to CSV/TSV in Clipboard
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Ensure the container takes full height of the pane */ | |
| html, body { | |
| height: 100%; | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| #app-container { | |
| display: flex; | |
| flex-direction: column; | |
| height: 100vh; /* Viewport height */ | |
| padding: 15px; | |
| box-sizing: border-box; | |
| } | |
| .header-section { | |
| flex: 0 0 auto; /* Do not grow or shrink */ | |
| margin-bottom: 15px; | |
| } | |
| .button-row { | |
| display: flex; | |
| gap: 10px; /* Space between buttons */ | |
| } | |
| .action-btn { | |
| flex: 1; /* Both buttons take equal width */ | |
| height: 60px; /* Taller click area */ | |
| font-size: 16px; | |
| } | |
| .output-section { | |
| flex: 1 1 auto; /* Grow to fill remaining space */ | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| textarea { | |
| flex: 1 1 auto; /* Grow to fill the output section */ | |
| width: 100%; | |
| resize: none; /* Disable manual resize since it auto-fills */ | |
| font-family: 'Consolas', 'Monaco', monospace; | |
| font-size: 12px; | |
| padding: 10px; | |
| border: 1px solid #ccc; | |
| /* UPDATED: Disable text wrapping and enable scrolling */ | |
| white-space: pre; | |
| overflow: auto; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div id="app-container"> | |
| <div class="header-section"> | |
| <p class="ms-font-l">Select range and choose format:</p> | |
| <div class="button-row"> | |
| <button id="run-csv" class="ms-Button ms-Button--primary action-btn"> | |
| <span class="ms-Button-label">Copy CSV</span> | |
| </button> | |
| <button id="run-tsv" class="ms-Button ms-Button--primary action-btn"> | |
| <span class="ms-Button-label">Copy TSV</span> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="output-section"> | |
| <textarea id="status" placeholder="Output preview will appear here..."></textarea> | |
| </div> | |
| </div> |
We can make this file beautiful and searchable if this error is corrected: No commas found in this CSV file in line 0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| https://appsforoffice.microsoft.com/lib/1/hosted/office.js | |
| https://code.jquery.com/jquery-3.7.1.min.js | |
| https://unpkg.com/d3-dsv@3.0.1/dist/d3-dsv.min.js |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Register event listeners | |
| $("#run-csv").click(() => tryCatch(() => run("csv"))); | |
| $("#run-tsv").click(() => tryCatch(() => run("tsv"))); | |
| async function run(formatType) { | |
| await Excel.run(async (context) => { | |
| // 1. Get Selection | |
| const range = context.workbook.getSelectedRange(); | |
| range.load("values"); | |
| await context.sync(); | |
| // 2. Parse Data | |
| let formattedData = ""; | |
| if (formatType === "csv") { | |
| formattedData = d3.csvFormatRows(range.values); | |
| } else if (formatType === "tsv") { | |
| formattedData = d3.tsvFormatRows(range.values); | |
| } | |
| // 3. Copy to Clipboard | |
| try { | |
| await navigator.clipboard.writeText(formattedData); | |
| // Update UI with preview | |
| const timestamp = new Date().toLocaleTimeString(); | |
| const statusMsg = `[${timestamp}] Copied ${formatType.toUpperCase()} to clipboard:\n\n${formattedData}`; | |
| document.getElementById("status").value = statusMsg; | |
| } catch (err) { | |
| document.getElementById("status").value = "Error accessing clipboard: " + err; | |
| } | |
| }); | |
| } | |
| /** Helper for error handling */ | |
| async function tryCatch(callback) { | |
| try { | |
| await callback(); | |
| } catch (error) { | |
| console.error(error); | |
| document.getElementById("status").value = error.toString(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment