Implementing Excel File Downloads in JavaScript

Handling file downloads in web applications—specifically exporting Excel files—requires careful management of binary data. Below are the primary technical approaches to triggering these downloads in a frontend environment.

1. Handling Blob Data via Axios

When interacting with APIs that return binary data, the most robust approach involvse setting the responseType to blob. This prevents the browser from misinterpreting the binary stream as plain text.

import axios from 'axios';

export async function downloadExcel(apiPath, payload, outputName) {
   const response = await axios.post(apiPath, payload, {
       responseType: 'blob'
   });

   const fileBlob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });

   // Handle modern browsers via hidden anchor tag
   if (window.navigator && window.navigator.msSaveOrOpenBlob) {
       window.navigator.msSaveOrOpenBlob(fileBlob, `${outputName}.xlsx`);
   } else {
       const link = document.createElement('a');
       link.href = URL.createObjectURL(fileBlob);
       link.download = `${outputName}.xlsx`;
       document.body.appendChild(link);
       link.click();
       document.body.removeChild(link);
       URL.revokeObjectURL(link.href);
   }
}

2. Using XMLHttpRequest for Legacy Compatibility

For scenarios where direct control over the request lifecycle is needed, XMLHttpRequest allows for granular handling of binary responses.

function fetchAndDownload(url, params) {
   const xhr = new XMLHttpRequest();
   xhr.open('POST', url, true);
   xhr.responseType = 'blob';

   xhr.onload = function() {
       if (this.status === 200) {
           const link = document.createElement('a');
           link.href = window.URL.createObjectURL(this.response);
           link.download = 'export_data.xlsx';
           link.click();
       }
   };
   xhr.send(JSON.stringify(params));
}

3. Form Submission Approach

If the backend endpoint is configured to trigger a download directly when receiving a POST request (without needing to handle a JSON response), dynamically creating and submitting an invisible HTML form is a reliable technique.

function submitExportForm(actionUrl, params) {
   const form = document.createElement('form');
   form.method = 'POST';
   form.action = actionUrl;
   form.style.display = 'none';

   for (const key in params) {
       const input = document.createElement('input');
       input.name = key;
       input.value = params[key];
       form.appendChild(input);
   }

   document.body.appendChild(form);
   form.submit();
   document.body.removeChild(form);
}

4. Simple Link-Based Downloads

For GET requests where the server sets the Content-Disposition header correctly, the simplest method is utilizing the browser's native anchor tag behavior.

<!-- Basic static link -->
<a href="/api/export-excel?id=123" download="report.xlsx">Download Export</a>

<!-- Programmatic navigation -->
window.open('/api/export-excel?id=123');

Tags: javascript axios blob browser-api http-requests

Posted on Wed, 03 Jun 2026 16:39:36 +0000 by hours12