如何在不将文件保存到服务器的情况下从文件输入中读取Excel文件

3
我收到了一个由客户上传到服务器的Excel文件,所有我看到的例子都展示了如何保存并读取它。
我需要做的是从网页或FileReader接收Excel文件,并将其保存到DataTable中,其中列名保留为Excel表格的第一行。
以下代码正是我所需要的,但它没有展示如何在不先将文件保存到存储器中的情况下将其读入数据表中。
我需要保存Excel文件并处理它,以确保所有列名和每行中的数据都是正确的。处理完这些信息后,我将开始将其保存到SQL数据库的过程。
如何将Excel文件保存为流并将其保留列名保存到DataTable中呢?
**请注意,表名并不重要,我只会处理Excel簿中的第一个工作表,最重要的是每行的列名和数据类型。
代码引用自:http://www.aspsnippets.com/Articles/Read-and-Import-Excel-File-into-DataSet-or-DataTable-using-C-and-VBNet-in-ASPNet.aspx
using System;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Configuration; 

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void btnUpload_Click(object sender, EventArgs e)
    {
        if (FileUpload1.HasFile)
        {
            string FileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
            string Extension = Path.GetExtension(FileUpload1.PostedFile.FileName);
            string FolderPath = ConfigurationManager.AppSettings["FolderPath"];

            string FilePath = Server.MapPath(FolderPath + FileName);
            FileUpload1.SaveAs(FilePath);
            Import_To_Grid(FilePath, Extension, rbHDR.SelectedItem.Text);
        }
    }
    private void Import_To_Grid(string FilePath, string Extension, string isHDR)
    {
        string conStr="";
        switch (Extension)
        {
            case ".xls": //Excel 97-03
                conStr = ConfigurationManager.ConnectionStrings["Excel03ConString"].ConnectionString;
                break;
            case ".xlsx": //Excel 07
                conStr = ConfigurationManager.ConnectionStrings["Excel07ConString"].ConnectionString;
                break;
        }
        conStr = String.Format(conStr, FilePath, isHDR);
        OleDbConnection connExcel = new OleDbConnection(conStr);
        OleDbCommand cmdExcel = new OleDbCommand();
        OleDbDataAdapter oda = new OleDbDataAdapter();
        DataTable dt = new DataTable(); 
        cmdExcel.Connection = connExcel;

        //Get the name of First Sheet
        connExcel.Open();
        DataTable dtExcelSchema;
        dtExcelSchema = connExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
        string SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
        connExcel.Close();

        //Read Data from First Sheet
        connExcel.Open();
        cmdExcel.CommandText = "SELECT * From [" + SheetName + "]";
        oda.SelectCommand = cmdExcel;
        oda.Fill(dt);
        connExcel.Close(); 

        //Bind Data to GridView
        GridView1.Caption = Path.GetFileName(FilePath); 
        GridView1.DataSource = dt;
        GridView1.DataBind();
    }
1个回答

1
你可以使用 EPPlus 来实现这个,代码如下所示:
protected void btnUpload_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {
        DataTable dataTable = new DataTable();
        using (MemoryStream mStream = new MemoryStream(fileContents))
        {
            using (var excelPackage = new ExcelPackage(mStream))
            {
                ExcelWorksheet firstSheet = excelPackage.Workbook.Worksheets.First();
                var endAddress = firstSheet.Dimension.End;
                dataTable.TableName = firstSheet.Name;
                ExcelRange headerRange = firstSheet.Cells[1, 1, 1,endAddress.Column ];

                //Add columns using headers
                foreach (var cell in headerRange)
                {
                    dataTable.Columns.Add(cell.Value.ToString()); //You can hardcode whatever type you need to here
                }

                //Add Data:
                for (int rowIdx = 2; rowIdx <= endAddress.Row; rowIdx++)
                {
                    DataRow dataRow = dataTable.NewRow();
                    for (int colIdx = 1; colIdx <= endAddress.Column; colIdx++)
                    {
                        dataRow[colIdx - 1] = firstSheet.Cells[rowIdx, colIdx].Value;
                    }
                    dataTable.Rows.Add(dataRow);
                }
            }
        }
        //Now Do whatever you want with your DataTable:
        GridView1.DataSource = dataTable;
        GridView1.DataBind();
    }
}

唯一的问题是您没有从导入的文件中读取任何类型的模式,因此您不会得到任何类型(上面的示例最终会导致每行都填充了通用的object类型)。
如果您需要一个强类型的数据表,并且您事先知道在DataTable中需要哪些列的类型,则可以切换创建列的行。例如:
dataTable.Columns.Add(cell.Value.ToString(),typeof(int));

如果您事先不知道列的类型,但仍需要强类型表格,那么我猜您可以使用单元格的Style.Numberformat属性来决定传递到列构造函数中的类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接