Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何下载Angular2或更高版本的文件_Javascript_Angular_Typescript_Download_Fileapi - Fatal编程技术网

Javascript 如何下载Angular2或更高版本的文件

Javascript 如何下载Angular2或更高版本的文件,javascript,angular,typescript,download,fileapi,Javascript,Angular,Typescript,Download,Fileapi,我有一个WebApi/MVC应用程序,我正在为它开发一个angular2客户端(以取代MVC)。我在理解Angular如何保存文件时遇到了一些问题 请求是可以的(MVC可以正常工作,我们可以记录收到的数据),但我不知道如何保存下载的数据(我主要遵循与中相同的逻辑)。我相信这是愚蠢的简单,但到目前为止,我只是没有掌握它 组件功能的代码如下所示。我尝试过不同的选择,blob方式应该是我所理解的方式,但是URL中没有函数createObjectURL。我甚至在窗口中找不到URL的定义,但它显然存在。如

我有一个WebApi/MVC应用程序,我正在为它开发一个angular2客户端(以取代MVC)。我在理解Angular如何保存文件时遇到了一些问题

请求是可以的(MVC可以正常工作,我们可以记录收到的数据),但我不知道如何保存下载的数据(我主要遵循与中相同的逻辑)。我相信这是愚蠢的简单,但到目前为止,我只是没有掌握它

组件功能的代码如下所示。我尝试过不同的选择,blob方式应该是我所理解的方式,但是
URL
中没有函数
createObjectURL
。我甚至在窗口中找不到
URL
的定义,但它显然存在。如果我使用了,我会得到同样的错误。所以我猜这是最近发生的变化,或者还没有实现。如何触发A2中的文件保存

下载文件(类型:字符串){ 让文件={}; this.pservice.downloadfile(this.rundata.name,类型) .subscribe(data=>thefile=newblob([data],{type:“application/octet stream”}),//console.log(data), error=>console.log(“下载文件时出错”), ()=>console.log('已完成文件下载'); 让url=window.url.createObjectURL(文件); 窗口打开(url); } 为了完整性起见,获取数据的服务如下所示,但它所做的唯一事情是发出请求并在成功的情况下传递数据,而不进行映射:

下载文件(runname:string,type:string){ 返回此.authHttp.get(this.files\u api+this.title+“/”+runname+“/?file=“+type) .catch(this.logAndPassOn); }
问题在于可观察对象在另一个上下文中运行,因此当您尝试创建URL变量时,您有一个空对象,而不是您想要的blob

解决这一问题的多种方法之一如下:

this.\u reportService.getReport().subscribe(数据=>this.downloadFile(数据)),//console.log(数据),
error=>console.log('下载文件时出错'),
()=>console.info('OK');
当请求准备就绪时,它将调用函数“downloadFile”,该函数定义如下:

下载文件(数据:响应){
const blob=new blob([data],{type:'text/csv'});
constURL=window.url.createObjectURL(blob);
窗口打开(url);
}
blob已经完全创建好了,因此URL变量,如果没有打开新窗口,请检查您是否已经导入了“rxjs/Rx”

导入'rxjs/Rx';
我希望这能对您有所帮助。

正如上面提到的,这是一个简单的范围错误。
subscribe
是异步运行的,必须将
open
放在该上下文中,以便在触发下载时完成数据加载

也就是说,有两种方法。正如文档所建议的,该服务负责获取和映射数据:

//在服务上:
下载文件(runname:string,type:string){
var headers=新的headers();
append('responseType','arraybuffer');
返回此.authHttp.get(this.files\u api+this.title+“/”+runname+“/?file=“+type)
.map(res=>newblob([res],{type:'application/vnd.openxmlformats officedocument.spreadsheetml.sheet}))
.catch(this.logAndPassOn);
}
然后,在组件上,我们只需订阅并处理映射的数据。有两种可能性第一个,如原帖所示,但需要一点修正,如亚历杭德罗所述:

//在组件上
下载文件(类型:字符串){
this.pservice.downloadfile(this.rundata.name,类型)
.subscribe(数据=>window.open(window.URL.createObjectURL(数据)),
error=>console.log(“下载文件时出错”),
()=>console.log('已完成文件下载');
}
第二种方法是使用FileReader。逻辑是相同的,但我们可以显式地等待FileReader加载数据,避免嵌套,并解决异步问题

//在使用FileReader的组件上
下载文件(类型:字符串){
var reader=new FileReader();
this.pservice.downloadfile(this.rundata.name,类型)
.subscribe(res=>reader.readAsDataURL(res),
error=>console.log(“下载文件时出错”),
()=>console.log('已完成文件下载');
reader.onloadend=函数(e){
打开(reader.result'Excel','width=20,height=10,toolbar=0,menubar=0,scrollbars=no');
}
}

注意:我正在尝试下载Excel文件,即使已触发下载(因此这回答了问题),该文件也已损坏。用于避免损坏的文件。如果不需要在请求中添加标题,要下载Angular2格式的文件,可以执行简单的():

window.location.href=http://example.com/myuri/report?param=x';

在您的组件中。

我分享了帮助我的解决方案(非常感谢任何改进)

在您的服务上“pservice”:


getMyFileFromBackend(typeName:string):可观察的

通过ajax下载文件总是一个痛苦的过程,在我看来,最好让服务器和浏览器进行内容类型协商

我想最好是


去做吧。这甚至不需要打开任何新窗口之类的东西

示例中的MVC控制器可以如下所示:

[HttpGet(“[action]”)
公共异步任务下载文件()
{
// ...
返回文件(dataStream.ToArray(),“text/plain”,“myblob.txt”);
}

下载适用于angular 2.4.x的*.zip解决方案:您必须从“@angular/http”和chan导入ResponseContentType
npm install file-saver --save
npm install @types/file-saver --save
npm install file-saver --save
npm install @types/file-saver --save


import {saveAs} from 'file-saver/FileSaver';

this.http.get('endpoint/', {responseType: "blob", headers: {'Accept': 'application/pdf'}})
  .subscribe(blob => {
    saveAs(blob, 'download.pdf');
  });
 let headers = new Headers({
                'Content-Type': 'application/json',
                'MyApp-Application': 'AppName',
                'Accept': 'application/vnd.ms-excel'
            });
            let options = new RequestOptions({
                headers: headers,
                responseType: ResponseContentType.Blob
            });


this.http.post(this.urlName + '/services/exportNewUpc', localStorageValue, options)
                .subscribe(data => {
                    if (navigator.appVersion.toString().indexOf('.NET') > 0)
                    window.navigator.msSaveBlob(data.blob(), "Export_NewUPC-Items_" + this.selectedcategory + "_" + this.retailname +"_Report_"+this.myDate+".xlsx");

                    else {
                        var a = document.createElement("a");
                        a.href = URL.createObjectURL(data.blob());
                        a.download = "Export_NewUPC-Items_" + this.selectedcategory + "_" + this.retailname +"_Report_"+this.myDate+ ".xlsx";
                        a.click();
                    }
                    this.ui_loader = false;
                    this.selectedexport = 0;
                }, error => {
                    console.log(error.json());
                    this.ui_loader = false;
                    document.getElementById("exceptionerror").click();
                });
this._reportService.getReport()
    .subscribe((data: any) => {
        this.downloadFile(data);
    },
        (error: any) => сonsole.log(error),
        () => console.log('Complete')
    );
downloadFile(data: any, type: number, name: string) {
    const blob = new Blob([data], {type: 'text/csv'});
    const dataURL = window.URL.createObjectURL(blob);

    // IE doesn't allow using a blob object directly as link href
    // instead it is necessary to use msSaveOrOpenBlob
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
      window.navigator.msSaveOrOpenBlob(blob);
      return;
    }

    const link = document.createElement('a');
    link.href = dataURL;
    link.download = 'export file.csv';
    link.click();

    setTimeout(() => {

      // For Firefox it is necessary to delay revoking the ObjectURL
      window.URL.revokeObjectURL(dataURL);
      }, 100);
    }
}
public downloadFile(file: File): Observable<Blob> {
    return this.http.get(file.fullPath, {responseType: 'blob'})
}
// service method
downloadFiles(vendorName, fileName) {
    return this.http.get(this.appconstants.filesDownloadUrl, { params: { vendorName: vendorName, fileName: fileName }, responseType: 'arraybuffer' }).map((res: ArrayBuffer) => { return res; })
        .catch((error: any) => _throw('Server error: ' + error));
}

// a controller function which actually downloads the file
saveData(data, fileName) {
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    let blob = new Blob([data], { type: "octet/stream" }),
        url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = fileName;
    a.click();
    window.URL.revokeObjectURL(url);
}

// a controller function to be called on requesting a download
downloadFiles() {
    this.service.downloadFiles(this.vendorName, this.fileName).subscribe(data => this.saveData(data, this.fileName), error => console.log("Error downloading the file."),
        () => console.info("OK"));
}
<a href="my_url">Download File</a>
downloadfile(runname: string, type: string): string {
   return window.location.href = `${this.files_api + this.title +"/"+ runname + "/?file="+ type}`;
}
<a download [attr.href]="yourDownloadLink"></a>
<div>
       <a [href]="fileUrl" mat-raised-button (click)='getGenaratedLetterTemplate(element)'> GENARATE </a>
</div>
import { environment } from 'environments/environment';
import { DomSanitizer } from '@angular/platform-browser';
export class ViewHrApprovalComponent implements OnInit {
private apiUrl = environment.apiUrl;
  fileUrl
 constructor(
    private sanitizer: DomSanitizer,
    private letterService: LetterService) {}
getGenaratedLetterTemplate(letter) {

    this.data.getGenaratedLetterTemplate(letter.letterId).subscribe(
      // cannot download files directly with AJAX, primarily for security reasons);
    console.log(this.apiUrl + 'getGeneratedLetter/' + letter.letterId);
    this.fileUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.apiUrl + 'getGeneratedLetter/' + letter.letterId);
  }
this.httpclient.get(
   `${myBackend}`,
   {
      observe: 'response',
      responseType: 'blob'
   }
).pipe(first())
.subscribe(response => SaveFileResponse(response, 'Custom File Name.extension'));
export const SaveFileResponse = 
(response: HttpResponse<Blob>, 
 filename: string = null) => 
{
    //null-checks, just because :P
    if (response == null || response.body == null)
        return;

    let serverProvidesName: boolean = true;
    if (filename != null)
        serverProvidesName = false;

    //assuming the header is something like
    //content-disposition: attachment; filename=TestDownload.xlsx; filename*=UTF-8''TestDownload.xlsx
    if (serverProvidesName)
        try {
            let f: string = response.headers.get('content-disposition').split(';')[1];
            if (f.includes('filename='))
                filename = f.substring(10);
        }
        catch { }
    SaveFile(response.body, filename);
}

//Create an anchor element, attach file to it, and
//programmatically click it. 
export const SaveFile = (blobfile: Blob, filename: string = null) => {
    const a = document.createElement('a');
    a.href = window.URL.createObjectURL(blobfile);
    a.download = filename;
    a.click();
}
downloadFile(x: any) {
var newBlob = new Blob([x], { type: "application/octet-stream" });

    // IE doesn't allow using a blob object directly as link href
    // instead it is necessary to use msSaveOrOpenBlob
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
      window.navigator.msSaveOrOpenBlob(newBlob);
      return;
    }

    // For other browsers: 
    // Create a link pointing to the ObjectURL containing the blob.
    const data = window.URL.createObjectURL(newBlob);

    var link = document.createElement('a');
    link.href = data;
    link.download = "mapped.xlsx";
    // this is necessary as link.click() does not work on the latest firefox
    link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));

    setTimeout(function () {
      // For Firefox it is necessary to delay revoking the ObjectURL
      window.URL.revokeObjectURL(data);
      link.remove();
    }, 100);  }
let link = document.createElement('a');
link.href = data.fileurl; //data is object received as response
link.download = data.fileurl.substr(data.fileurl.lastIndexOf('/') + 1);
link.click();
public exportAsExcelFile(dataId: InputData) {
    return this.http.get(this.apiUrl + `event/export/${event.id}`, {
        responseType: "blob",
        observe: "response"
    }).pipe(
        tap(response => {
            this.downloadFile(response.body, this.parseFilename(response.headers.get('Content-Disposition')));
        })
    );
}

private downloadFile(data: Blob, filename: string) {
    const blob = new Blob([data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8;'});
    if (navigator.msSaveBlob) { // IE 10+
        navigator.msSaveBlob(blob, filename);
    } else {
        const link = document.createElement('a');
        if (link.download !== undefined) {
            // Browsers that support HTML5 download attribute
            const url = URL.createObjectURL(blob);
            link.setAttribute('href', url);
            link.setAttribute('download', filename);
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    }
}

private parseFilename(contentDisposition): string {
    if (!contentDisposition) return null;
    let matches = /filename="(.*?)"/g.exec(contentDisposition);

    return matches && matches.length > 1 ? matches[1] : null;
}
 private object ConvertFileResponse(ExcelOutputDto excelOutput)
    {
        if (excelOutput != null)
        {
            ContentDisposition contentDisposition = new ContentDisposition
            {
                FileName = excelOutput.FileName.Contains(_excelExportService.XlsxExtension) ? excelOutput.FileName : "TeamsiteExport.xlsx",
                Inline = false
            };
            Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
            Response.Headers.Add("Content-Disposition", contentDisposition.ToString());
            return File(excelOutput.ExcelSheet, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        }
        else
        {
            throw new UserFriendlyException("The excel output was empty due to no events.");
        }
    }