如何从文件输入中读取excel文件而不将文件保存到服务器

时间:2014-03-06 02:07:07

标签: c# sql excel

我收到一个客户已上传到服务器的Excel文件,我正在查看的所有示例都显示了如何保存然后阅读它。

我需要做的是从网页和/或FileReader接收excel文件,并将其保存到数据表中,其中列名保留在Excel工作表的第一行。

下面的代码完全符合我的要求,但它没有说明如何将文件读入数据表而不先将其保存到存储中。

我需要保存excel文件并对其进行处理以确保所有列名都正确并且每行中的数据都是正确的,在我处理完这些信息后,我将开始将其保存到sql数据库的过程

如何在保留列名的同时将Excel文件保存为数据流?

**注意表名不重要,我只处理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 个答案:

答案 0 :(得分:1)

You can do this using EPPlus with something like the following:

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

The only issue is you are not reading any kind of schema from the imported file so you don't get any types (the above example ends up with each row filled with general object type).

If you need a strongly typed data table and you know in advance the type of columns you need in the DataTable then you can switch out the line creating the columns. For Example:

dataTable.Columns.Add(cell.Value.ToString(),typeof(int));

If you don't know in advance the types of column and still need the strongly typed table then I guess you could kludge something using the cell's Style.Numberformat property to decide which type to pass into the column contructor.