Mam aplikację WebApi / MVC, dla której tworzę klienta angular2 (w celu zastąpienia MVC). Mam pewne problemy ze zrozumieniem, jak Angular zapisuje plik.
Żądanie jest w porządku (działa dobrze z MVC i możemy zarejestrować otrzymane dane), ale nie mogę dowiedzieć się, jak zapisać pobrane dane (głównie kieruję się tą samą logiką, co w tym poście ). Jestem pewien, że jest to głupio proste, ale jak dotąd po prostu tego nie rozumiem.
Kod funkcji komponentu znajduje się poniżej. Próbowałem różnych alternatyw, tak kropelka powinna być droga, iść tak daleko, jak to rozumieć, ale nie ma funkcji createObjectURL
w URL
. Nie mogę nawet znaleźć definicji URL
w oknie, ale najwyraźniej istnieje. Jeśli używam FileSaver.js
modułu, pojawia się ten sam błąd. Myślę więc, że jest to coś, co ostatnio się zmieniło lub nie zostało jeszcze wdrożone. Jak mogę wyzwolić zapis pliku w 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);
}
Ze względu na kompletność usługa, która pobiera dane, znajduje się poniżej, ale jedyne, co robi, to wysłanie żądania i przekazanie danych bez mapowania, jeśli się powiedzie:
downloadfile(runname: string, type: string){
return this.authHttp.get( this.files_api + this.title +"/"+ runname + "/?file="+ type)
.catch(this.logAndPassOn);
}
Odpowiedzi:
Problem polega na tym, że obserwowalne działa w innym kontekście, więc kiedy próbujesz utworzyć zmienną URL, masz pusty obiekt, a nie żądany obiekt blob.
Jeden z wielu istniejących sposobów rozwiązania tego problemu jest następujący:
Gdy żądanie będzie gotowe, wywoła funkcję „downloadFile” zdefiniowaną w następujący sposób:
obiekt blob został stworzony idealnie, więc adres URL var, jeśli nie otwiera nowego okna, sprawdź, czy już zaimportowałeś 'rxjs / Rx';
Mam nadzieję, że to ci pomoże.
źródło
this._reportService.getReport()
i co wraca?getReport()
zwracathis.http.get(PriceConf.download.url)
Spróbuj tego !
1 - Zainstaluj zależności dla wyskakującego okienka zapisz / otwórz plik
2- Utwórz usługę z tą funkcją, aby otrzymać dane
3- W komponencie przeanalizuj obiekt blob za pomocą „file-saver”
To działa dla mnie!
źródło
Jeśli nie musisz dodawać nagłówków w żądaniu, aby pobrać plik w Angular2, możesz wykonać proste :
w swoim komponencie.
źródło
authHttp
!To jest dla osób, które chcą to zrobić przy użyciu HttpClient i funkcji oszczędzania plików:
Klasa usługi API:
Składnik:
źródło
Co powiesz na to?
Mógłbym z tym zrobić.
nie ma potrzeby dodatkowego pakietu.
źródło
Jak wspomniał Alejandro Corredor , jest to prosty błąd zakresu.
subscribe
Prowadzony jest asynchronicznie iopen
musi być umieszczony w tym kontekście, tak że dane zakończeniu ładowania kiedy wyzwolić pobieranie.To powiedziawszy, można to zrobić na dwa sposoby. Zgodnie z dokumentacją usługa zajmuje się pobieraniem i mapowaniem danych:
Następnie w komponencie po prostu subskrybujemy i zajmujemy się zmapowanymi danymi. Są dwie możliwości. Pierwszy , jak sugerował w oryginalnym poście, ale wymaga niewielkiej korekty, jak zauważył Alejandro:
Drugim sposobem byłoby użycie FileReader. Logika jest taka sama, ale możemy jawnie poczekać, aż FileReader załaduje dane, unikając zagnieżdżania i rozwiązując problem asynchroniczny.
Uwaga: próbuję pobrać plik programu Excel i mimo że pobieranie zostało uruchomione (więc to odpowiada na pytanie), plik jest uszkodzony. Zobacz odpowiedź na ten post, aby uniknąć uszkodzenia pliku.
źródło
res
do obiektu blob i faktycznie chceszres._body
. Jednak_body
jest to zmienna prywatna i niedostępna. Na dzień dzisiejszy.blob()
i.arrayBuffer()
obiekt odpowiedzi http nie został zaimplementowany w Angular 2.text()
ijson()
są to jedyne dwie opcje, ale obie mogą zniekształcić twoje ciało. Znalazłeś rozwiązanie?<a href=""></a>
pobrać plik.Pobierz rozwiązanie * .zip dla angular 2.4.x: musisz zaimportować ResponseContentType z '@ angular / http' i zmienić responseType na ResponseContentType.ArrayBuffer (domyślnie ResponseContentType.Json)
źródło
W przypadku nowszych wersji kątowych:
źródło
Pobieranie pliku przez Ajax jest zawsze bolesnym procesem i moim zdaniem najlepiej jest pozwolić serwerowi i przeglądarce na negocjację typu treści.
Myślę, że najlepiej mieć
zrobić to. Nie wymaga to nawet otwierania nowych okien i podobnych rzeczy.
Kontroler MVC taki jak w Twoim przykładzie może wyglądać jak ten poniżej:
źródło
Używam Angular 4 z obiektem 4.3 httpClient. Zmodyfikowałem odpowiedź, którą znalazłem na blogu technicznym Jsa, która tworzy obiekt linku, używa go do pobierania, a następnie niszczy.
Klient:
Wartość this.downloadUrl została wcześniej ustawiona tak, aby wskazywała na interfejs API. Używam tego do pobierania załączników, więc znam identyfikator, typ zawartości i nazwę pliku: używam interfejsu API MVC, aby zwrócić plik:
Klasa załącznika wygląda następująco:
Repozytorium filerep zwraca plik z bazy danych.
Mam nadzieję, że to komuś pomoże :)
źródło
Dla osób używających Redux Pattern
Dodałem do wygaszacza plików, jak @Hector Cuevas wymienił w swojej odpowiedzi. Używając Angular2 v. 2.3.1, nie musiałem dodawać @ types / file-saver.
Poniższy przykład to pobranie dziennika w formacie PDF.
Działania dziennika
Efekty dziennika
Usługa dziennika
Usługa HTTP
Reduktor dziennika Chociaż ustawia to tylko poprawne stany używane w naszej aplikacji, nadal chciałem go dodać, aby wyświetlić pełny wzór.
Mam nadzieję, że to jest pomocne.
źródło
Udostępniam rozwiązanie, które mi pomogło (każda poprawa jest bardzo mile widziana)
W Twojej usłudze „pservice”:
Część składowa:
W części składowej wywołujesz usługę bez subskrybowania odpowiedzi. Aby uzyskać pełną listę typów MIME OpenOffice, zapisz się na: http://www.openoffice.org/framework/documentation/mimetypes/mimetypes.html
źródło
Będzie lepiej, jeśli spróbujesz wywołać w sobie nową metodę
subscribe
downloadFile(data)
Funkcja wewnętrzna, którą musimy wykonaćblock, link, href and file name
źródło
Aby pobrać i wyświetlić pliki PDF , bardzo podobny fragment kodu wygląda jak poniżej:
źródło
Oto coś, co zrobiłem w moim przypadku -
Odniesienie do rozwiązania znajduje się tutaj
źródło
Zaktualizuj do odpowiedzi Hectora przy użyciu funkcji oszczędzania plików i HttpClient dla kroku 2:
źródło
Otrzymałem rozwiązanie do pobierania z Angular 2 bez uszkodzenia, używając sprężynowego MVC i kątowego 2
Pierwszy - mój typ zwrotu to: - ResponseEntity z końca java. Tutaj wysyłam tablicę bajtów [] ma typ zwrotu ze sterownika.
2nd - aby dołączyć wygaszacz plików do swojego obszaru roboczego - na stronie indeksu jako:
3rd- w komponencie ts napisz ten kod:
To da ci format pliku xls. Jeśli chcesz inne formaty, zmień typ nośnika i nazwę pliku z odpowiednim rozszerzeniem.
źródło
Miałem dzisiaj do czynienia z tym samym przypadkiem, musiałem pobrać plik pdf jako załącznik (plik nie powinien być renderowany w przeglądarce, ale zamiast tego pobierany). Aby to osiągnąć, odkryłem, że muszę pobrać plik w Angular
Blob
i jednocześnie dodaćContent-Disposition
nagłówek w odpowiedzi.To był najprostszy, jaki mogłem uzyskać (Angular 7):
Wewnątrz usługi:
Następnie, gdy chcę pobrać plik w komponencie, mogę po prostu:
AKTUALIZACJA:
Usunięto niepotrzebne ustawienie nagłówka z usługi
źródło
Poniższy kod zadziałał dla mnie
źródło
W dotychczasowych odpowiedziach brakowało wglądu i ostrzeżeń. Możesz i powinieneś uważać na niezgodności z IE10 + (jeśli Ci zależy).
To jest kompletny przykład z częścią aplikacyjną i częścią serwisową po. Zwróć uwagę, że ustawiliśmy klauzulę observ: "response", aby złapać nagłówek nazwy pliku. Należy również pamiętać, że nagłówek Content-Disposition musi być ustawiony i ujawniony przez serwer, w przeciwnym razie bieżący HttpClient kątowy nie przekaże go dalej. Dodałem poniżej podstawowy fragment kodu dotnet .
Rdzeń Dotnet, z Content-Disposition i MediaType
źródło
źródło
Wystarczy umieścić
url
takhref
jak poniżej.źródło
<a href="my_url" download="myfilename">Download file</a>
my_url powinien mieć to samo źródło, w przeciwnym razie przekieruje do tej lokalizacji
źródło
Możesz również pobrać plik bezpośrednio z szablonu, w którym używasz atrybutu pobierania i
[attr.href]
możesz podać wartość właściwości z komponentu. To proste rozwiązanie powinno działać na większości przeglądarek.Źródła: https://www.w3schools.com/tags/att_a_download.asp
źródło
Jeśli wysyłasz parametry tylko na adres URL, możesz to zrobić w ten sposób:
w serwisie, który otrzymuje parametry
źródło
Ta odpowiedź sugeruje, że nie można pobierać plików bezpośrednio za pomocą AJAX, głównie ze względów bezpieczeństwa. Więc opiszę, co robię w tej sytuacji,
01. Dodaj
href
atrybut w tagu kotwicy wewnątrzcomponent.html
pliku,np .: -
02. Wykonaj wszystkie poniższe kroki,
component.ts
aby ominąć poziom zabezpieczeń i wyświetlić okno dialogowe Zapisz jako wyskakujące okienko,np .: -
źródło
Cóż, napisałem fragment kodu zainspirowany wieloma z powyższych odpowiedzi, który powinien z łatwością działać w większości scenariuszy, w których serwer wysyła plik z nagłówkiem dyspozycji treści, bez żadnych instalacji innych firm, z wyjątkiem rxjs i angular.
Po pierwsze, jak wywołać kod z pliku komponentu
Jak widać, jest to w zasadzie przeciętne wywołanie backendu z angular, z dwiema zmianami
Po pobraniu pliku z serwera w zasadzie deleguję całe zadanie zapisania pliku do funkcji pomocniczej, którą trzymam w osobnym pliku i importuję do dowolnego komponentu, którego potrzebuję
Nie ma już tajemniczych nazw plików GUID! Możemy użyć dowolnej nazwy dostarczonej przez serwer, bez konieczności jawnego określania jej w kliencie, lub nadpisać nazwę pliku dostarczoną przez serwer (jak w tym przykładzie). Można też łatwo, jeśli zajdzie taka potrzeba, zmienić algorytm wyodrębniania nazwy pliku z dyspozycji zawartości, aby odpowiadał jej potrzebom, a wszystko inne pozostanie nienaruszone - w przypadku błędu podczas takiej ekstrakcji po prostu przejdzie 'null' jako nazwa pliku.
Jak już wskazała inna odpowiedź, IE wymaga specjalnego traktowania, jak zawsze. Ale ponieważ chromium Edge pojawi się za kilka miesięcy, nie martwiłbym się tym podczas tworzenia nowych aplikacji (miejmy nadzieję). Jest też kwestia unieważnienia adresu URL, ale nie jestem tego pewien, więc jeśli ktoś mógłby pomóc w komentarzach, byłoby wspaniale.
źródło
Jeśli karta otwiera się i zamyka bez pobierania czegokolwiek, próbowałem podążać za fałszywym łączem kotwicy i zadziałało.
źródło