Posterior a investigar con expertos en esta materia, programadores de varias ramas y maestros hemos dado con la solución al problema y la compartimos en esta publicación.
Solución:
-
Necesita configurar el encabezado de respuesta
responseType: 'blob'
en la solicitud. -
Debe pasar el tipo MIME correcto mientras crea el archivo blob. (fe aplicación/flujo de octetos o application/vnd.openxmlformats-officedocument.spreadsheetml.sheet).
componente.ts
downloadFile(data: Response)
const blob = new Blob([data], type: 'application/octet-stream' );
const url= window.URL.createObjectURL(blob);
window.open(url);
Agregar encabezado responseType: 'blob'
Como esto:
this.http.post(apiEndpoint,request, responseType: 'blob' )
Durante el uso responseType: 'blob'
como dicen la mayoría de las respuestas aquí funciona, sugeriría usar responseType: 'arraybuffer'
en vez de blob
con observe: 'response'
. Su llamada se vería así:
this.httpClient.get(resource,
headers: this.httpHeaders, // Any custom client side headers like Authorization
observe: 'response',
responseType: 'arraybuffer'
);
La ventaja de esto es doble:
- Arraybuffer es un flujo genérico de bytes y el objeto Blob se puede crear utilizando un
blob
o unarraybuffer
utilizando elContent-Type
observe: 'response'
también incluirá los encabezados de respuesta que estableció en el servidor en la respuesta analizada.
Yo uso este método para poner el nombre del archivo y el Tipo MIME del arraybuffer
en el Content-Disposition
y Content-Type
encabezados de respuesta y luego use un servicio de descarga genérico en el lado del cliente.
Además, sugeriría usar un File
objeto en lugar de solo el Blob
lo que le brinda la flexibilidad de darle un nombre de archivo como este:
public downloadFile(response: any, fileName?: string) response.headers.get('content-disposition').split(';')[0];
const file = new File([blob], fileName, type: response.headers.get('content-type') );
saveAs(file);
Esto también resolverá el problema que planteó @knbibin sobre el uso de un nombre de archivo personalizado.
Recuerda que puedes dar visibilidad a este tutorial si te fue útil.