J'ai une application WebApi / MVC pour laquelle je développe un client angular2 (pour remplacer MVC). J'ai du mal à comprendre comment Angular enregistre un fichier.
La demande est correcte (fonctionne bien avec MVC, et nous pouvons enregistrer les données reçues) mais je ne peux pas comprendre comment enregistrer les données téléchargées (je suis principalement la même logique que dans cet article ). Je suis sûr que c'est stupidement simple, mais jusqu'à présent, je ne le saisis tout simplement pas.
Le code de la fonction du composant est ci-dessous. J'ai essayé différentes alternatives, la méthode blob devrait être la manière d'aller aussi loin que je l'ai compris, mais il n'y a pas de fonction createObjectURL
dans URL
. Je ne trouve même pas la définition de URL
dans window, mais apparemment, elle existe. Si j'utilise le FileSaver.js
module, j'obtiens la même erreur. Je suppose donc que c'est quelque chose qui a changé récemment ou qui n'est pas encore mis en œuvre. Comment puis-je déclencher l'enregistrement du fichier dans 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);
}
Par souci d'exhaustivité, le service qui récupère les données est ci-dessous, mais la seule chose qu'il fait est d'émettre la requête et de transmettre les données sans mappage si elle réussit:
downloadfile(runname: string, type: string){
return this.authHttp.get( this.files_api + this.title +"/"+ runname + "/?file="+ type)
.catch(this.logAndPassOn);
}
Réponses:
Le problème est que l'observable s'exécute dans un autre contexte, donc lorsque vous essayez de créer l'URL var, vous avez un objet vide et non l'objet blob souhaité.
L'une des nombreuses façons de résoudre ce problème est la suivante:
Lorsque la demande est prête, elle appellera la fonction "downloadFile" qui est définie comme suit:
le blob a été créé parfaitement et donc l'URL var, si n'ouvre pas la nouvelle fenêtre, veuillez vérifier que vous avez déjà importé 'rxjs / Rx';
J'espère que cela pourra vous aider.
la source
this._reportService.getReport()
ce que c'est et que renvoie-t-ilgetReport()
retourne unthis.http.get(PriceConf.download.url)
Essayez ceci !
1 - Installer les dépendances pour afficher la fenêtre de sauvegarde / ouvrir le fichier
2- Créez un service avec cette fonction pour recevoir les données
3- Dans le composant analyser le blob avec 'file-saver'
Cela fonctionne pour moi!
la source
Si vous n'avez pas besoin d'ajouter des en-têtes dans la demande, pour télécharger un fichier dans Angular2, vous pouvez faire un simple :
dans votre composant.
la source
authHttp
!Ceci est pour les gens qui cherchent comment le faire en utilisant HttpClient et File-Saver:
Classe de service API:
Composant:
la source
Que dis-tu de ça?
Je pourrais faire avec.
pas besoin de paquet supplémentaire.
la source
Comme mentionné par Alejandro Corredor il s'agit d'une simple erreur de portée. Le
subscribe
est exécuté de manière asynchrone etopen
doit être placé dans ce contexte, de sorte que les données aient fini de se charger lorsque nous déclenchons le téléchargement.Cela dit, il existe deux façons de procéder. Comme la documentation le recommande, le service se charge d'obtenir et de mapper les données:
Ensuite, sur le composant, nous nous abonnons simplement et traitons les données mappées. Il y a deux possibilités. La première , comme suggéré dans l'article original, mais nécessite une petite correction comme l'a noté Alejandro:
La deuxième façon serait d'utiliser FileReader. La logique est la même mais nous pouvons explicitement attendre que FileReader charge les données, évitant l'imbrication et résolvant le problème asynchrone.
Remarque: j'essaie de télécharger un fichier Excel, et même si le téléchargement est déclenché (cela répond donc à la question), le fichier est corrompu. Voir la réponse à ce message pour éviter le fichier corrompu.
la source
res
dans le blob et que vous le souhaitez réellementres._body
. Cependant,_body
c'est une variable privée et non accessible. À ce jour.blob()
et.arrayBuffer()
sur un objet de réponse http, ils n'ont pas été implémentés dans Angular 2.text()
etjson()
sont les deux seules options, mais les deux vont brouiller votre corps. Avez-vous trouvé une solution?<a href=""></a>
à télécharger un fichier.Téléchargez la solution * .zip pour angular 2.4.x: vous devez importer ResponseContentType depuis '@ angular / http' et changer responseType en ResponseContentType.ArrayBuffer (par défaut, ResponseContentType.Json)
la source
Pour les nouvelles versions angulaires:
la source
Le téléchargement de fichiers via ajax est toujours un processus pénible et à mon avis, il est préférable de laisser le serveur et le navigateur faire ce travail de négociation de type de contenu.
Je pense que c'est mieux d'avoir
pour le faire. Cela ne nécessite même pas l'ouverture de nouvelles fenêtres et des trucs comme ça.
Le contrôleur MVC comme dans votre exemple peut être comme celui ci-dessous:
la source
J'utilise Angular 4 avec l'objet httpClient 4.3. J'ai modifié une réponse trouvée dans le blog technique de Js qui crée un objet lien, l'utilise pour faire le téléchargement, puis le détruit.
Client:
La valeur de this.downloadUrl a été définie précédemment pour pointer vers l'API. J'utilise ceci pour télécharger des pièces jointes, donc je connais l'id, le contentType et le nom de fichier: j'utilise une api MVC pour renvoyer le fichier:
La classe de pièce jointe ressemble à ceci:
Le référentiel filerep renvoie le fichier de la base de données.
J'espère que cela aide quelqu'un :)
la source
Pour ceux qui utilisent Redux Pattern
J'ai ajouté dans l'économiseur de fichiers comme @Hector Cuevas nommé dans sa réponse. En utilisant Angular2 v. 2.3.1, je n'ai pas eu besoin d'ajouter le @ types / file-saver.
L'exemple suivant consiste à télécharger un journal au format PDF.
Les actions du journal
Les effets du journal
Le service journal
Le service HTTP
Le réducteur de journal Bien que cela ne définisse que les états corrects utilisés dans notre application, je voulais toujours l'ajouter pour afficher le modèle complet.
J'espère que ceci est utile.
la source
Je partage la solution qui m'a aidé (toute amélioration est grandement appréciée)
Sur votre service 'pservice':
Partie composant :
Sur le composant, vous appelez le service sans souscrire à une réponse. L'abonnement pour une liste complète des types mime openOffice voir: http://www.openoffice.org/framework/documentation/mimetypes/mimetypes.html
la source
Ce sera mieux si vous essayez d'appeler la nouvelle méthode en vous
subscribe
downloadFile(data)
Fonction intérieure que nous devons faireblock, link, href and file name
la source
Pour télécharger et afficher des fichiers PDF , un code très similaire extrait est comme ci-dessous:
la source
Voici quelque chose que j'ai fait dans mon cas -
La solution est référencée à partir d' ici
la source
Mettez à jour la réponse d'Hector à l'aide de l'économiseur de fichiers et de HttpClient pour l'étape 2:
la source
J'ai une solution pour télécharger à partir d'angular 2 sans être corrompu, en utilisant spring mvc et angular 2
1er- mon type de retour est: - ResponseEntity de la fin de Java. Ici, j'envoie le tableau d'octets [] a un type de retour du contrôleur.
2ème - pour inclure l'économiseur de fichiers dans votre espace de travail - dans la page d'index comme:
3ème au composant ts écrivez ce code:
Cela vous donnera le format de fichier xls. Si vous voulez d'autres formats, changez le type de média et le nom du fichier avec l'extension droite.
la source
J'étais confronté à ce même cas aujourd'hui, j'ai dû télécharger un fichier pdf en pièce jointe (le fichier ne devait pas être rendu dans le navigateur, mais téléchargé à la place). Pour y parvenir, j'ai découvert que je devais obtenir le fichier dans un format angulaire
Blob
et, en même temps, ajouter unContent-Disposition
tête dans la réponse.C'était le plus simple que je puisse obtenir (Angular 7):
À l'intérieur du service:
Ensuite, lorsque j'ai besoin de télécharger le fichier dans un composant, je peux simplement:
METTRE À JOUR:
Suppression du paramètre d'en-tête inutile du service
la source
Le code suivant a fonctionné pour moi
la source
Jusqu'à présent, j'ai trouvé que les réponses manquaient de perspicacité et d'avertissement. Vous pouvez et devez surveiller les incompatibilités avec IE10 + (si vous vous en souciez).
Ceci est l'exemple complet avec la partie application et la partie service après. Notez que nous définissons observer: "response" pour attraper l'en-tête du nom de fichier. Notez également que l'en-tête Content-Disposition doit être défini et exposé par le serveur, sinon le Angular HttpClient actuel ne le transmettra pas. J'ai ajouté un morceau de code de base dotnet pour cela ci-dessous.
Dotnet core, avec Content-Disposition et MediaType
la source
la source
Il suffit de mettre le
url
commehref
ci - dessous.la source
<a href="my_url" download="myfilename">Download file</a>
my_url doit avoir la même origine, sinon il sera redirigé vers cet emplacement
la source
Vous pouvez également télécharger un fichier directement à partir de votre modèle où vous utilisez l'attribut de téléchargement et
[attr.href]
vous pouvez fournir une valeur de propriété à partir du composant. Cette solution simple devrait fonctionner sur la plupart des navigateurs.Référence: https://www.w3schools.com/tags/att_a_download.asp
la source
Si vous envoyez uniquement les paramètres à une URL, vous pouvez le faire de cette façon:
dans le service qui reçoit les paramètres
la source
Cette réponse suggère que vous ne pouvez pas télécharger des fichiers directement avec AJAX, principalement pour des raisons de sécurité. Je vais donc décrire ce que je fais dans cette situation,
01. Ajoutez un
href
attribut dans votre balise d'ancrage à l'intérieur ducomponent.html
fichier,par exemple: -
02. Faites toutes les étapes suivantes dans votre
component.ts
pour contourner le niveau de sécurité et afficher la boîte de dialogue Enregistrer en tant que popup,par exemple: -
la source
Eh bien, j'ai écrit un morceau de code inspiré de la plupart des réponses ci-dessus qui devrait facilement fonctionner dans la plupart des scénarios où le serveur envoie un fichier avec un en-tête de disposition de contenu, sans aucune installation tierce, sauf rxjs et angular.
Tout d'abord, comment appeler le code à partir de votre fichier de composant
Comme vous pouvez le voir, il s'agit essentiellement de l'appel backend moyen d'angular, avec deux changements
Une fois le fichier récupéré sur le serveur, je délègue en principe toute la tâche de sauvegarde du fichier à la fonction d'assistance, que je garde dans un fichier séparé, et que je l'importe dans le composant dont j'ai besoin
Là, plus de noms de fichiers GUID cryptiques! Nous pouvons utiliser n'importe quel nom fourni par le serveur, sans avoir à le spécifier explicitement dans le client, ou écraser le nom de fichier fourni par le serveur (comme dans cet exemple). De plus, on peut facilement, si nécessaire, changer l'algorithme d'extraction du nom de fichier de la disposition de contenu pour répondre à leurs besoins, et tout le reste restera inchangé - en cas d'erreur lors d'une telle extraction, il passera simplement `` null '' comme nom de fichier.
Comme une autre réponse l'a déjà souligné, IE a besoin d'un traitement spécial, comme toujours. Mais avec Chrome Edge à venir dans quelques mois, je ne m'inquiéterais pas à ce sujet lors de la création de nouvelles applications (espérons-le). Il y a aussi la question de la révocation de l'URL, mais je ne suis pas si sûr de cela, donc si quelqu'un pouvait aider avec cela dans les commentaires, ce serait génial.
la source
Si un onglet s'ouvre et se ferme sans rien télécharger, j'ai essayé de suivre avec un lien d'ancrage simulé et cela a fonctionné.
la source