web-dev-qa-db-ja.com

サーバーに保存せずにFileUploadコントロールを使用してアップロードされたExcelファイルを読み取る

ASP.NETのFileUploadControlを使用してアップロードされたExcelファイルを読み取ることができる必要があります。ソリューションはサーバーでホストされます。 Excelファイルをサーバーに保存したくありません。 Excelコンテンツをデータセットまたはデータテーブルに直接変換して利用したい

以下は、私がすでに見つけたが私には役に立たない2つのソリューションです。

  1. LINQTOEXCEL-この方法は、ローカルマシンにExcelファイルがあり、ローカルマシンでコードを実行している場合に機能します。私の場合、ユーザーはサーバーでホストされているWebページを使用して、ローカルマシンからExcelファイルをアップロードしようとしています。

  2. ExcelDataReader-現在これを使用していますが、これはサードパーティのツールです。これをお客様に移動することはできません。また、行/列の交点に数式が含まれている場合、その行/列の交点のデータはデータセットに読み込まれません。

GoogleとStackOverflowで見つけた提案のほとんどは、Excelと.NETソリューションの両方が同じマシン上にあるときに機能します。しかし、私の場合、ソリューションがサーバーでホストされ、ユーザーがローカルマシン上のホストされたWebページを使用してExcelをアップロードしようとしているときに動作する必要があります。他に提案があれば、教えてください。

25
Chandra

InputStreamの-​​ HttpPostedFile プロパティを使用して、ファイルをメモリに読み込むことができます。

DataTableを使用して、HttpPostedFileIO.Streamから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.";
    }
}

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

完全を期すために、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>
35
Tim Schmelter
//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

多分あなたは Koogra を見てみることができます。これはオープンソースのExcelリーダーです(読み取り専用でライターはありません)。クライアントからストリームを取得できると思います。そうすれば、今やっているようにすべてのことができます。メモリストリームから読み取り、データベースに書き込みます。

これがお役に立てば幸いです。

0
Jordy van Eijk

これは、ClosedXML.Excelを使用してMVCでこれを行う方法です。私はこの答えが遅すぎることを知っています。グーグルの問題の後にこのページにアクセスしたすべての人にこの答えを付けたかっただけです。 Visual Studioでツールメニューをクリックし、NuGetパッケージマネージャーを展開して、パッケージマネージャーコンソールを実行します。次のコマンドを入力します。

Install-Package ClosedXML

モデル:

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

コントローラー:

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

このリンクには、Excelのさまざまなものを処理するさまざまな方法を示す多くの例があります。

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

景色

@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