1

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.


Problem Details:

  1. 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)
    
  2. 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: *  
    
  3. 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
    
  4. Tests Performed:

    • Tested the API in Insomnia and Postman, and the file is returned correctly.
    • Changed responseType to text, json, and other values, but the error persists.
    • Verified the response headers, and they seem correct.
  5. 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;
    

Question:

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?


What I've Tried:

  • Changing responseType in Angular (blob, text, json, etc.).
  • Manually decoding the Base64 in Angular.
  • Verifying the response headers in Insomnia/Postman.

Additional Information:

  • Framework: Angular 16.
  • Backend: AWS Lambda + API Gateway.
  • The generated Excel file is approximately 87 KB.

Thanks:

Thank you in advance for any help or suggestions! 😊

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.