We are using NPOI library here, which will help to perform import and export operations. In order to see how to create a .NET Core Web Application with Razor Pages and retrieve data from SQL Server using Entity Framework, you can visit my previous article.
Below are the software/concepts used in this document.
- Visual Studio 2019
- NPOI Library
- NuGet Packages
- Razor Pages
- .NET Core 2.0
- .NETCore Web Application
- C# Language
Brief description of NPOI
NPOI is an open source project which can help you read/write XLS, DOC, PPT file extensions. This tool is the .NET version of POI Java project (http://poi.apache.org/). It covers most of the features of Excel like styling, formatting, data formulas, extract images, etc. The good thing is that it does not require Microsoft Office on the server. For example, you can use it to -
- Generate an Excel report without Microsoft Office suite installed on your Server, which is more efficient than calling Microsoft Excel ActiveX in the background.
- Extract text from Office documents to help you implement full-text indexing feature (most of the times, this feature is used to create search engines).
- Extract images from Office documents.
- Generate Excel sheets which contain formulas.
How Razor Pages handle incoming HTTP Requests
Razor pages use handler methods to deal with the incoming HTTP request (GET/POST/PUT/Delete). They are prefixed with “On” and the name of HTTP verbs like -
- OnGet
- OnPost
- OnPut
- OnGetAsync
- OnPostAsync
- OnPutAsync
Besides these default handlers, we can also specify custom names. The custom name must come after the followed naming convention like, for example -
- OnGetCountries()
- OnPostUserMaster()
- OnPostUserDetails()
We will be using custom names for our Import and Export handler methods.
Open your project in Visual Studio 2019
In my case, I am opening the earlier created project where Razor pages are present.

Add NuGet Packages to the above-created project
In the Visual Studio menu, browse to Tools >> NuGet Package Manager >> Package Manager Console.

Then, execute the following command to install the NPOI.
Export to Excel by creating Excel (.xlsx/.xls) with dummy data
Open the Index page (Razor page) where the data is present. In my example, I am opening Index.cshtml under “Customers” folder where my customer data is displayed.
- <form method="post" enctype="multipart/form-data">
- <div class="row">
- <div class="col-md-8" style="padding-top:10px;">
- <button asp-page-handler="ExporttoExcel">Export to Excel</button>
- </div>
- </div>
- <div id="divData"></div>
- </form>
- private IHostingEnvironment _hostingEnvironment;
- public IndexModel(IHostingEnvironment hostingEnvironment)
- {
- _hostingEnvironment = hostingEnvironment;
- }
- public async Task<IActionResult> OnPostExporttoExcel()
- {
- string webRootPath = _hostingEnvironment.WebRootPath;
- string fileName = @"Testingdummy.xlsx";
- string URL = string.Format("{0}://{1}/{2}", Request.Scheme, Request.Host, fileName);
- FileInfo file = new FileInfo(Path.Combine(webRootPath, fileName));
- var memoryStream = new MemoryStream();
- // --- Below code would create excel file with dummy data----
- using (var fs = new FileStream(Path.Combine(webRootPath, fileName), FileMode.Create, FileAccess.Write))
- {
- IWorkbook workbook = new XSSFWorkbook();
- ISheet excelSheet = workbook.CreateSheet("Testingdummy");
- IRow row = excelSheet.CreateRow(0);
- row.CreateCell(0).SetCellValue("ID");
- row.CreateCell(1).SetCellValue("Name");
- row = excelSheet.CreateRow(1);
- row.CreateCell(0).SetCellValue(1);
- row.CreateCell(1).SetCellValue("Mike");
- row = excelSheet.CreateRow(2);
- row.CreateCell(0).SetCellValue(2);
- row.CreateCell(1).SetCellValue("James");
- workbook.Write(fs);
- }
- using (var fileStream = new FileStream(Path.Combine(webRootPath, fileName), FileMode.Open))
- {
- await fileStream.CopyToAsync(memoryStream);
- }
- memoryStream.Position = 0;
- return File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
- }

Export to Excel by taking data from the screen
Open the Index page (Razor page) where the data is present. In my example, I am opening Index.cshtml under “Customers” folder where my customer data is displayed.
- Repeat the two steps from above (where we put Form and IHostingEnvironment code on the index.cshtml and index.cshtml.cs pages).
- My data already gets loaded on the page and the same data I want to export to the Excel.

- The NPOI package supports both “xls” and “xlsx” extensions using HSSFWorkbook and XSSFWorkbook classes. In my example, I would be using XSSFWorkbook class, as I will work with .xlsx file. In Index.cshtml.cs file, put the following code. Also, since I have 4 columns of data to be exported to Excel, in my example, I will have 4 columns.
- public async Task<IActionResult> OnPostExporttoExcel()
- {
- string webRootPath = _hostingEnvironment.WebRootPath;
- string fileName = @"Testingdummy.xlsx";
- string URL = string.Format("{0}://{1}/{2}", Request.Scheme, Request.Host, fileName);
- FileInfo file = new FileInfo(Path.Combine(webRootPath, fileName));
- var memoryStream = new MemoryStream();
- // --- Below code would create excel file with dummy data----
- using (var fs = new FileStream(Path.Combine(webRootPath, fileName), FileMode.Create, FileAccess.Write))
- {
- IWorkbook workbook = new XSSFWorkbook();
- ISheet excelSheet = workbook.CreateSheet("Testingdummy");
- IRow row = excelSheet.CreateRow(0);
- row.CreateCell(0).SetCellValue("CustomerId");
- row.CreateCell(1).SetCellValue("FirstName");
- row.CreateCell(2).SetCellValue("LastName");
- row.CreateCell(3).SetCellValue("Email");
- cust = from s in _context.Customers select s;
- int counter = 1;
- foreach(var customer in cust)
- {
- string FirstName = string.Empty;
- if (customer.FirstName.Length > 100)
- FirstName = customer.FirstName.Substring(0, 100);
- else
- FirstName = customer.FirstName;
- row = excelSheet.CreateRow(counter);
- row.CreateCell(0).SetCellValue(customer.CustomerId);
- row.CreateCell(1).SetCellValue(FirstName);
- row.CreateCell(2).SetCellValue(customer.LastName);
- row.CreateCell(3).SetCellValue(customer.Email);
- counter++;
- }
- workbook.Write(fs);
- }
- using (var fileStream = new FileStream(Path.Combine(webRootPath, fileName), FileMode.Open))
- {
- await fileStream.CopyToAsync(memoryStream);
- }
- memoryStream.Position = 0;
- return File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
- }




Greg HowleyPosted Jul 26, 2022, 5:14 PM
It turns out that the issue with File() was due to the fact that I was coding outside the controller. https://stackoverflow.com/questions/35936628/non-invocable-member-file-cannot-be-used-like-a-method-while-generating-report
Greg HowleyPosted Jul 26, 2022, 3:12 PM
Hi - first off, thanks for putting up this useful content. I'm about to complain about it not working, but in the end, this is all helpful and I don't want to come across as one of the internet's ubiquitous trolls. :-)So firstly, in your #3, I'm seeing you create a filestream fs and then never use it. You then create a second filestream named filestream and copy it to the returned memorystream without using fs or workbook. Is this correct? Secondly, I'm trying to use "return File(...)" and I'm seeing CS1955: Non-invocable member 'File' cannot be used like a method. I'm on VS2022, .NET 6.0 and not sure what I'm doing wrong.
Hemant SharmaPosted May 15, 2019, 7:36 AM
Please suggest the coding to get the activeCell no. from Excel (.xls) with NPOI DLL in C#.