读取Excel文件的最佳方法(.xls/.xlsx)

Ank*_*esh 65 c# oledb excel excel-interop openxml-sdk

我知道有不同的方法来读取Excel文件:

  • Iterop
  • Oledb
  • Open Xml SDK

兼容性不是问题,因为程序将在受控环境中执行.

我的要求:
将文件读取到DataTable/ CUstom Entities(我不知道如何为对象创建动态属性/字段[列名将在Excel文件中变化])

用于DataTable/Custom Entities使用其数据执行某些操作.

更新DataTable操作结果

把它写回去excel file.

哪个更简单.

如果可能的话,请告诉我自定义实体(动态地向对象添加属性/字段)

Eni*_*ity 64

看看Linq-to-Excel.它非常整洁.

var book = new LinqToExcel.ExcelQueryFactory(@"File.xlsx");

var query =
    from row in book.Worksheet("Stock Entry")
    let item = new
    {
        Code = row["Code"].Cast<string>(),
        Supplier = row["Supplier"].Cast<string>(),
        Ref = row["Ref"].Cast<string>(),
    }
    where item.Supplier == "Walmart"
    select item;
Run Code Online (Sandbox Code Playgroud)

它还允许强类型的行访问.

  • 和Access数据库引擎,虽然微软是另一个依赖. (9认同)
  • @fschricker - 只有两个 - "log4net"和"Remotion". (5认同)
  • 不要成为'巨魔'......但是......如果有人在考虑使用它.您可以"可能"使用它的唯一地方是您自己的桌面.没有人会让你在客户端桌面或Web服务器上安装"访问数据库引擎"...许多地方(有充分理由)甚至不允许你在本地安装这样的东西.再次,我喜欢语法,我喜欢这个想法......但这不是一个广泛可行的解决方案.还是......非常酷. (5认同)
  • 请注意,Linq-to-Excel使用第三方库列表. (4认同)
  • 虽然很好......但由于"Access数据库引擎",这不是一个可行的生产资产. (3认同)
  • @kevinc - 确实如此。但为什么要提到呢?OP 没有询问可移植性。 (2认同)

Fur*_*dar 23

使用OLE查询,它非常简单(例如sheetName是Sheet1 $):

DataTable LoadWorksheetInDataTable(string fileName, string sheetName)
{           
    DataTable sheetData = new DataTable();
    using (OleDbConnection conn = this.returnConnection(fileName))
    {
       conn.Open();
       // retrieve the data using data adapter
       OleDbDataAdapter sheetAdapter = new OleDbDataAdapter("select * from [" + sheetName + "$]", conn);
       sheetAdapter.Fill(sheetData);
       conn.Close();
    }                        
    return sheetData;
}

private OleDbConnection returnConnection(string fileName)
{
    return new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + "; Jet OLEDB:Engine Type=5;Extended Properties=\"Excel 8.0;\"");
}
Run Code Online (Sandbox Code Playgroud)

对于较新的Excel版本:

return new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=Excel 12.0;");
Run Code Online (Sandbox Code Playgroud)

您还可以在ExcelP上使用Excel Data Reader作为开源项目.它的工作非常适合从Excel工作表导出数据.

指定链接上给出的示例代码:

FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);

//1. Reading from a binary Excel file ('97-2003 format; *.xls)
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
//...
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = 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();
Run Code Online (Sandbox Code Playgroud)

参考:如何使用Microsoft.Office.Interop.Excel从Excel导入DataSet?

  • `this.returnConnection(fileName)`的代码在哪里? (4认同)

Dan*_*Dan 10

我意识到这个问题是在将近7年前提出的,但是对于某些有关使用C#导入excel数据的关键字,它仍然是Google排名最高的搜索结果,因此我想根据最近的一些技术发展提供一个替代方案。

导入Excel数据已成为我日常工作中的一项常见任务,因此我简化了流程并在博客上记录了该方法:在c#中读取excel文件的最佳方法

我使用NPOI是因为它可以在未安装Microsoft Office的情况下读取/写入Excel文件,并且不使用COM +或任何互操作。这意味着它可以在云中工作!

但是真正的魔力来自与Donny Tian的 NPOI Mapper的配对,因为它使我无需编写任何代码即可将Excel列映射到C#类中的属性。很美丽。

这是基本思想:

我创建一个.net类来匹配/映射我感兴趣的Excel列:

        class CustomExcelFormat
        {
            [Column("District")]
            public int District { get; set; }

            [Column("DM")]
            public string FullName { get; set; }

            [Column("Email Address")]
            public string EmailAddress { get; set; }

            [Column("Username")]
            public string Username { get; set; }

            public string FirstName
            {
                get
                {
                    return Username.Split('.')[0];
                }
            }

            public string LastName
            {
                get
                {
                    return Username.Split('.')[1];
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

注意,如果需要,它允许我基于列名进行映射!

然后,当我处理excel文件时,我需要做的就是这样:

        public void Execute(string localPath, int sheetIndex)
        {
            IWorkbook workbook;
            using (FileStream file = new FileStream(localPath, FileMode.Open, FileAccess.Read))
            {
                workbook = WorkbookFactory.Create(file);
            }

            var importer = new Mapper(workbook);
            var items = importer.Take<CustomExcelFormat>(sheetIndex);
            foreach(var item in items)
            {
                var row = item.Value;
                if (string.IsNullOrEmpty(row.EmailAddress))
                    continue;

                UpdateUser(row);
            }

            DataContext.SaveChanges();
        }
Run Code Online (Sandbox Code Playgroud)

现在,坦率地说,我的代码不会修改Excel文件本身。我改为使用Entity Framework将数据保存到数据库中(这就是为什么在我的示例中看到“ UpdateUser”和“ SaveChanges”的原因)。但是,关于SO如何使用NPOI保存/修改文件已经有很好的讨论。

  • 这就像一个魅力!迄今为止最简单的解决方案。两者均以 NuGet 包形式提供。 (2认同)

小智 6

尝试使用这种免费方式,https://freenetexcel.codeplex.com

 Workbook workbook = new Workbook();

 workbook.LoadFromFile(@"..\..\parts.xls",ExcelVersion.Version97to2003);
 //Initialize worksheet
 Worksheet sheet = workbook.Worksheets[0];

 DataTable dataTable = sheet.ExportDataTable();
Run Code Online (Sandbox Code Playgroud)


dav*_*ere 5

如果您可以将其限制为(Open Office XML 格式)*.xlsx 文件,那么最流行的库可能是EPPLus

奖励是,没有其他依赖项。只需使用nuget安装:

Install-Package EPPlus
Run Code Online (Sandbox Code Playgroud)