Export Qualtrics Data & Analysis Table to Excel Including In-Progress Responses

The Qualtrics Data & Analysis table gives you a live view of your responses, including in-progress sessions with details like Survey Session ID, Last Question, and Progress percentage. This free browser script lets you capture that exact view as a formatted Excel file, across all pages and respecting any filter you have applied.

The Challenge

When you open the Data and Analysis tab in Qualtrics and filter the Data & Analysis table to show responses in progress, you have access to session-level detail that is genuinely useful for fieldwork management. The built-in Export Data function is optimised for completed responses, so this script fills the gap for teams who want to work with the filtered table view directly, including columns like Survey Session ID, Last Question, Progress percentage, and Expires.

If you are monitoring survey fieldwork, chasing partial completions, or auditing who started a survey and where they dropped off, you need exactly this data in a file you can share and work with.

The Solution

A JavaScript script that runs in your browser console and reads the Data & Analysis table directly from the page. It collects every visible row, handles date and time columns correctly, auto-navigates through all pages, and downloads the result as an Excel workbook.

How to Use

1

Open the Data and Analysis Tab

Navigate to your survey in Qualtrics and click Data and Analysis, then select the Data tab. Apply any filter you need, such as filtering to show only responses in progress.

2

Make Sure You Are on Page 1

The full export function starts from page 1 and works forward. If you are not on page 1, navigate back before running the script.

Page size tip: The script works with whichever page size you have selected (20, 50, or 100). It reads the total page count automatically and navigates each page in turn.
3

Open the Browser Console

Right-click anywhere on the Data & Analysis table and select Inspect or Inspect Element from the context menu. In the developer tools panel that opens, click the Console tab.

4

Paste and Run the Script

Click the Copy Script button below, paste it into the console, and press Enter. A usage guide will print in the console confirming the script is ready.

5

Run Your Export Command

Type one of these commands and press Enter:

// Export all pages to a single Excel file (recommended)
downloadAllPagesExcel()

// Export the current page only
downloadDataTableExcel()

// Preview current page data in the console
previewDataTable()

The Script

// ============================================================================
// QUALTRICS DATA TABLE — EXCEL EXPORT TOOLKIT
// Exports the Data & Analysis table (incl. In-Progress responses) to .xlsx
// Supports single-page and full multi-page export with auto-pagination
// Developed by Pirai AI — piraiai.com
// ============================================================================

(function () {

    // ── 1. LOAD SheetJS from CDN ─────────────────────────────────────────────
    function loadSheetJS(callback) {
        if (window.XLSX) { callback(); return; }
        const script = document.createElement('script');
        script.src = 'https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js';
        script.onload = () => { console.log('✅ SheetJS loaded'); callback(); };
        script.onerror = () => console.error('❌ Failed to load SheetJS.');
        document.head.appendChild(script);
    }

    // ── 2. PAGINATION HELPERS ────────────────────────────────────────────────

    function getTotalPages() {
        const pagination = document.querySelector('[data-testid="DataTablePagination"]');
        if (!pagination) return 1;
        const text = pagination.textContent || '';
        const match = text.match(/of\s+(\d+)/);
        return match ? parseInt(match[1], 10) : 1;
    }

    function getCurrentPage() {
        const input = document.querySelector('[data-testid="DataTablePagination-PageInput"]');
        return input ? parseInt(input.value, 10) : 1;
    }

    function isTableLoading() {
        const spinner = document.querySelector('[role="progressbar"][aria-label="Loading"]');
        return spinner && spinner.offsetParent !== null;
    }

    function waitForTableReady(timeout = 8000) {
        return new Promise((resolve, reject) => {
            const start = Date.now();
            const check = () => {
                if (!isTableLoading()) {
                    // Small buffer after spinner disappears for DOM to settle
                    setTimeout(resolve, 400);
                } else if (Date.now() - start > timeout) {
                    reject(new Error('Timed out waiting for table to load'));
                } else {
                    setTimeout(check, 200);
                }
            };
            // Give Qualtrics a moment to show the spinner before polling
            setTimeout(check, 300);
        });
    }

    function clickNextPage() {
        const btn = document.querySelector('[data-testid="DataTablePagination-NextButton"]');
        if (!btn || btn.getAttribute('aria-disabled') === 'true') return false;
        btn.click();
        return true;
    }

    // ── 3. EXTRACT VISIBLE TABLE DATA ────────────────────────────────────────

    function extractVisibleRows(existingHeaders = null) {
        const result = { headers: [], rows: [] };

        if (!existingHeaders) {
            document.querySelectorAll('table thead tr th').forEach(th => {
                const label = th.getAttribute('aria-label') || th.textContent.trim();
                if (label && label !== 'Record Selection') result.headers.push(label);
            });
        } else {
            result.headers = existingHeaders;
        }

        document.querySelectorAll('table tbody tr').forEach(tr => {
            const cells = tr.querySelectorAll('td');
            const rowData = [];
            let skippedFirst = false;

            cells.forEach(td => {
                if (!skippedFirst) { skippedFirst = true; return; }

                const spans = td.querySelectorAll('span');
                if (spans.length > 0) {
                    const parts = Array.from(spans).map(s => s.textContent.trim()).filter(Boolean);
                    rowData.push(parts.join(' '));
                } else {
                    const btn = td.querySelector('button');
                    rowData.push(btn ? btn.textContent.trim() : td.textContent.trim());
                }
            });

            if (rowData.some(cell => cell !== '')) result.rows.push(rowData);
        });

        return result;
    }

    // ── 4. BUILD & DOWNLOAD EXCEL ────────────────────────────────────────────

    function buildAndDownload(headers, allRows) {
        if (headers.length === 0 || allRows.length === 0) {
            console.error('❌ No data to export.');
            return;
        }

        const wsData = [headers, ...allRows];
        const ws = XLSX.utils.aoa_to_sheet(wsData);

        ws['!cols'] = headers.map((h, colIdx) => {
            const maxLen = wsData.reduce((max, row) => {
                const val = row[colIdx] ? String(row[colIdx]) : '';
                return Math.max(max, val.length);
            }, h.length);
            return { wch: Math.min(maxLen + 2, 50) };
        });

        const wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, 'Survey Data');

        const wsMeta = XLSX.utils.aoa_to_sheet([
            ['Export Info', ''],
            ['Exported by', 'Pirai AI Data Table Toolkit'],
            ['Exported at', new Date().toLocaleString()],
            ['Total rows', allRows.length],
            ['Columns', headers.join(', ')]
        ]);
        wsMeta['!cols'] = [{ wch: 20 }, { wch: 60 }];
        XLSX.utils.book_append_sheet(wb, wsMeta, 'Export Info');

        const timestamp = new Date().toISOString().slice(0, 19).replace(/[T:]/g, '-');
        const filename = `qualtrics_data_table_${timestamp}.xlsx`;
        XLSX.writeFile(wb, filename);

        console.log(`\n✅ Exported ${allRows.length} rows × ${headers.length} columns`);
        console.log(`📥 File: ${filename}`);
    }

    // ── 5. SINGLE-PAGE EXPORT ────────────────────────────────────────────────

    window.downloadDataTableExcel = function () {
        console.log('\n🔄 Exporting current page...');
        loadSheetJS(() => {
            const { headers, rows } = extractVisibleRows();
            console.log(`📊 Found ${rows.length} rows, ${headers.length} columns`);
            buildAndDownload(headers, rows);
        });
    };

    // ── 6. MULTI-PAGE EXPORT (AUTO-PAGINATE) ─────────────────────────────────

    window.downloadAllPagesExcel = async function () {
        const totalPages = getTotalPages();
        const startPage = getCurrentPage();

        console.log(`\n╔══════════════════════════════════════════════════════════╗`);
        console.log(`║  Starting full export — ${totalPages} page(s) detected`);
        console.log(`╚══════════════════════════════════════════════════════════╝\n`);

        if (startPage !== 1) {
            console.warn(`⚠️  Not on page 1. Navigate to page 1 first, then re-run.`);
            return;
        }

        loadSheetJS(async () => {
            let allRows = [];
            let headers = null;

            for (let page = 1; page <= totalPages; page++) {
                console.log(`📄 Extracting page ${page} of ${totalPages}...`);

                try {
                    await waitForTableReady();
                } catch (e) {
                    console.warn(`⚠️ Page ${page} load timeout — extracting whatever is visible`);
                }

                const { headers: h, rows } = extractVisibleRows(headers);
                if (!headers) headers = h;

                console.log(`   ↳ ${rows.length} rows collected (running total: ${allRows.length + rows.length})`);
                allRows = allRows.concat(rows);

                if (page < totalPages) {
                    const moved = clickNextPage();
                    if (!moved) {
                        console.warn(`⚠️ Next page button unavailable at page ${page}. Stopping early.`);
                        break;
                    }
                    // Brief pause before polling for spinner
                    await new Promise(r => setTimeout(r, 600));
                }
            }

            console.log(`\n📊 Total rows collected across all pages: ${allRows.length}`);
            buildAndDownload(headers, allRows);
        });
    };

    // ── 7. PREVIEW ───────────────────────────────────────────────────────────

    window.previewDataTable = function () {
        const data = extractVisibleRows();
        console.log(`\n📋 Headers (${data.headers.length}):`, data.headers);
        console.table(
            data.rows.map(row =>
                Object.fromEntries(data.headers.map((h, i) => [h, row[i] || '']))
            )
        );
        return data;
    };

    // ── 8. USAGE GUIDE ───────────────────────────────────────────────────────
    console.log(`
╔══════════════════════════════════════════════════════════════╗
║   QUALTRICS DATA TABLE — EXCEL EXPORT TOOLKIT               ║
║   Pirai AI — piraiai.com                                    ║
╠══════════════════════════════════════════════════════════════╣
║                                                              ║
║  BEFORE RUNNING:                                             ║
║  • Go to Data & Analysis → Data tab                         ║
║  • Apply your filter (e.g. "Responses in progress")         ║
║  • Make sure you are on page 1                              ║
║                                                              ║
║  COMMANDS:                                                   ║
║                                                              ║
║  previewDataTable()         — Preview current page          ║
║  downloadDataTableExcel()   — Export current page as .xlsx  ║
║  downloadAllPagesExcel()    — Export ALL pages as .xlsx ⭐  ║
║                                                              ║
║  downloadAllPagesExcel() reads the "of N" page count,       ║
║  auto-clicks Next Page, waits for each page to fully load,  ║
║  collects all rows, then downloads a single combined .xlsx   ║
║                                                              ║
╚══════════════════════════════════════════════════════════════╝

Ready! Run: downloadAllPagesExcel()
`);

})();                    
                                    
                

Excel Output Format

The downloaded file contains two sheets. The first sheet holds the full Data & Analysis table exactly as it appears in Qualtrics. The second sheet records export metadata for reference.

Survey Session ID | First Name | Last Name | Email | Start Time | Last Activity | Expires | Last Question | Progress
FS_922QFbtytRIUlwo | | | | Apr 22, 2026 9:44 PM | Apr 22, 2026 9:44 PM | Apr 29, 2026 9:44 PM | Q1 | 13%
FS_9rGZnmBVqVpDVip | | | | Apr 22, 2026 9:44 PM | Apr 22, 2026 9:44 PM | Apr 29, 2026 9:44 PM | S14 | 9%
Column Description
Survey Session ID The unique session identifier for each response, useful for tracking partial completions
First Name / Last Name / Email Contact fields populated when the respondent was pre-loaded via a distribution
IP Address Respondent IP address if collected by the survey
External Reference External ID passed through the distribution link
Start Time When the respondent first opened the survey
Last Activity The most recent time the respondent interacted with the survey
Expires When the session link will expire and the response will be lost
Last Question The question ID where the respondent stopped, useful for identifying drop-off points
Progress Percentage of the survey completed at the time of export

How the Auto-Pagination Works

When you run downloadAllPagesExcel(), the script reads the total page count from the pagination control on the page, then works through each page automatically. After clicking the Next Page button, it watches for the Qualtrics loading spinner to appear and then clear before collecting that page's rows. Once all pages are collected, it combines everything into a single Excel file and triggers the download.

Keep the tab active while exporting

Some browsers throttle timers in background tabs. Keep the Qualtrics tab visible while the script runs to avoid timing issues, especially with larger datasets across many pages.

Use Cases

📋

Fieldwork Monitoring

Track which respondents have started but not completed the survey, and how far they got before dropping off.

Expiry Chasing

Identify sessions expiring soon so you can send reminder distributions before the data is lost.

🔍

Drop-off Analysis

Use the Last Question column to find where respondents are abandoning the survey and improve those sections.

📊

Reporting

Share a clean snapshot of response progress with stakeholders who do not have Qualtrics access.

Quality Assurance

Audit session data before closing a survey to confirm all expected respondents have submitted.

🗃️

Archiving

Save a timestamped record of the Data & Analysis table state at key milestones during fieldwork.

Troubleshooting

No rows exported

Make sure the Data & Analysis table is fully loaded and visible before running the script. If you applied a filter, confirm the table has refreshed and rows are showing before calling the export command.

Export stops before the last page

This usually happens when the Next Page button becomes disabled unexpectedly. Try keeping the browser tab active and in focus while the script runs. If the issue persists, use downloadDataTableExcel() on each page manually and combine the files.

Script not working

Clear the console and paste the script again. Make sure you are using a modern browser such as Chrome, Edge, or Firefox. The script does not work in Internet Explorer.

Important notes: This is a browser-based tool requiring no installation. Your data stays private and everything runs locally in your browser. Works with all Qualtrics licence types and requires no API key.

Automate Your Survey Workflow

Pirai AI converts Word, PDF, and Excel questionnaires into Qualtrics and 20+ other platforms automatically. No manual programming required.

Try Pirai AI Free