Search code examples
entity-frameworkmodel-view-controllerfile-upload.net-corenpoi

Upload and read excel file using .NET core MVC


I have implemented an algorithm of reading an excel file using NPOI in .NET Core. Now I want is to upload a excel file in a web-app and read the excel file during uploading time and save it to database.

I am a bit confused about how should I approach for Model, Views and Controllers. Here are the optimized requirement list:

  • To ensure user is uploading .xlsx file (not other files)
  • Reading excel data during upload time
  • Save data in a database

Solution

  • Your controller can be something like this:

        public ActionResult Import(System.Web.HttpPostedFileBase uploadFile)
        {
            if (uploadFile != null)
                {
                    if (uploadFile.ContentLength > 0)
                    {
                        var fileExtension = Path.GetExtension(uploadFile.FileName);
                        if (fileExtension.ToLower().Equals(".xlsx"))
                        {
                            BinaryReader b = new BinaryReader(uploadFile.InputStream);
                            int count = uploadFile.ContentLength;
                            byte[] binData = b.ReadBytes(count);
                            using (MemoryStream stream = new MemoryStream(binData))
                            {
                                //call the service layer to read the data from stream
                            }
                         }
                      }
                 }
        }
    

    And your service layer is what you already figured out, using NPOI to read.

    Based on the data you are reading from the excel file, your model could be something like this:

    public class Product
    {
        public int ProductID {get; set;}
        public string Name {get; set;}
        public decimal Price {get; set;}
    }
    

    In the database, you can have a stored procedure which can take multiple rows of data using user-defined table type. You can call this stored procedure from your repository, after your read the data in service layer.

    Finally in the view, you can have a form with the file upload dialog and pass the file uploaded by the user. Javascript to call the controller could be something like this:

    function x () {
                var inputdata = null;
                var form = $('#__ImportFileForm');
                var token = $('input[name="__RequestVerificationToken"]', form).val();
                var fd = new FormData();
                fd.append("__RequestVerificationToken", token);
                fd.append("uploadFile", $("#uploadFile")[0].files[0]);
                inputdata = fd;
                inputdata.skipAjaxPrefilter = true;
    
                $.ajax({
                    type: "Post",
                    url: url,
                    data: inputdata,
                    processData: false,
                    contentType: false,
                    traditional: true,
                    async: true,
                    success: function(data) { //do what you want },
                    error: function(data, ajaxOptions, thrownError) { //do what you want }
                });
    }
    

    Hope this answers all your questions!