Pugnatore
Pugnatore

Reputation: 405

Error downloading .xlsx file using http.get in angular with asp.net web api

Im trying to download a .xlsx file using Angular 7 and web api in c# but Im getting this error:

enter image description here

My service.ts

public exportExcelFile(matchedRows: string, reportInfoId: number): Observable<any> {
        const httpOptions = {
            headers: new HttpHeaders({ 'responseType':  'ResponseContentType.Blob',
            'Content-Type':  'application/vnd.ms-excel'})};
        const url = `${environment.apiUrl}report/${reportInfoId}/exportExcelFile?matchedRows=${matchedRows}`;

        return this.http.get(url, httpOptions);

    }

Method that is "consuming" my service:

exportExcelFile(matchedRows:string){
        this.service.exportExcelFile(matchedRows, this.reportInfo.ide).subscribe((response)=>{
            console.log(response)
        })  
        this.exportingExcelFile=false;
        this.ready=true;
    }

Method that is retrieving my response from API

[HttpGet]
public IHttpActionResult ExportExcelFile(int reportId, bool matchedRows)
{

    var user = Request.GetAuthenticatedUser();
    var query = new GetExcelFileQuery(reportId, user.UserName, matchedRows);
    var result = _dispatcher.Dispatch<GetExcelFileQuery, GetExcelFileModel>(query);

    using (var memoryStream = new MemoryStream()) //creating memoryStream
    {
        result.Workbook.Write(memoryStream);

        var response = new HttpResponseMessage(HttpStatusCode.OK);
        response.Content = new ByteArrayContent(memoryStream.ToArray());
        response.Content.Headers.ContentType = new MediaTypeHeaderValue
               ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.Content.Headers.ContentDisposition =
               new ContentDispositionHeaderValue("attachment")
               {
                   FileName = result.FileName
               };

        return result == null ? NotFound() : (IHttpActionResult)new FileResult(response);
    }
}

If I access directly using the URL on my browser, the excel file is correctly exported

Upvotes: 2

Views: 2023

Answers (2)

Pugnatore
Pugnatore

Reputation: 405

Service.ts

   public exportExcelFile(matchedRows: string, reportInfoId: number): Observable<any> {

        const url = `${environment.apiUrl}report/${reportInfoId}/exportExcelFile?matchedRows=${matchedRows}`;

        return this.http.get(url,{  observe: 'response', responseType: 'blob'} );

    }

Method that is calling my service

exportExcelFile(matchedRows:string){
        this.service.exportExcelFile(matchedRows, this.reportInfo.ide).subscribe((response)=>{

            const blob = new Blob([response.body],
                { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });

            const file = new File([blob], 'reports.txt',
                { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });


            saveAs(file);
        })  

with

import { saveAs } from 'file-saver';

The excel file is correctly generated

Upvotes: 1

nll_ptr
nll_ptr

Reputation: 881

Your backend is fine. The client is trying to parse the response as it was a json file. 'responseType' should just be 'blob' and it should be placed outside of the HttpHeaders object. You can omit the entire httpHeaders object in your situation

const url = `${environment.apiUrl}report/${reportInfoId}/exportExcelFile?matchedRows=${matchedRows}`;

return this.http.get(url, {responseType: 'blob'});

Here's some additional info on the responseType object: https://angular.io/api/common/http/HttpRequest#responseType

Upvotes: 1

Related Questions