バックエンドからExcelをダウンロードする必要があります。ファイルが返されます。
要求を行うと、エラーが発生します。
TypeError:ストリームが予想される場所に「未定義」を指定しました。 Observable、Promise、Array、またはIterableを提供できます。
私のコードは:
this.http.get(`${environment.apiUrl}/...`)
.subscribe(response => this.downloadFile(response, "application/ms-Excel"));
Getとmap(...)を試みましたが、うまくいきませんでした。
詳細:角度5.2
参照:
import { HttpClient } from '@angular/common/http';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/finally';
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/catch';
応答のコンテンツタイプ:
Content-Type: application/ms-Excel
どうしましたか?
次のようなものを試してください:
タイプ:application/ms-Excel
/**
* used to get file from server
*/
this.http.get(`${environment.apiUrl}`,{
responseType: 'arraybuffer',headers:headers}
).subscribe(response => this.downLoadFile(response, "application/ms-Excel"));
/**
* Method is use to download file.
* @param data - Array Buffer data
* @param type - type of the document.
*/
downLoadFile(data: any, type: string) {
let blob = new Blob([data], { type: type});
let url = window.URL.createObjectURL(blob);
let pwa = window.open(url);
if (!pwa || pwa.closed || typeof pwa.closed == 'undefined') {
alert( 'Please disable your Pop-up blocker and try again.');
}
}
BLOBは、バックエンドからファイルタイプとともに返されます。次の関数は、任意のファイルタイプとポップアップダウンロードウィンドウを受け入れます。
downloadFile(route: string, filename: string = null): void{
const baseUrl = 'http://myserver/index.php/api';
const token = 'my JWT';
const headers = new HttpHeaders().set('authorization','Bearer '+token);
this.http.get(baseUrl + route,{headers, responseType: 'blob' as 'json'}).subscribe(
(response: any) =>{
let dataType = response.type;
let binaryData = [];
binaryData.Push(response);
let downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, {type: dataType}));
if (filename)
downloadLink.setAttribute('download', filename);
document.body.appendChild(downloadLink);
downloadLink.click();
}
)
}
この答えへの応答を探すのに多くの時間を費やした後:Node.jsで書かれたAPIの安らかなサーバーからAngularコンポーネントアプリに簡単な画像をダウンロードする方法、私はついにこのWebで美しい答えを見つけました- Angular HttpClient Blob 。基本的には次のもので構成されます。
API Node.js restful:
/* After routing the path you want ..*/
public getImage( req: Request, res: Response) {
// Check if file exist...
if (!req.params.file) {
return res.status(httpStatus.badRequest).json({
ok: false,
msg: 'File param not found.'
})
}
const absfile = path.join(STORE_ROOT_DIR,IMAGES_DIR, req.params.file);
if (!fs.existsSync(absfile)) {
return res.status(httpStatus.badRequest).json({
ok: false,
msg: 'File name not found on server.'
})
}
res.sendFile(path.resolve(absfile));
}
Angular 6がテストしたコンポーネントサービス(私の場合はEmployeeService):
downloadPhoto( name: string) : Observable<Blob> {
const url = environment.api_url + '/storer/employee/image/' + name;
return this.http.get(url, { responseType: 'blob' })
.pipe(
takeWhile( () => this.alive),
filter ( image => !!image));
}
テンプレート
<img [src]="" class="custom-photo" #photo>
コンポーネントサブスクライバおよび使用:
@ViewChild('photo') image: ElementRef;
public LoadPhoto( name: string) {
this._employeeService.downloadPhoto(name)
.subscribe( image => {
const url= window.URL.createObjectURL(image);
this.image.nativeElement.src= url;
}, error => {
console.log('error downloading: ', error);
})
}
「投稿を使用してrxjsダウンロードファイル」を検索すると、ここで終了しました。
これが私の最終製品でした。サーバーの応答で指定されたファイル名とタイプを使用します。
import { ajax, AjaxResponse } from 'rxjs/ajax';
import { map } from 'rxjs/operators';
downloadPost(url: string, data: any) {
return ajax({
url: url,
method: 'POST',
responseType: 'blob',
body: data,
headers: {
'Content-Type': 'application/json',
'Accept': 'text/plain, */*',
'Cache-Control': 'no-cache',
}
}).pipe(
map(handleDownloadSuccess),
);
}
handleDownloadSuccess(response: AjaxResponse) {
const downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(response.response);
const disposition = response.xhr.getResponseHeader('Content-Disposition');
if (disposition) {
const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
const matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) {
const filename = matches[1].replace(/['"]/g, '');
downloadLink.setAttribute('download', filename);
}
}
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}