This worked for me:
Front-end:
HTML/CSS:
<div id="" class="col-xs-12 info-box">
<div class="col-xs-12">
<a role="button" data-toggle="collapse" href="#upload-sample" aria-expanded="false">
<h3><span class="glyphicon glyphicon-upload"></span> Upload de Arquivo</h3>
</a>
</div>
<div id="upload-sample" class="col-xs-12 collapse">
<form method="post" enctype="multipart/form-data">
<div>
<div class="form-group attach" style="width: 100%;">
<label>Select Excel File <button type="button" id="btnDownloadTemplate">(Download Template)</button></label>
<div class="col-md-12"><input type="file" id="fUpload" name="files" multiple class="form-control" style="max-width: 400px;" /></div>
</div>
<div class="filter-button" style="width: 100%;">
<button onclick="AJAXSubmit(this); return false;" id="btnUpload" class="btn btn-primary">Send File and update data</button>
</div>
</div>
</form>
</div>
JavaScript:
async function AJAXSubmit(oFormElement) {
const files = $('#fUpload').prop("files");
const fdata = new FormData();
for (var i = 0; i < files.length; i++) {
fdata.append("files", files[i]);
}
if (files.length > 0) {
Block();
$.ajax({
type: "POST",
url: "/{{controllerName}}/OnPostUpload?handler=Upload",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: fdata,
contentType: false,
processData: false,
success: function (response) {
document.getElementById("fUpload").value = "";
//Unblock();
//toastr.success(response, "File processed successfully");
FilterHandlebarsF.Search(this, true);
},
error: function (response) {
document.getElementById("fUpload").value = "";
//Unblock();
//toastr.warning(response, "Error on processing");
}
});
}
else {
//toastr.warning("Please, select a file.");
}
}
Back-end:
Startup.cs: services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
Controller:
public ActionResult OnPostUpload(List<IFormFile> files)
{
try
{
var file = files.FirstOrDefault();
var inputstream = file.OpenReadStream();
XSSFWorkbook workbook = new XSSFWorkbook(stream);
var FIRST_ROW_NUMBER = {{firstRowWithValue}};
ISheet sheet = workbook.GetSheetAt(0);
// Example: var firstCellRow = (int)sheet.GetRow(0).GetCell(0).NumericCellValue;
for (int rowIdx = 2; rowIdx <= sheet.LastRowNum; rowIdx++)
{
IRow currentRow = sheet.GetRow(rowIdx);
if (currentRow == null || currentRow.Cells == null || currentRow.Cells.Count() < FIRST_ROW_NUMBER) break;
var df = new DataFormatter();
for (int cellNumber = {{firstCellWithValue}}; cellNumber < {{lastCellWithValue}}; cellNumber++)
{
//business logic & saving data to DB
}
}
}
catch(Exception ex)
{
throw new FileFormatException($"Error on file processing - {ex.Message}");
}
}
List<IFormFile>, notICollection. Although, reading the documentation, it can accept anIEnumerable<IFormFile>. See learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads