2
votes

Téléchargez le fichier Excel avec le nom de fichier tel quel dans Angular

Comment télécharger un fichier Excel avec le nom de fichier renvoyé par le service dans mon application Angular ? J'utilise la bibliothèque file-saver . Voici mon code:

return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .header(HttpHeaders.CONTENT_DISPOSITION,
                "attachment; filename=\"" + excelCreateResource.getFilename() + "\"")
                .body(excelCreateResource);

Voici la réponse du service Angular:

return this.http.get(`${this.reportsUrl}`, { responseType: 'blob'});

Réponse de mon service backend (Spring MVC). excelCreatedResource est de type org.springframework.core.io.Resource:

let blob = new Blob([response],  {type: 'application/vnd.openxmlformat-officedocument.spreadsheetml.sheet;'});
saveAs(blob, 'hello.xlsx');

Je ne veux pas fournir hello.xlsx . Au lieu de cela, je voudrais simplement télécharger le fichier sans changer le nom de fichier renvoyé par le service. Si j'accède à l'URL directement depuis le navigateur, je peux télécharger le fichier Excel.


3 commentaires

Quelle est la structure de la réponse de votre service?


voulez-vous s'il vous plaît ajouter un extrait de réponse pour mieux comprendre votre question


Je suppose que vous pouvez découper le nom de this.reportsUrl . L'autre option serait de demander que le nom du fichier soit envoyé dans la réponse que vous obtenez de cette API.


4 Réponses :


1
votes

Si excelCreateResource.getFilename (); renvoie un nom de fichier alors, vous pouvez stocker le nom de fichier dans une variable locale et passer cette variable dans la méthode saveAs () comme: < pre> XXX

Cela fonctionnera peut-être pour vous.


1 commentaires

excelCreateResource est un objet Java, pas JS.



2
votes

Selon votre question, je pense que vous devez observer la réponse complète et obtenir les détails de l'en-tête. Dans Angular, vous pouvez le faire en utilisant

let observable$ = this.http.get(`${this.reportsUrl}`, { observe: 'response'});
observable$.subscribe(response => {
  let blobObj = response.body; // this should be your blob object (body of response)
  let headers = response.Headers //This is a disctionary/HashMap were you'll find the content-desposition header

//.....

})  


5 commentaires

J'obtiens cette erreur: Le type «Object» ne peut pas être affecté au type «BlobPart». Le type «Objet» est attribuable à très peu d'autres types. Vouliez-vous plutôt utiliser le type «tout»? Le type "Objet" ne peut pas être affecté au type "chaîne".


Pour cela: let filename = response.headers.get ('filename'); laissez body = response.body; var blob = new Blob ([body], {type: 'application / vnd.openxmlformat-officedocument.spreadsheetml.‌ sheet;'}); saveAs (blob, nom de fichier);


Comment savoir qu'il consommerait du blob, car il dit: error: SyntaxError: "JSON.parse: caractère inattendu à la ligne 1 colonne 1 des données JSON"


Plus d'erreur. Mais le problème est que je ne peux pas obtenir le nom du fichier. Il renvoie null .


Je vous remercie. J'ai suivi exactement vos codes et j'ai ajouté la suggestion @Zarna Borda. Vos deux réponses complètent la solution.



1
votes

Vous pouvez enregistrer un constructeur de fichier sans spécifier de nom de fichier. Le fichier lui-même contient déjà un nom.

let blob = new Blob ([response], {type: 'application / vnd.openxmlformatofficedocument.spreadsheetml.sheet;'}); saveAs (blob);

ou vous devez récupérer les en-têtes de votre réponse, enregistrer le nom de fichier dans la variable et passer la variable à la fonction saveAs ().


2 commentaires

Par défaut, il téléchargera le fichier en tant que download.xlsx. Ajoutez 'Access-Control-Expose-Headers': 'Content-Disposition' dans votre en-tête de réponse backend. Obtenez le nom du fichier à partir de l'en-tête de la réponse. et passez ce nom de fichier à saveAs ()


Je vous remercie. Enfin, mon problème a été résolu. Je ne sais tout simplement pas quelle réponse j'accepterais. La réponse @Ankesh est également d'une grande aide. Je l'ai suivi exactement et j'ai ajouté votre suggestion. Vos deux réponses complètent la solution.



1
votes

Utilisation de la bibliothèque FileSaver Js

let wbout = <write output> // write table or json to excell
function s2ab(s) {
  var buf = new ArrayBuffer(s.length);
  var view = new Uint8Array(buf);
  for (var i = 0; i < s.length; i++) {
    view[i] = s.charCodeAt(i) & 0xFF;
  }
  return buf;
}
// Save it as test.xlsx
saveAs(new Blob([s2ab(wbout)], {type:"application/octet-stream"}), 'hello.xlsx');


4 commentaires

Comme je l'ai dit, je ne veux pas fournir de nom de fichier dans le client, comme hello.xlsx .


vous dites ce que vous ne voulez pas, mais pas ce que vous voulez.


Vraiment? Tu n'as pas lu cette ligne? Je ne veux pas fournir hello.xlsx. Au lieu de cela, je voudrais simplement télécharger le fichier sans changer le nom de fichier renvoyé par le service. Si j'accède à l'URL directement depuis le navigateur, je peux télécharger le fichier Excel.


D'ailleurs, si vraiment je n'ai pas dit ce que je voulais, mais clairement j'ai dit ce que je ne voulais pas. Par conséquent, la moindre chose que vous puissiez faire est de ne pas suggérer ce que je ne veux pas. Vous auriez dû demander, si vous n'avez pas compris mon message.