I am facing difficulties consuming an API in Angular that returns an Excel file encoded in Base64. The API is configured in AWS API Gateway and uses a Lambda function to generate the file. Although the API response seems correct (tested in Insomnia/Postman), Angular cannot interpret the content properly.
API Response:
When I make the request in Insomnia, I receive a response with status 200 OK, and the body contains the Base64-encoded Excel file. Here's an example of the response:
UEsDBBQAAAAIA... (long Base64 string)
Response Headers:
The headers returned by the API include:
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Disposition: attachment; filename="suitability-produtos-20251124-150728.xlsx"
Access-Control-Allow-Origin: *
Angular Configuration:
In Angular, I am trying to consume the API with the following code:
this.http.post('https://my-api.com/suitability-produtos-templates', {}, { responseType: 'blob' })
.subscribe((response: Blob) => {
const blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'template.xlsx';
link.click();
});
However, I get the following error:
Response is not a Blob
Tests Performed:
responseType to text, json, and other values, but the error persists.Lambda Configuration:
The Lambda function is configured to return the file in Base64 with the following headers:
const response = {
statusCode: 200,
isBase64Encoded: true,
body: base64EncodedFile,
headers: {
"Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"Content-Disposition": "attachment; filename=\"template.xlsx\"",
"Access-Control-Allow-Origin": "*"
}
};
return response;
How can I configure my Angular code to correctly consume this API that returns an Excel file in Base64? Is there anything I can adjust in the API Gateway or Lambda function configuration to solve this issue?
responseType in Angular (blob, text, json, etc.).Thank you in advance for any help or suggestions! 😊
According to your response example, the response is base64-encoded text, not a blob.
body: base64EncodedFile
this.http.post('https://my-api.com/suitability-produtos-templates', {}, { responseType: 'blob' })
That means you are passing text here rather than bytes.
const blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
Try instead to pick base64 (or commit to serving a raw file).
const response = {
statusCode: 200,
isBase64Encoded: true,
body: base64EncodedFile,
headers: {
"Content-Type": "text/plain",
"Access-Control-Allow-Origin": "*"
}
};
Then using this function to convert the base64 string to a downloadable file (by way of converting to bytes and a Blob).
function downloadBase64File(base64: string, filename: string, mimeType: string) {
const byteChars = atob(base64);
const byteNumbers = new Uint8Array(byteChars.length);
for (let i = 0; i < byteChars.length; i++) {
byteNumbers[i] = byteChars.charCodeAt(i);
}
const blob = new Blob([byteNumbers], { type: mimeType });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
The better solution would be to serve the raw file and not add the processing and 30% size overhead of base64, but you are already serving base64 so I used that.