21

In similar questions, with this code works to download a PDF:

I'm testing with local files (.xlsx, .pdf, .zip) inside the Controller folder.

Similar Question Here

[HttpGet("downloadPDF")]
public FileResult TestDownloadPCF()
{
   HttpContext.Response.ContentType = "application/pdf";
   FileContentResult result = new FileContentResult
   (System.IO.File.ReadAllBytes("Controllers/test.pdf"), "application/pdf")
    {
      FileDownloadName = "test.pdf"
    };
   return result;
}

This works great!

But when another file?, for example an Excel File(.xlsx) or ZIP File(.zip), testing does not work properly.

Code :

[HttpGet("downloadOtherFile")]
public FileResult TestDownloadOtherFile()
{
  HttpContext.Response.ContentType = 
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  FileContentResult result = new FileContentResult(System.IO.File.ReadAllBytes("Controllers/test.xlsx"), 
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
  {
    FileDownloadName = "otherfile"
   };
  return result;
}

Result: enter image description here

I also did tests with the following Content-Type:

  • "Application / vnd.ms-excel"
  • "Application / vnd.ms-excel.12"

Getting the same result.

Which is the right way to return any file type?

Thanks for your answers

5
  • 1
    You need to add a Content-Disposition header with attachment type Commented Aug 10, 2016 at 15:39
  • add HttpContext.Response.Headers.Add ("Content-disposition", "attachment"); But get the same result. Commented Aug 10, 2016 at 15:51
  • We read the xls file into a byte array and return it as a Base64 encoded string. Commented Aug 10, 2016 at 16:56
  • set the charset to utf-8? Commented Aug 10, 2016 at 17:58
  • Download Excel file in reactjs --> stackoverflow.com/a/73421257/8621764 Commented Aug 19, 2022 at 19:10

5 Answers 5

15

My (working) solution:

  • I've got a class that dynamically creates an XLSX file using EPPlus.Core.
    • This returns a FileInfo for the generated file's path.

This is what is in my Controller:

[HttpGet("test")]
public async Task<FileResult> Get()
{
    var contentRootPath = _hostingEnvironment.ContentRootPath;

    // "items" is a List<T> of DataObjects
    var items = await _mediator.Send(new GetExcelRequest());

    var fileInfo = new ExcelFileCreator(contentRootPath).Execute(items);
    var bytes = System.IO.File.ReadAllBytes(fileInfo.FullName);

    const string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    HttpContext.Response.ContentType = contentType;
    HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");

    var fileContentResult = new FileContentResult(bytes, contentType)
    {
        FileDownloadName = fileInfo.Name
    };

    return fileContentResult;
}

And here is what I have in Angular2:

downloadFile() {
    debugger;
    var headers = new Headers();
    headers.append('responseType', 'arraybuffer');

    let url = new URL('api/excelFile/test', environment.apiUrl);

    return this.http
        .get(url.href, {
            withCredentials: true,
            responseType: ResponseContentType.ArrayBuffer
        })
        .subscribe((response) => {
            let file = new Blob([response.blob()], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
            let fileName = response.headers.get('Content-Disposition').split(';')[1].trim().split('=')[1];
            saveAs(file, fileName);
        },
        err => this.errorHandler.onError(err)
        );
}
Sign up to request clarification or add additional context in comments.

1 Comment

The contentType of application/vnd.openxmlformats-officedocument.spreadsheetml.sheet worked for me.
4

I had this same issue. My issue was being caused by the client request, not the server response. I solved it by adding a response content type to my Get request's header options. Here is my example in Angular 2.

Request from client (Angular 2) **requires filesaver.js library

this._body = '';

    let rt: ResponseContentType = 2; // This is what I had to add ResponseContentType (2 = ArrayBuffer , Blob = 3)
        options.responseType = rt;
    if (url.substring(0, 4) !== 'http') {
        url = config.getApiUrl(url);
    }

    this.http.get(url, options).subscribe(
        (response: any) => {
            let mediaType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
            let blob = new Blob([response._body], { type: mediaType });
            let filename = 'test.xlsx';
            fileSaver.saveAs(blob, filename);
        });

Server side code. (.net core)

    [HttpGet("{dataViewId}")]
    public IActionResult GetData(string dataViewId)
    {
        var fileName = $"test.xlsx";
        var filepath = $"controllers/test/{fileName}";
        var mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

        byte[] fileBytes = System.IO.File.ReadAllBytes(filepath);
        return File(fileBytes, mimeType, fileName);
    }

here are the references if you want to see.

Corrupted download in AngularJs app

C# File Download is Corrupt

1 Comment

Download Excel file in reactjs --> stackoverflow.com/a/73421257/8621764
1

Following is an example of how you can download a file, you can model your scenario of downloading an Excel file after it:

public IActionResult Index([FromServices] IHostingEnvironment hostingEnvironment)
{
    var path = Path.Combine(hostingEnvironment.ContentRootPath, "Controllers", "TextFile.txt");
    return File(System.IO.File.OpenRead(path), contentType: "text/plain; charset=utf-8", fileDownloadName: "Readme.txt");
}

If the file is in the wwwroot folder, you could do something like below instead:

public IActionResult Index()
{
    return File(virtualPath: "~/TextFile.txt", contentType: "text/plain; charset=utf-8", fileDownloadName: "Readme.txt");
}

Comments

0

you can use NPOI

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System.Collections.Generic;
using System.IO;

namespace export_excel.Controllers
{

    [ApiController]
    [Route("[controller]")]
    public class ExportExcelController : ControllerBase
    {

        private readonly IHostingEnvironment _hostingEnvironment;

        public ExportExcelController(IHostingEnvironment hostingEnvironment)
        {
            _hostingEnvironment = hostingEnvironment;
        }

        // https://localhost:5001/ExportExcel/Export
        // https://localhost:5001/static-file/employee.xlsx
        [HttpGet]
        [Route("Export")]
        public IActionResult Export()
        {
            List<Employee> list = new List<Employee>()
            {
                new Employee{ emp_code = "152110032", Name = "Nguyen Hong Anh", Phone = "0909998789" },
                new Employee{ emp_code = "152110055", Name = "Tran Phuong Dung", Phone = "0909993456" },
                new Employee{ emp_code = "152110022", Name = "Do Bich Ngoc", Phone = "0909991237" },
                new Employee{ emp_code = "152110025", Name = "Tran Thu Ha", Phone = "0909990987" },
            };
            // New workbook.
            XSSFWorkbook wb = new XSSFWorkbook();
            // New worksheet.
            ISheet sheet = wb.CreateSheet();
            // Write to sheet.
            // Tạo row
            var row0 = sheet.CreateRow(0);
            // At first row, merge 3 columns.
            // Create cell before merging.
            row0.CreateCell(0);
            CellRangeAddress cellMerge = new CellRangeAddress(0, 0, 0, 2);
            sheet.AddMergedRegion(cellMerge);
            row0.GetCell(0).SetCellValue("Employee information");
            // Ghi tên cột ở row 1
            var row1 = sheet.CreateRow(1);
            row1.CreateCell(0).SetCellValue("emp_code");
            row1.CreateCell(1).SetCellValue("fullname");
            row1.CreateCell(2).SetCellValue("Phone");
            // Traversaling array, then write continous.
            int rowIndex = 2;
            foreach (var item in list)
            {
                // Init new row.
                var newRow = sheet.CreateRow(rowIndex);
                // set values.
                newRow.CreateCell(0).SetCellValue(item.emp_code);
                newRow.CreateCell(1).SetCellValue(item.Name);
                newRow.CreateCell(2).SetCellValue(item.Phone);
                // Increase index.
                rowIndex++;
            };
            if (!System.IO.File.Exists("c:\\myfiles\\employee.xlsx"))

            {
                FileStream fs = new FileStream(@"c:\myfiles\employee.xlsx", FileMode.CreateNew);
                wb.Write(fs);
            }
            var path = Path.Combine(@"c:\myfiles\employee.xlsx");
            return File(System.IO.File.OpenRead(path), contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8", fileDownloadName: "employee.xlsx");
        }

    }

    public class Employee
    {
        public string emp_code;
        public string Name;
        public string Phone;
    }

}

File Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using System.IO;

namespace export_excel
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(
            // Path.Combine(env.ContentRootPath, @"c:\audio\")),
            // Path.Combine(@"c:\audio\")),
            Path.Combine(@"c:\myfiles")),
                RequestPath = "/static-file"
            });
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

}

You can use 1 of 2 ways, go to

https://localhost:5001/ExportExcel/Export

or

https://localhost:5001/static-file/employee.xlsx

Comments

0
// imports
import * as FileSaver from "file-saver";
import axios from "axios";

export default function App() {
   // function to download file
  const downloadExcelFileFun = () => {
    axios
      .post(
        `https://yourapp.test.com/api/v1/myexcelfile/demoExcelfile`,
        {
          // api payload data if any
        },
        {
          headers: {
            Authorization: `Bearer TOKEN_STRING`,
          },
          responseType: "blob",
        }
      )
      .then((res) => {
        // the res.data is of type blob
        FileSaver.saveAs(res.data, "exampleFile.xlsx");
      });
  };

  return (
    <div className="App">
      <button
        onClick={() => {
          downloadExcelFileFun();
        }}
      >
        Download xLsx File
      </button>
    </div>
  );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.