Angular 2 - 下载csv文件
我试图从Microsoft Web API 2控制器下载csv文件。这是我到目前为止有: -Angular 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);
}
}
角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);
}
}
角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)
})
}
}
但是,当我运行do wnload,我得到一个csv文件下载,其中包含以下内容: -
{“Version”:{“_ Major”:1 _Minor:1 _Build:-1 _Revision:-1}内容:{“Headers”: [{“Key”:“Content-Disposition”值:[“attachment; filename = \“RPModel_Portfolio_ISY - 20170925.csv \”“]} {”Key“:”Content-Type“Value:[”application/octet-stream“]}]} StatusCode:200 ReasonPhrase:”OK“Headers:[] RequestMessage:空IsSuccessStatusCode:真正}
谁能帮助
感谢
我无法弄清楚如何解决这个问题,所以我只是提供了我的Web API操作中的csv数据的json表示,然后使用Angular2Csv Angular 2库将此json对象转换为CSV文件
由于某种原因,使用ResponseMessage(result)而不是其他Web API包装(如Ok(result))之一意味着CORS被实际请求忽略。 OPTIONS(pre-flight)请求似乎可以工作,但GET在使用ResponseMessage(result)时不会发生,但在使用Ok(result)时会发生,所以我只能假设Ok(result)正在做某些事情来使用Cors功能在网页API 2
我有同样的问题从下载的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的主体创建一个blob。如果返回二进制文件,则可以调用“.blob()”。
我希望它对你有所帮助。
提供我改变了我的代码以匹配你的,但它仍然给我的csv文件 getExtractContent(extractId:数):相同的输出可观测 { 回报this.http.get(这一点。 baseAddress +'extractContent /'+ extractId,this.options) 。map((data:any)=> var mediaType = data.headers.get(“Content-Type”); var body = data._body; return new Blob([body],{type:mediaType} ); } ) .catch(this.errorService.handleError); } –
BigBytes
我还将选项更改为: - this.options = new RequestOptions({headers:this.headers,withCredentials:true,responseType:ResponseContentType.Text}); 但这没有什么区别。 我想知道是否因为我在WebAPI行动中这样做: - 好的(结果) – BigBytes
所以我改变了我的web api action来返回一个ResponseMessage(result),但现在我得到了一个500内部服务器错误,GET请求的资源上出现“No-Access-Control-Allow-Origin'标头,原因'http:// localhost:4200'因此不被允许访问。可怕的CORS错误。 OPTIONS飞行前请求以200响应,但GET响应500以及上述错误消息。有任何想法吗? – BigBytes