Created
August 24, 2024 05:13
-
-
Save jeznag/fbdec58a942e5c66a809b1b3eceb4689 to your computer and use it in GitHub Desktop.
Downloading airtable data if there's no export button
This file contains 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
// Run this in chrome dev tools | |
// Only helpful for one page worth of data | |
// Look at an API integration if you need to capture more data than that | |
(async function() { | |
const headerMap = {}; | |
const headerArray = ['Row Index']; // Add Row Index as the first column | |
const rowMap = {}; | |
// Function to extract and quote text content from a cell | |
function getCellText(cell) { | |
let text = cell.innerText.trim(); | |
// If the text contains a comma or a newline, wrap it in double quotes | |
if (text.includes(',') || text.includes('\n')) { | |
text = `"${text}"`; | |
} | |
return text; | |
} | |
// Function to process the currently visible rows | |
function processVisibleRows() { | |
const rows = document.querySelectorAll('.dataRow'); | |
rows.forEach(row => { | |
const rowId = row.getAttribute('data-rowid'); | |
const firstCell = row.querySelector('.cell[data-rowindex]'); | |
const rowIndex = firstCell ? firstCell.getAttribute('data-rowindex') : ''; | |
if (!rowMap[rowId]) { | |
rowMap[rowId] = { 'Row Index': rowIndex }; | |
// Initialize the row with empty strings for each column | |
headerArray.forEach(header => { | |
if (header !== 'Row Index') { // Row Index already added | |
rowMap[rowId][header] = ''; | |
} | |
}); | |
} | |
// Fill rowMap with data from each cell | |
const cells = row.querySelectorAll('.cell[data-columnid]'); | |
cells.forEach(cell => { | |
const cellText = getCellText(cell); | |
const columnName = headerMap[cell.getAttribute('data-columnid')]; | |
rowMap[rowId][columnName] = cellText; | |
}); | |
}); | |
console.log(`Processed ${rows.length} rows in this iteration.`); | |
} | |
// Function to capture headers | |
function captureHeaders() { | |
const headers = document.querySelectorAll('.gridHeaderCellPhosphorIcons'); | |
headers.forEach(header => { | |
const columnId = header.getAttribute('data-columnid'); | |
const headerText = getCellText(header); | |
headerMap[columnId] = headerText; | |
if (!headerArray.includes(headerText)) { | |
headerArray.push(headerText); | |
} | |
}); | |
} | |
// Function to prompt the user to scroll and continue processing | |
function promptToScroll() { | |
// Prompt the user to scroll | |
const shouldContinue = confirm("Scroll the page down and then click 'OK' to continue. Click 'Cancel' to stop."); | |
if (shouldContinue) { | |
// Capture visible rows | |
processVisibleRows(); | |
// Prompt again after a delay | |
setTimeout(promptToScroll, 1000); // Wait for 1 second before prompting again | |
} else { | |
console.log('Scrolling and processing stopped.'); | |
finalizeData(); | |
} | |
} | |
// Function to finalize the data and create the CSV | |
function finalizeData() { | |
const data = []; | |
// Convert the rowMap object to an array of rows in the correct order, sorted by Row Index | |
const sortedRows = Object.values(rowMap).sort((a, b) => a['Row Index'] - b['Row Index']); | |
sortedRows.forEach(rowObject => { | |
const rowArray = headerArray.map(header => rowObject[header]); | |
data.push(rowArray); | |
}); | |
// Add the headers as the first row | |
data.unshift(headerArray); | |
// Convert the data array to CSV format | |
const csvContent = data.map(e => e.join(",")).join("\n"); | |
// Create a Blob from the CSV data | |
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); | |
// Create a download link and click it programmatically | |
const link = document.createElement("a"); | |
const url = URL.createObjectURL(blob); | |
link.setAttribute("href", url); | |
link.setAttribute("download", "airtable_data.csv"); | |
document.body.appendChild(link); | |
link.click(); | |
document.body.removeChild(link); | |
console.log('CSV file has been generated and downloaded.'); | |
} | |
// Start by capturing the headers | |
captureHeaders(); | |
// Start the interactive scroll prompts | |
promptToScroll(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment