Tengo una aplicación WebApi/MVC para la que estoy desarrollando un cliente angular2 (para reemplazar MVC). Tengo algunos problemas para entender cómo Angular guarda un archivo.
La solicitud está bien (funciona bien con MVC, y podemos registrar los datos recibidos) pero no puedo averiguar cómo guardar los datos descargados (principalmente sigo la misma lógica que en esta publicación ). Estoy seguro de que es estúpidamente simple, pero hasta ahora simplemente no lo entiendo.
El código de la función del componente se encuentra a continuación. Probé diferentes alternativas, la forma de blob debería ser el camino a seguir hasta donde entendí, pero no hay función createObjectURL en URL . Ni siquiera puedo encontrar la definición de URL en la ventana, pero aparentemente existe. Si uso el módulo FileSaver.js obtengo el mismo error. Así que supongo que esto es algo que cambió recientemente o aún no se implementó. ¿Cómo puedo activar el guardado del archivo en A2?
downloadfile(type: string){ let thefile = {}; this.pservice.downloadfile(this.rundata.name, type) .subscribe(data => thefile = new Blob([data], { type: "application/octet-stream" }), //console.log(data), error => console.log("Error downloading the file."), () => console.log('Completed file download.')); let url = window.URL.createObjectURL(thefile); window.open(url); }En aras de la exhaustividad, el servicio que obtiene los datos se encuentra a continuación, pero lo único que hace es emitir la solicitud y pasar los datos sin mapear si tiene éxito:
downloadfile(runname: string, type: string){ return this.authHttp.get( this.files_api + this.title +"/"+ runname + "/?file="+ type) .catch(this.logAndPassOn); }El problema es que el observable se ejecuta en otro contexto, por lo que cuando intenta crear la URL var, tiene un objeto vacío y no el blob que desea.
Una de las muchas formas que existen para solucionar esto es la siguiente:
this._reportService.getReport().subscribe(data => this.downloadFile(data)),//console.log(data), error => console.log('Error downloading the file.'), () => console.info('OK');Cuando la solicitud esté lista, llamará a la función "descargar archivo" que se define de la siguiente manera:
downloadFile(data: Response) { const blob = new Blob([data], { type: 'text/csv' }); const url= window.URL.createObjectURL(blob); window.open(url); }el blob se ha creado perfectamente y, por lo tanto, la URL var, si no abre la nueva ventana, compruebe que ya ha importado 'rxjs/Rx';
import 'rxjs/Rx' ;Espero que esto pueda ayudarte.
¡Prueba esto !
1 - Instale las dependencias para mostrar la ventana emergente guardar/abrir archivo
npm install file-saver --save npm install -D @types/file-saver2- Crea un servicio con esta función para recibir los datos
downloadFile(id): Observable<Blob> { let options = new RequestOptions({responseType: ResponseContentType.Blob }); return this.http.get(this._baseUrl + '/' + id, options) .map(res => res.blob()) .catch(this.handleError) }3- En el componente analice el blob con 'file-saver'
import {saveAs as importedSaveAs} from "file-saver"; this.myService.downloadFile(this.id).subscribe(blob => { importedSaveAs(blob, this.fileName); } )¡Esto funciona para mí!
Si no necesita agregar encabezados en la solicitud, para descargar un archivo en Angular2 puede hacer un simple ( PRINCIPIO KISS ):
window.location.href='http://example.com/myuri/report?param=x';en su componente.