Angular 2 - download csv file

徘徊边缘 提交于 2020-01-25 09:32:08

问题


I'm trying to download a csv file from a Microsoft Web API 2 controller. Here's what I have so far:-

Web API:-

    [Route("extractContent/{extractId}")]
    public async Task<IHttpActionResult> GetExtractContent(int extractId)
    {
        _logger.Info($"Getting extract file content for extract with id: {extractId}...");

        try
        {
            IEnumerable<ExtractDto> extracts = await _extractService.GetExtractsAsync(new ExtractSearchRequest { ExtractId = extractId });

            ExtractDto extract = extracts?.FirstOrDefault();

            if (extract != null)
            {
                string path = extract.FilePath;

                HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);

                var stream = new FileStream(path, FileMode.Open, FileAccess.Read);

                using (result.Content = new StreamContent(stream))
                {
                    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                    {
                        FileName = Path.GetFileName(path)
                    };
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

                    return Ok(result);
                }
            }
            throw new InvalidOperationException($"Could not find extract with id: {extractId}");
        }
        catch (Exception e)
        {
            _logger.ErrorException($"An error occured trying to get extract content for extract with id: {extractId}", e);

            return InternalServerError(e);
        }
    }

Angular 2 Download Service:-

@Injectable()
export class DownloadService {
private baseAddress: string;
private headers: Headers;
private options: RequestOptions;

constructor(private http: Http, private config: Config, private errorService: ErrorService) {
    this.baseAddress = config.cache.get('portfolioUploadApiUrl');
    this.headers = new Headers({ 'Content-Type': 'application/json' });
    this.options = new RequestOptions({ headers: this.headers, withCredentials: true, responseType:  ResponseContentType.Blob});
}

getExtractContent(extractId: number): Observable<Blob> {

    return this.http.get(this.baseAddress + 'extractContent/' + extractId, this.options)
        .map((response: Response) => 
            {
                return new Blob([response.blob()], {type: 'application/csv'});
            }
        )
        .catch(this.errorService.handleError);
}

}

Angular 2 client code:-

onDownload(): void {
    if (this.extract && this.extract.FilePath) {
        this.downloadService.getExtractContent(this.extractId).subscribe(blob => {
            var date = new Date();
            var day = date.getDay();
            var month = date.getMonth();
            var year = date.getFullYear();
            var seconds = date.getSeconds();
            var minutes = date.getMinutes();
            var hours = date.getHours();
            var formattedDate = day + '' + (month + 1) + '' + year + '' + hours + '' + minutes + '' + seconds;
            var fileName = "Extract" + this.extractId + "-" + formattedDate + ".csv";
            FileSaver.saveAs(blob, fileName)
        })
    }
}

However, when I run the download, I get a csv file downloaded which has the following in it:-

{"Version":{"_Major":1 _Minor:1 _Build:-1 _Revision:-1} Content:{"Headers":[{"Key":"Content-Disposition" Value:["attachment; filename=\"RPModel_Portfolio_ISY - 20170925.csv\""]} {"Key":"Content-Type" Value:["application/octet-stream"]}]} StatusCode:200 ReasonPhrase:"OK" Headers:[] RequestMessage:null IsSuccessStatusCode:true}

Can anyone help?

Thanks


回答1:


i had the same problem downloading a XML file from WebAPI.

There's a difference in RequestOptions, when have a Binary File (.PDF, .ZIP, ...) you can call as:

this.options = new RequestOptions({ headers: this.headers, withCredentials: true, responseType:  ResponseContentType.Blob});

But, when a file is Text File (.txt, .csv, ...) you have to call the API asking for a text file, so:

this.options = new RequestOptions({ headers: this.headers, withCredentials: true, responseType:  ResponseContentType.Text});

In my case, i create a procedure to receive the response from API and create the correspondent file.

saveFile(data, fileName: string, extentionFile: string) {
    var mediaType = data.headers.get("Content-Type");
    var file;

    if (extentionFile == "csv") {
        file = new Blob([data._body], { type: mediaType })
    } else {
        file = new Blob([data.blob()], { type: mediaType })
    }

    FileSaver.saveAs(file, fileName);
}

When the Response returns a text, you create a blob from body of the Response. If returns a Binary file, you can call ".blob()".

I hope it helped you.




回答2:


I couldn't figure out how to get around this so I went with just providing a json representation of my csv data from my Web API action and then just using Angular2Csv Angular 2 library to convert this json object into a CSV file

For some reason, using ResponseMessage(result) rather than one of the other Web API wrappers (such as Ok(result)) means that CORS gets ignored for the actual request. The OPTIONS (pre-flight) request seems to work but the GET doesn't when using ResponseMessage(result) but it does when using Ok(result) so I can only assume that Ok(result) is doing something to use the Cors functionality provided in Web API 2



来源:https://stackoverflow.com/questions/46412012/angular-2-download-csv-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!