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');