web-dev-qa-db-fra.com

Lire un fichier Excel chargé à l'aide de FileUpload Control sans l'enregistrer sur le serveur

Il faut pouvoir lire un fichier Excel chargé à l'aide de FileUploadControl dans ASP.NET. La solution sera hébergée sur un serveur. Je ne veux pas stocker le fichier Excel sur le serveur. Je voudrais convertir directement le contenu Excel en un ensemble de données ou un datatable et utiliser.

Vous trouverez ci-dessous les deux solutions que j'ai déjà trouvées mais qui ne fonctionneraient pas pour moi.

  1. LINQTOEXCEL - Cette méthode fonctionne lorsque vous avez un fichier Excel sur votre ordinateur local et que vous exécutez votre code sur l'ordinateur local. Dans mon cas, l'utilisateur essaie de télécharger un fichier Excel à partir de son ordinateur local à l'aide d'une page Web hébergée sur un serveur. 

  2. ExcelDataReader - J'utilise actuellement celui-ci, mais il s'agit d'un outil tiers. Je ne peux pas transférer ceci à notre client. De même, si une intersection ligne/colonne contient une formule, les données de cette intersection ligne/colonne ne sont pas lues dans le jeu de données.

La plupart des suggestions que j'ai trouvées sur Google et StackOverflow fonctionnent lorsque les solutions Excel et .NET se trouvent sur le même ordinateur. Mais dans le mien, j’ai besoin que cela fonctionne lorsque la solution est hébergée sur un serveur et que les utilisateurs essaient de télécharger Excel à l’aide de la page Web hébergée sur leur ordinateur local . ?

23
Chandra

Vous pouvez utiliser la propriété InputStream de HttpPostedFile pour lire le fichier en mémoire.

Voici un exemple qui montre comment créer une DataTable à partir du IO.Stream d'une HttpPostedFile en utilisant EPPlus:

protected void UploadButton_Click(Object sender, EventArgs e)
{
    if (FileUpload1.HasFile && Path.GetExtension(FileUpload1.FileName) == ".xlsx")
    {
        using (var Excel = new ExcelPackage(FileUpload1.PostedFile.InputStream))
        {
            var tbl = new DataTable();
            var ws = Excel.Workbook.Worksheets.First();
            var hasHeader = true;  // adjust accordingly
            // add DataColumns to DataTable
            foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
                tbl.Columns.Add(hasHeader ? firstRowCell.Text
                    : String.Format("Column {0}", firstRowCell.Start.Column));

            // add DataRows to DataTable
            int startRow = hasHeader ? 2 : 1;
            for (int rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
            {
                var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
                DataRow row = tbl.NewRow();
                foreach (var cell in wsRow)
                    row[cell.Start.Column - 1] = cell.Text;
                tbl.Rows.Add(row);
            }
            var msg = String.Format("DataTable successfully created from Excel-file. Colum-count:{0} Row-count:{1}",
                                    tbl.Columns.Count, tbl.Rows.Count);
            UploadStatusLabel.Text = msg;
        }
    }
    else 
    {
        UploadStatusLabel.Text = "You did not specify a file to upload.";
    }
}

Voici la version VB.NET:

Sub UploadButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
    If (FileUpload1.HasFile AndAlso IO.Path.GetExtension(FileUpload1.FileName) = ".xlsx") Then
        Using Excel = New ExcelPackage(FileUpload1.PostedFile.InputStream)
            Dim tbl = New DataTable()
            Dim ws = Excel.Workbook.Worksheets.First()
            Dim hasHeader = True ' change it if required '
            ' create DataColumns '
            For Each firstRowCell In ws.Cells(1, 1, 1, ws.Dimension.End.Column)
                tbl.Columns.Add(If(hasHeader,
                                   firstRowCell.Text,
                                   String.Format("Column {0}", firstRowCell.Start.Column)))
            Next
            ' add rows to DataTable '
            Dim startRow = If(hasHeader, 2, 1)
            For rowNum = startRow To ws.Dimension.End.Row
                Dim wsRow = ws.Cells(rowNum, 1, rowNum, ws.Dimension.End.Column)
                Dim row = tbl.NewRow()
                For Each cell In wsRow
                    row(cell.Start.Column - 1) = cell.Text
                Next
                tbl.Rows.Add(row)
            Next
            Dim msg = String.Format("DataTable successfully created from Excel-file Colum-count:{0} Row-count:{1}",
                                    tbl.Columns.Count, tbl.Rows.Count)
            UploadStatusLabel.Text = msg
        End Using
    Else
        UploadStatusLabel.Text = "You did not specify an Excel-file to upload."
    End If
End Sub

Par souci d'exhaustivité, voici l'aspx:

<div>
   <h4>Select a file to upload:</h4>

   <asp:FileUpload id="FileUpload1"                 
       runat="server">
   </asp:FileUpload>

   <br /><br />

   <asp:Button id="UploadButton" 
       Text="Upload file"
       OnClick="UploadButton_Click"
       runat="server">
   </asp:Button>    

   <hr />

   <asp:Label id="UploadStatusLabel"
       runat="server">
   </asp:Label>        
</div>
34
Rango
//Best Way To read file direct from stream
IExcelDataReader excelReader = null;
//file.InputStream is the file stream stored in memeory by any ways like by upload file control or from database
int excelFlag = 1; //this flag us used for execl file format .xls or .xlsx
if (excelFlag == 1)
{
    //1. Reading from a binary Excel file ('97-2003 format; *.xls)
    excelReader = ExcelReaderFactory.CreateBinaryReader(file.InputStream);
}
else if(excelFlag == 2)                                
{
    //2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
    excelReader = ExcelReaderFactory.CreateOpenXmlReader(file.InputStream);
}

if (excelReader != null)
{
    //...
    //3. DataSet - The result of each spreadsheet will be created in the result.Tables
    ds = excelReader.AsDataSet();
    //...
    ////4. DataSet - Create column names from first row
    //excelReader.IsFirstRowAsColumnNames = true;
    //DataSet result = excelReader.AsDataSet();

    ////5. Data Reader methods
    //while (excelReader.Read())
    //{
    //    //excelReader.GetInt32(0);
    //}

    //6. Free resources (IExcelDataReader is IDisposable)
    excelReader.Close();
}
2
Nilesh Nikumbh

Peut-être pourriez-vous jeter un coup d’œil à Koogra c’est un lecteur Excel Open Source (en lecture seule aucun écrivain). Je pense que vous obtiendrez un flux du client. Ensuite, vous pouvez faire toutes vos tâches comme vous le faites maintenant. Lisez à partir de memorystream et écrivez dans Database.

J'espère que ça aide.

0
Jordy van Eijk

Voici comment procéder dans MVC avec ClosedXML.Excel. Je sais que cette réponse est trop tard. Je voulais juste mettre cette réponse pour tous ceux qui atterrissent sur cette page après le problème googler. Dans Visual Studio, cliquez sur le menu Outils, développez NuGet Package Manager, puis lancez Package Manager console. Tapez la commande suivante:

Install-Package ClosedXML

Le modèle:

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

Le controlle:

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, "sheet1 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();
            }
        }
    }

Ce lien contient de nombreux exemples montrant différentes manières de gérer divers éléments d'Excel.

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

La vue

@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" }))
{



    <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>
}
0
Shah Aadil