from descargar con archivos archivo json excel angularjs http-post

json - descargar - download file from angular 5



AngularJS $ http-post-convierte archivos binarios a Excel y descarga (9)

Me acabo de dar cuenta de que no puede usarlo debido a IE8 / 9, pero voy a enviar enviar de todos modos ... tal vez alguien lo encuentre útil

Esto realmente se puede hacer a través del navegador, usando blob . Observe el tipo de responseType y el código en la promesa de success .

$http({ url: ''your/webservice'', method: "POST", data: json, //this is your json data string headers: { ''Content-type'': ''application/json'' }, responseType: ''arraybuffer'' }).success(function (data, status, headers, config) { var blob = new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}); var objectUrl = URL.createObjectURL(blob); window.open(objectUrl); }).error(function (data, status, headers, config) { //upload failed });

Hay algunos problemas con esto, aunque como:

  1. No es compatible con caniuse.com/#feat=bloburls :
  2. Abre una ventana emergente para abrir el objectUrl que las personas pueden haber bloqueado
  3. Genera nombres de archivos raros

¡Funcionó!

El código del lado del servidor en PHP lo probé con un aspecto como este. Estoy seguro de que puedes establecer encabezados similares en Java:

$file = "file.xlsx"; header(''Content-disposition: attachment; filename=''.$file); header(''Content-Length: '' . filesize($file)); header(''Content-Transfer-Encoding: binary''); header(''Cache-Control: must-revalidate''); header(''Pragma: public''); echo json_encode(readfile($file));

Editar 20.04.2016

Los navegadores están haciendo más difícil guardar los datos de esta manera. Una buena opción es usar filesaver.js . Proporciona una implementación de navegador cruzado para saveAs , y debería reemplazar parte del código en la promesa de success anterior.

Creé una aplicación en Angular JS para descargar un libro de Excel a través de $ http post.

En el siguiente código, paso la información en forma de JSON y la envío al servicio web REST del servidor (java) a través de una publicación angular $ http. El servicio web utiliza la información de JSON y produce un libro de Excel. En la respuesta dentro del cuerpo de éxito de $ http post, obtengo datos binarios dentro de esa variable de datos , pero no sé cómo convertirlos y descargarlos como un archivo de Excel.

¿Puede alguien decirme alguna solución para esto para convertir el archivo binario a Excel y descargarlo?

Mi código es el siguiente:

$http({ url: ''myweb.com/myrestService'', method: "POST", data: json, //this is your json data string headers: { ''Content-type'': ''application/json'' } }).success(function (data, status, headers, config) { // Here i''m getting excel sheet binary datas in ''data'' }).error(function (data, status, headers, config) { });


Así es como lo haces:

  1. Olvídese de IE8 / IE9, no vale la pena el esfuerzo y no le devuelve el dinero.
  2. Necesita usar el encabezado HTTP correcto, use Aceptar en ''application / vnd.openxmlformats-officedocument.spreadsheetml.sheet'' y también debe poner responseType en ''arraybuffer'' (ArrayBuffer pero configurado con minúsculas).
  3. HTML5 saveAs se utiliza para guardar los datos reales en el formato deseado. Tenga en cuenta que aún funcionará sin agregar tipo en este caso.

$http({ url: ''your/webservice'', method: ''POST'', responseType: ''arraybuffer'', data: json, //this is your json data string headers: { ''Content-type'': ''application/json'', ''Accept'': ''application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'' } }).success(function(data){ var blob = new Blob([data], { type: ''application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'' }); saveAs(blob, ''File_Name_With_Some_Unique_Id_Time'' + ''.xlsx''); }).error(function(){ //Some error log });

¡Propina! No mezcle "y", adhiérase a usar siempre ", en un entorno profesional tendrá que pasar la validación js, por ejemplo jshint, lo mismo vale para usar === y no ==, y así sucesivamente, pero ese es otro tema :)

Yo pondría el save excel en otro servicio, por lo que tiene una estructura limpia y la publicación está en su propio servicio. Puedo hacer un violín JS para ti, si no consigues que mi ejemplo funcione. Entonces también necesitaría algunos datos json de usted que use para un ejemplo completo.

Feliz codificación ... Eduardo


Creé un servicio que hará esto por ti.

Pase un objeto $http estándar y agregue algunos parámetros adicionales.

1) Un parámetro "tipo". Especificando el tipo de archivo que está recuperando. El valor predeterminado es ''application/vnd.openxmlformats-officedocument.spreadsheetml.sheet''
2) Un parámetro "fileName". Esto es obligatorio, y debe incluir la extensión.

Ejemplo:

httpDownloader({ method : ''POST'', url : ''--- enter the url that returns a file here ---'', data : ifYouHaveDataEnterItHere, type : ''application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'', // this is the default fileName : ''YourFileName.xlsx'' }).then(res => {}).catch(e => {});

Eso es todo lo que necesitas. El archivo se descargará al dispositivo del usuario sin una ventana emergente.

Aquí está el repositorio de git: https://github.com/stephengardner/ngHttpDownloader


Descargue la respuesta del servidor como un buffer de matriz. Guárdelo como un Blob usando el tipo de contenido del servidor (que debe ser application/vnd.openxmlformats-officedocument.spreadsheetml.sheet ):

var httpPromise = this.$http.post(server, postData, { responseType: ''arraybuffer'' }); httpPromise.then(response => this.save(new Blob([response.data], { type: response.headers(''Content-Type'') }), fileName));

Guarde el blob en el dispositivo del usuario:

save(blob, fileName) { if (window.navigator.msSaveOrOpenBlob) { // For IE: navigator.msSaveBlob(blob, fileName); } else { // For other browsers: var link = document.createElement(''a''); link.href = window.URL.createObjectURL(blob); link.download = fileName; link.click(); window.URL.revokeObjectURL(link.href); } }


Estaba enfrentando el mismo problema. Déjame decirte cómo lo resolví y logré todo lo que pareces querer.

Requisitos:

  1. Debe tener un botón (o enlace) a un archivo - (o una secuencia de memoria generada)
  2. Debe hacer clic en el botón y descargar el archivo

En mi servicio, (estoy usando Asp.net Web API), tengo un controlador que devuelve un "HttpResponseMessage". Agrego un "StreamContent" al campo response.Content, establezco los encabezados en "application / octet-stream" y agrego los datos como un archivo adjunto. Incluso le doy un nombre "myAwesomeFile.xlsx"

response = Request.CreateResponse(HttpStatusCode.OK); response.Content = new StreamContent(memStream); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "myAwesomeFile.xlsx" };

Ahora aquí está el truco;)

Estoy almacenando la URL base en un archivo de texto que leí en una variable en un valor angular llamado "apiRoot". Hago esto al declararlo y luego configurarlo en la función "ejecutar" del Módulo, de esta manera:

app.value(''apiRoot'', { url: '''' }); app.run(function ($http, apiRoot) { $http.get(''/api.txt'').success(function (data) { apiRoot.url = data; }); });

De esa forma puedo configurar la URL en un archivo de texto en el servidor y no preocuparme por "eliminarlo" en una carga. (Siempre puede cambiarlo más tarde por razones de seguridad, pero esto quita la frustración del desarrollo;))

Y AHORA la magia:

Todo lo que hago es crear un enlace con una URL que golpea directamente mi punto final del servicio y el objetivo es un "_blank".

<a ng-href="{{vm.getFileHref(FileId)}}" target="_blank" class="btn btn-default">&nbsp;Excel File</a>

la salsa secreta es la función que establece el href. ¿Estás listo para esto?

vm.getFileHref = function (Id) { return apiRoot.url + "/datafiles/excel/" + Id; }

Sí, eso es todo. ;)

Incluso en una situación en la que está iterando sobre muchos registros que tienen archivos para descargar, simplemente transfiere el Id a la función y la función genera la url al punto final del servicio que entrega el archivo.

¡Espero que esto ayude!


La respuesta No 5 funcionó para mí, Sugerencia para el desarrollador que enfrentan un problema similar.

////////////////////////////////////////////////////////// //Server side ////////////////////////////////////////////////////////// imports *** public class AgentExcelBuilder extends AbstractExcelView { protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { //poi code goes here .... response.setHeader("Cache-Control","must-revalidate"); response.setHeader("Pragma", "public"); response.setHeader("Content-Transfer-Encoding","binary"); response.setHeader("Content-disposition", "attachment; filename=test.xls"); OutputStream output = response.getOutputStream(); workbook.write(output); System.out.println(workbook.getActiveSheetIndex()); System.out.println(workbook.getNumberOfSheets()); System.out.println(workbook.getNumberOfNames()); output.flush(); output.close(); }//method buildExcelDocument ENDS //service.js at angular JS code function getAgentInfoExcel(workgroup,callback){ $http({ url: CONTEXT_PATH+''/rest/getADInfoExcel'', method: "POST", data: workgroup, //this is your json data string headers: { ''Content-type'': ''application/json'' }, responseType: ''arraybuffer'' }).success(function (data, status, headers, config) { var blob = new Blob([data], {type: "application/vnd.ms-excel"}); var objectUrl = URL.createObjectURL(blob); window.open(objectUrl); }).error(function (data, status, headers, config) { console.log(''Failed to download Excel'') }); } ////////////////////////////////in .html <div class="form-group">`enter code here` <a href="javascript:void(0)" class="fa fa-file-excel-o" ng-click="exportToExcel();"> Agent Export</a> </div>


No hay forma (que yo sepa) de activar la ventana de descarga en su navegador desde Javascript. La única manera de hacerlo es redirigir el navegador a una URL que transmite el archivo al navegador.

Si puede modificar su servicio REST, puede resolverlo cambiando para que la solicitud POST no responda con el archivo binario, pero con una url para ese archivo. Eso le proporcionará la URL en JavaScript en lugar de los datos binarios, y puede redirigir el navegador a esa url, lo que debería provocar la descarga sin abandonar la página original.


También podría tomar un enfoque alternativo: no tiene que usar $ http, no necesita bibliotecas adicionales, y debería funcionar en cualquier navegador.

Simplemente coloque un formulario invisible en su página.

<form name="downloadForm" action="/MyApp/MyFiles/Download" method="post" target="_self"> <input type="hidden" name="value1" value="{{ctrl.value1}}" /> <input type="hidden" name="value2" value="{{ctrl.value2}}" /> </form>

Y coloque este código en su controlador angular.

ctrl.value1 = ''some value 1''; ctrl.value2 = ''some value 2''; $timeout(function () { $window.document.forms[''downloadForm''].submit(); });

Este código publicará sus datos en / MyApp / MyFiles / Download y recibirá un archivo en su carpeta de Descargas.
Funciona con Internet Explorer 10.

Si un formulario HTML convencional no le permite publicar su objeto complejo, entonces tiene dos opciones:

1. Stringify su objeto y ponerlo en uno de los campos del formulario como una cadena.

<input type="hidden" name="myObjJson" value="{{ctrl.myObj | json:0}}" />


2. Considere los formularios HTML JSON: https://www.w3.org/TR/html-json-forms/


Trabajó para mi -

$scope.downloadFile = function () { Resource.downloadFile().then(function (response) { var blob = new Blob([response.data], { type: "application/pdf" }); var objectUrl = URL.createObjectURL(blob); window.open(objectUrl); }, function (error) { debugger; }); };

Que llama lo siguiente de mi fábrica de recursos-

downloadFile: function () { var downloadRequst = { method: ''GET'', url: ''http://localhost/api/downloadFile?fileId=dfckn4niudsifdh.pdf'', headers: { ''Content-Type'': "application/pdf", ''Accept'': "application/pdf" }, responseType: ''arraybuffer'' } return $http(downloadRequst); }

Asegúrate de que tu API también establezca el tipo de contenido del encabezado:

response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf"); response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");