How to read Excel file and fill it with data in Grid in MVC without saving Excel file anywhere?

I want to download an Excel file using the Browse button. I don't need to save this. Then, with the click of a button, how can I read the data into Excel and show it as a table. I need to accomplish this task using MVC.

+4


source to share


3 answers


Here's my revised answer:

1) Download SDK OpenXML from Microsoft

2) Create an empty MVC 5 project and name it "MVCImportExcel"

3) Add link to DocumentFormat.OpenXML by going to SDK lib subdirectory

4) Add a link to WindowsBase

5) Create a new model called "MyViewModel"

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;


namespace MVCImportExcel.Models
{
    public class MyViewModel
    {
        [Required]
        public HttpPostedFileBase MyExcelFile { get; set; }

        public string MSExcelTable { get; set; }
    }
}

      



6) Create a new controller called "HomeController"

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCImportExcel.Models;
using System.Data;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System.IO;
namespace MVCImportExcel.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
        public ActionResult Index()
        {
            var model = new MyViewModel();
            return View(model);
        }

        [HttpPost]
        public ActionResult Index(MyViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
            DataTable dt = GetDataTableFromSpreadsheet(model.MyExcelFile.InputStream,false);
            string strContent = "<p>Thanks for uploading the file</p>" + ConvertDataTableToHTMLTable(dt);
            model.MSExcelTable = strContent;
            return View(model);
        }
        public static DataTable GetDataTableFromSpreadsheet(Stream MyExcelStream, bool ReadOnly)
        {
            DataTable dt = new DataTable();
            using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(MyExcelStream, ReadOnly))
            {
                WorkbookPart workbookPart = sDoc.WorkbookPart;
                IEnumerable<Sheet> sheets = sDoc.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
                string relationshipId = sheets.First().Id.Value;
                WorksheetPart worksheetPart = (WorksheetPart)sDoc.WorkbookPart.GetPartById(relationshipId);
                Worksheet workSheet = worksheetPart.Worksheet;
                SheetData sheetData = workSheet.GetFirstChild<SheetData>();
                IEnumerable<Row> rows = sheetData.Descendants<Row>();

                foreach (Cell cell in rows.ElementAt(0))
                {
                    dt.Columns.Add(GetCellValue(sDoc, cell));
                }

                foreach (Row row in rows) //this will also include your header row...
                {
                    DataRow tempRow = dt.NewRow();

                    for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
                    {
                        tempRow[i] = GetCellValue(sDoc, row.Descendants<Cell>().ElementAt(i));
                    }

                    dt.Rows.Add(tempRow);
                }
            }
            dt.Rows.RemoveAt(0);
            return dt;
        }
        public static string GetCellValue(SpreadsheetDocument document, Cell cell)
        {
            SharedStringTablePart stringTablePart = document.WorkbookPart.SharedStringTablePart;
            string value = cell.CellValue.InnerXml;

            if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
            {
                return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
            }
            else
            {
                return value;
            }
        }
        public static string ConvertDataTableToHTMLTable(DataTable dt)
        {
            string ret = "";
            ret = "<table id=" + (char)34 + "tblExcel" + (char)34 + ">";
            ret+= "<tr>";
            foreach (DataColumn col in dt.Columns)
            {
                ret += "<td class=" + (char)34 + "tdColumnHeader" + (char)34 + ">" + col.ColumnName + "</td>";
            }
            ret+= "</tr>";
            foreach (DataRow row in dt.Rows)
            {
                ret+="<tr>";
                for (int i = 0;i < dt.Columns.Count;i++)
                {
                    ret+= "<td class=" + (char)34 + "tdCellData" + (char)34 + ">" + row[i].ToString() + "</td>";
                }
                ret+= "</tr>";
            }
            ret+= "</table>";
            return ret;
        }
    }
}

      

7) Create a new view under the House and name it "Index"

@model MVCImportExcel.Models.MyViewModel
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title></title>
    <style type="text/css">
        #tblExcel
        {
            width: 1000px;
            border: none;
        background-color: #000000;
    }
    .tdColumnHeader
    {
        padding: 2px 2px 2px 2px;
        text-align: center;
        font-family: Verdana;
        font-size: 12px;
        font-weight: bold;
        background-color: cornflowerblue;
        color: #FFFFFF;
    }
    .tdCellData
    {
        padding: 2px 2px 2px 2px;
        font-family: Verdana;
        font-size: 12px;
        background-color: aqua;
        color: #000000;
    }
</style>
</head>
<body>
    @using (Html.BeginForm(null,null,FormMethod.Post,new { enctype = "multipart/form-data" }))
    {
        <div>
            @Html.LabelFor(x => x.MyExcelFile)
            @Html.TextBoxFor(x => x.MyExcelFile, new { type = "file" })
            @Html.ValidationMessageFor(x => x.MyExcelFile)
        </div>
        <button type="submit">Upload</button>

        <br /><br />
        @Html.Raw(Model.MSExcelTable)
    }
</body>

</html>

      

As I said in my comment, this will only work for XLSX files. Hope this helps you or someone else along the way.

:) David

+9


source


I know this answer is too late. I just wanted to answer this question to all those who have landed on this page after having trouble finding it. Here's how to do it using ClosedXML.Excel In Visual Studio, click on the tools menu and expand the NuGet Package Manager and then launch the Package Manager Console. Enter the following command:

Install-Package ClosedXML

      

Model:

namespace ExcelUploadFileDemo.Models
    {
        public class UploadFile
        {
            [Required]
            public HttpPostedFileBase ExcelFile { get; set; }
        }
    }

      

Controller:



namespace ExcelUploadFileDemo.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                UploadFile UploadFile = new UploadFile();
                return View(UploadFile);
            }

            [HttpPost]
            public ActionResult Index(UploadFile UploadFile)
            {
                if (ModelState.IsValid)
                {

                    if (UploadFile.ExcelFile.ContentLength > 0)
                    {
                        if (UploadFile.ExcelFile.FileName.EndsWith(".xlsx") || UploadFile.ExcelFile.FileName.EndsWith(".xls"))
                        {
                            XLWorkbook Workbook;
                            Try//incase if the file is corrupt
                            {
                                Workbook = new XLWorkbook(UploadFile.ExcelFile.InputStream);
                            }
                            catch (Exception ex)
                            {
                                ModelState.AddModelError(String.Empty, $"Check your file. {ex.Message}");
                                return View();
                            }
                            IXLWorksheet WorkSheet = null;
                            Try//incase if the sheet you are looking for is not found
                            {
                                WorkSheet = Workbook.Worksheet("sheet1");

                            }
                            catch
                            {
                                ModelState.AddModelError(String.Empty, "sheet not found!");
                                return View();
                            }
                            WorkSheet.FirstRow().Delete();//if you want to remove ist row

                            foreach (var row in WorkSheet.RowsUsed())
                            {
                                //do something here
                                row.Cell(1).Value.ToString();//Get ist cell. 1 represent column number

                            }
                        }
                        else
                        {
                            ModelState.AddModelError(String.Empty, "Only .xlsx and .xls files are allowed");
                            return View();
                        }
                    }
                    else
                    {
                        ModelState.AddModelError(String.Empty, "Not a valid file");
                        return View();
                    }
                }
                return View();
            }
        }
    }

      

There are many examples in this link showing different ways to handle a variety of excel materials.

https://github.com/ClosedXML/ClosedXML/tree/9ac4d868a313f308b82e94617b9cc2d28baeb1c3/ClosedXML

View

@model ExcelUploadFileDemo.Models.UploadFile


@{
    ViewBag.Title = "Upload Excel File";
}
<h2>Upload an Excel File</h2>

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{

    @Html.AntiForgeryToken();

    <div class="form-horizontal">
        @Html.ValidationSummary("", new { @class = "text-danger" });
        <div class="form-group">
            @Html.LabelFor(model => model.ExcelFile, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.TextBoxFor(model => model.ExcelFile, new { type = "file", @class = "form-control" })
                @Html.ValidationMessageFor(model => model.ExcelFile, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type = "submit" value="Submit" class="btn btn-default" />
            </div>
        </div>
  </div>
}

      

+2


source


To read this data from an Excel file, you need to install a package ExcelDataReader

named ExcelDataReader

installation package ExcelDataReader

select V2.1.2.3

. Otherwise, sometimes I get an error with the following code.

1. Create a controller named ReadExcel

Index.cshtml

your view Index.cshtml

add the following line of code.

@{
    ViewBag.Title = "Read data from excel and view";
}

<h2>Read data from excel and view</h2>

@using (Html.BeginForm("Index", "ReadExcel", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken();
    @Html.ValidationSummary();

    <label class="text-info">Upload Excel File</label>
    <input type="file" class="form-control" name="uploadfile" id="uploadfile" />
    <input type="submit" value="submit" class="btn btn-default" />

    if (Model != null)
    {
        <table class="table table-responsive table-bordered">
            <thead>
                <tr>
                    @foreach(DataColumn column in Model.Columns)
                    {
                        <th>@column.ColumnName</th>
                    }
                </tr>
            </thead>
            <tbody>
                @foreach(DataRow row in Model.Rows)
                {
                    <tr>
                        @foreach(DataColumn col in Model.Columns)
                        {
                            <td>@row[col.ColumnName]</td>
                        }
                    </tr>
                }
            </tbody>
        </table>
    }
}

      

In your controller add the following piece of code.

public class ReadExcelController : Controller
    {
        // GET: ReadExcel
        public ActionResult Index()
        {
            return View();
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(HttpPostedFileBase uploadfile)
        {
            if (ModelState.IsValid)
            {
                if (uploadfile != null && uploadfile.ContentLength > 0)
                {
                    //ExcelDataReader works on binary excel file
                    Stream stream = uploadfile.InputStream;
                    //We need to written the Interface.
                    IExcelDataReader reader = null;
                    if (uploadfile.FileName.EndsWith(".xls"))
                    {
                        //reads the excel file with .xls extension
                        reader = ExcelReaderFactory.CreateBinaryReader(stream);
                    }
                    else if (uploadfile.FileName.EndsWith(".xlsx"))
                    {
                        //reads excel file with .xlsx extension
                        reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
                    }
                    else
                    {
                        //Shows error if uploaded file is not Excel file
                        ModelState.AddModelError("File", "This file format is not supported");
                        return View();
                    }
                    //treats the first row of excel file as Coluymn Names
                    reader.IsFirstRowAsColumnNames = true;
                    //Adding reader data to DataSet()
                    DataSet result = reader.AsDataSet();
                    reader.Close();
                    //Sending result data to View
                    return View(result.Tables[0]);
                }
            }
            else
            {
                ModelState.AddModelError("File","Please upload your file");
            }
            return View();
        }
    }

      

+2


source







All Articles