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

问题描述 投票:57回答:5

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

  • Iterop
  • Oledb
  • Open Xml SDK

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

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

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

使用操作结果更新DataTable

把它写回excel file

哪个更简单。

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

c# excel oledb openxml-sdk excel-interop
5个回答
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;

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


20
投票

使用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);
    }                        
    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;\"");
}

对于较新的Excel版本:

return new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filename + ";Extended Properties=Excel 12.0;");

您还可以在CodePlex上使用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();

参考:How do I import from Excel to a DataSet using Microsoft.Office.Interop.Excel?


7
投票

我意识到这个问题是在大约7年前被问到的,但对于使用C#导入Excel数据的某些关键字,它仍然是谷歌的搜索结果,所以我想根据最近的一些技术发展提供替代方案。

导入Excel数据已经成为我日常工作中的一项常见任务,我已经简化了流程并在我的博客上记录了该方法:best way to read excel file in c#

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

但真正的魔力来自于与NPOI Mapper from Donny Tian配对,因为它允许我将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];
                }
            }
        }

请注意,如果我愿意,它允许我根据列名进行映射!

然后当我处理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();
        }

现在,诚然,我的代码不会修改Excel文件本身。我使用Entity Framework将数据保存到数据库(这就是为什么你在我的例子中看到“UpdateUser”和“SaveChanges”)。但是关于如何使用save/modify a file using NPOI已经有了很好的讨论。


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

3
投票

如果你可以将它限制为(Open Office XML格式)* .xlsx文件,那么最受欢迎的库可能是EPPLus

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

Install-Package EPPlus

1
投票

就个人而言,我发现开源和免费的ExcelMapper最容易使用。

与通常的Microsoft.Interop和OLE查询相比,它提供了一种更简洁(即可读)的Excel文件阅读方式。

1.给出一个Excel文件:

enter image description here

2.创建一个Person C#对象:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}

3.使用ExcelMapper读取它

  var fileName = @"C:\Temp\Names.xlsx"; // your excel file
  List<Person> people = new ExcelMapper(fileName).Fetch<Person>();

您还可以通过传入其他工作表参数从其他工作表中读取:

  var fileName = @"C:\Temp\Names.xlsx"; // your excel file
  List<Person> people = new ExcelMapper(fileName).Fetch<Person>("Sheet2");

您可以使用NuGet安装它

Install-Package ExcelMapper

免责声明:我与ExcelMapper无关,但在尝试了各种不同的库之后,我发现这个库最容易使用。

instructional video - how to read excel files in c#这是一个简短的video,展示了上述内容。


0
投票

尝试使用Aspose.cells库,它非常好。

Install-package Aspose.cells

有示例代码:

using Aspose.Cells;
using System;

namespace ExcelReader
{
    class Program
    {
        static void Main(string[] args)
        {
            // Replace path for your file
            readXLS(@"C:\MyExcelFile.xls"); // or "*.xlsx"
            Console.ReadKey();
        }

        public static void readXLS(string PathToMyExcel)
        {
            //Open your template file.
            Workbook wb = new Workbook(PathToMyExcel);

            //Get the first worksheet.
            Worksheet worksheet = wb.Worksheets[0];

            //Get cells
            Cells cells = worksheet.Cells;

            // Get row and column count
            int rowCount = cells.MaxDataRow;
            int columnCount = cells.MaxDataColumn;

            // Current cell value
            string strCell = "";

            Console.WriteLine(String.Format("rowCount={0}, columnCount={1}", rowCount, columnCount));

            for (int row = 0; row <= rowCount; row++) // Numeration starts from 0 to MaxDataRow
            {
                for (int column = 0; column <= columnCount; column++)  // Numeration starts from 0 to MaxDataColumn
                {
                    strCell = "";
                    strCell = Convert.ToString(cells[row, column].Value);
                    if (String.IsNullOrEmpty(strCell))
                    {
                        continue;
                    }
                    else
                    {
                        // Do your staff here
                        Console.WriteLine(strCell);
                    }
                }
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.