Angular 2 - 下载csv文件

时间:2017-09-25 18:36:16

标签: angular csv asp.net-web-api2

我试图从Microsoft Web API 2控制器下载csv文件。这是我到目前为止所拥有的: -

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下载服务: -

@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客户端代码: -

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)
        })
    }
}

但是,当我运行下载时,我会下载一个csv文件,其中包含以下内容: -

{&#34;版本&#34;:{&#34; _Major&#34;:1 _Minor:1 _Build:-1 _Revision:-1}内容:{&#34; Headers&#34;:[{ &#34;键&#34;:&#34;内容处置&#34;值:[&#34;附件; filename = \&#34; RPModel_Portfolio_ISY - 20170925.csv \&#34;&#34;]} {&#34; Key&#34;:&#34; Content-Type&#34;值:[&#34; application / octet-stream&#34;]}]} StatusCode:200 ReasonPhrase:&#34; OK&#34;标题:[] RequestMessage:null IsSuccessStatusCode:true}

有人可以帮忙吗?

由于

2 个答案:

答案 0 :(得分:0)

从WebAPI下载XML文件时遇到同样的问题。

RequestOptions存在差异,当有二进制文件(.PDF,.ZIP,...)时,您可以调用:

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

但是,当文件是文本文件(.txt,.csv,...)时,你必须调用API来询问文本文件,所以:

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

在我的情况下,我创建了一个从API接收响应并创建通信文件的过程。

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);
}

当Response返回文本时,您将从Response的主体创建一个blob。如果返回二进制文件,您可以调用&#34; .blob()&#34;。

我希望它对你有所帮助。

答案 1 :(得分:0)

我无法弄清楚如何解决这个问题所以我只是从我的Web API操作中提供了我的csv数据的json表示,然后只使用Angular2Csv Angular 2库将此json对象转换为CSV文件

出于某种原因,使用ResponseMessage(result)而不是其他Web API包装器(例如Ok(result))意味着实际请求会忽略CORS。 OPTIONS(飞行前)请求似乎有效,但GET在使用ResponseMessage(结果)时没有,但是在使用Ok(结果)时它确实如此,所以我只能假设Ok(结果)正在做一些事情来使用Web API 2中提供的Cors功能