关于.net:从C#读取Excel文件

关于.net:从C#读取Excel文件

Reading Excel files from C#

是否有免费或开放源代码库可直接从C#程序读取Excel文件(.xls)?

不必太花哨,只需选择一个工作表并以字符串形式读取数据。 到目前为止,我一直在使用Excel的"导出到Unicode文本"功能,并分析生成的(制表符分隔)文件,但是我想省去手动步骤。


1
2
3
4
5
6
7
8
9
var fileName = string.Format("{0}\\fileNameHere", Directory.GetCurrentDirectory());
var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", fileName);

var adapter = new OleDbDataAdapter("SELECT * FROM [workSheetNameHere$]", connectionString);
var ds = new DataSet();

adapter.Fill(ds,"anyNameHere");

DataTable data = ds.Tables["anyNameHere"];

这就是我通常使用的。这有点不同,因为我通常在表的编辑中粘贴一个AsEnumerable():

1
var data = ds.Tables["anyNameHere"].AsEnumerable();

因为这使我可以使用LINQ从字段中搜索和构建结构。

1
2
3
4
5
6
7
var query = data.Where(x => x.Field<string>("phoneNumber") != string.Empty).Select(x =>
                new MyContact
                    {
                        firstName= x.Field<string>("First Name"),
                        lastName = x.Field<string>("Last Name"),
                        phoneNumber =x.Field<string>("Phone Number"),
                    });

如果只是Excel文件中包含的简单数据,则可以通过ADO.NET读取数据。请参见此处列出的连接字符串:

http://www.connectionstrings.com/?carrier=excel2007
要么
http://www.connectionstrings.com/?carrier=excel

-Ryan

更新:然后您可以通过类似select * from [Sheet1$]的方式阅读工作表


ADO.NET方法快速简便,但是您需要注意一些怪癖,特别是关于如何处理数据类型。

这篇出色的文章将帮助您避免一些常见的陷阱:
http://blog.lab49.com/archives/196


这是我用于Excel 2003的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Dictionary<string, string> props = new Dictionary<string, string>();
props["Provider"] ="Microsoft.Jet.OLEDB.4.0";
props["Data Source"] = repFile;
props["Extended Properties"] ="Excel 8.0";

StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> prop in props)
{
    sb.Append(prop.Key);
    sb.Append('=');
    sb.Append(prop.Value);
    sb.Append(';');
}
string properties = sb.ToString();

using (OleDbConnection conn = new OleDbConnection(properties))
{
    conn.Open();
    DataSet ds = new DataSet();
    string columns = String.Join(",", columnNames.ToArray());
    using (OleDbDataAdapter da = new OleDbDataAdapter(
       "SELECT" + columns +" FROM [" + worksheet +"$]", conn))
    {
        DataTable dt = new DataTable(tableName);
        da.Fill(dt);
        ds.Tables.Add(dt);
    }
}


Excel Data Reader怎么样?

http://exceldatareader.codeplex.com/

我曾在生产环境中使用它来将大量数据从各种Excel文件中提取到SQL Server Compact中。它工作得很好,并且非常健壮。


这是几年前我使用.NET 1.1在C#中编写的一些代码。不知道这是否正是您所需要的(可能不是我最好的代码:)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using System;
using System.Data;
using System.Data.OleDb;

namespace ExportExcelToAccess
{
    /// <summary>
    /// Summary description for ExcelHelper.
    /// </summary>
    public sealed class ExcelHelper
    {
        private const string CONNECTION_STRING ="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<FILENAME>;Extended Properties="Excel 8.0;HDR=Yes;";";

        public static DataTable GetDataTableFromExcelFile(string fullFileName, ref string sheetName)
        {
            OleDbConnection objConnection = new OleDbConnection();
            objConnection = new OleDbConnection(CONNECTION_STRING.Replace("<FILENAME>", fullFileName));
            DataSet dsImport = new DataSet();

            try
            {
                objConnection.Open();

                DataTable dtSchema = objConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

                if( (null == dtSchema) || ( dtSchema.Rows.Count <= 0 ) )
                {
                    //raise exception if needed
                }

                if( (null != sheetName) && (0 != sheetName.Length))
                {
                    if( !CheckIfSheetNameExists(sheetName, dtSchema) )
                    {
                        //raise exception if needed
                    }
                }
                else
                {
                    //Reading the first sheet name from the Excel file.
                    sheetName = dtSchema.Rows[0]["TABLE_NAME"].ToString();
                }

                new OleDbDataAdapter("SELECT * FROM [" + sheetName +"]", objConnection ).Fill(dsImport);
            }
            catch (Exception)
            {
                //raise exception if needed
            }
            finally
            {
                // Clean up.
                if(objConnection != null)
                {
                    objConnection.Close();
                    objConnection.Dispose();
                }
            }


            return dsImport.Tables[0];
            #region Commented code for importing data from CSV file.
            //              string strConnectionString ="Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source=" + System.IO.Path.GetDirectoryName(fullFileName) +";" +"Extended Properties="Text;HDR=YES;FMT=Delimited"";
            //
            //              System.Data.OleDb.OleDbConnection conText = new System.Data.OleDb.OleDbConnection(strConnectionString);
            //              new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM" + System.IO.Path.GetFileName(fullFileName).Replace(".","#"), conText).Fill(dsImport);
            //              return dsImport.Tables[0];

            #endregion
        }

        /// <summary>
        /// This method checks if the user entered sheetName exists in the Schema Table
        /// </summary>
        /// <param name="sheetName">Sheet name to be verified</param>
        /// <param name="dtSchema">schema table </param>
        private static bool CheckIfSheetNameExists(string sheetName, DataTable dtSchema)
        {
            foreach(DataRow dataRow in dtSchema.Rows)
            {
                if( sheetName == dataRow["TABLE_NAME"].ToString() )
                {
                    return true;
                }  
            }
            return false;
        }
    }
}

Koogra是一个用C#编写的开源组件,可以读取和写入Excel文件。


虽然您确实确实要求.xls,这意味着较旧的文件格式,但对于OpenXML格式(例如xlsx),我强烈建议您使用OpenXML SDK(http://msdn.microsoft.com/zh-cn/library/bb448854.aspx)


前一段时间,我从C#中的Excel文件中进行了大量读取,我们使用了两种方法:

  • COM API,您可以在其中直接访问Excel的对象并通过方法和属性对其进行操作
  • 允许像数据库一样使用Excel的ODBC驱动程序。

后一种方法要快得多:通过COM读取具有20列和200行的大表将花费30秒,而通过ODBC则需要半秒。因此,如果您需要的只是数据,我建议使用数据库方法。

干杯,

卡尔


ExcelMapper是一种开放源代码工具(http://code.google.com/p/excelmapper/),可用于将Excel工作表作为强类型对象读取。它支持xls和xlsx格式。


我想展示一种使用.NET读取xls / xlsx文件的简单方法。希望以下内容对您有所帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 private DataTable ReadExcelToTable(string path)    
 {

     //Connection String

     string connstring ="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path +";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';";  
     //the same name
     //string connstring = Provider=Microsoft.JET.OLEDB.4.0;Data Source=" + path + //";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';";

     using(OleDbConnection conn = new OleDbConnection(connstring))
     {
        conn.Open();
        //Get All Sheets Name
        DataTable sheetsName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,new object[]{null,null,null,"Table"});  

        //Get the First Sheet Name
        string firstSheetName = sheetsName.Rows[0][2].ToString();

        //Query String
        string sql = string.Format("SELECT * FROM [{0}]",firstSheetName);
        OleDbDataAdapter ada =new OleDbDataAdapter(sql,connstring);
        DataSet set = new DataSet();
        ada.Fill(set);
        return set.Tables[0];  
   }
 }

代码来自文章:http://www.c-sharpcorner.com/uploadfile/d2dcfc/read-excel-file-with-net/。您可以从中获取更多详细信息。


它不是免费的,但是使用最新的Office会有一个非常不错的自动化.Net API。 (已经存在API已有很长时间了,但是它却是令人讨厌的COM),而Office应用程序仍然是一个隐藏的后台进程,则可以在代码中完成所有想要/需要的事情。


如果我不在这里,请原谅我,但这不是Office PIA的目的吗?


SmartXLS是另一个excel电子表格组件,它支持excel图表的大多数功能,公式引擎,并且可以读取/写入excel2007 openxml格式。


SpreadsheetGear for .NET是Excel兼容的.NET电子表格组件。您可以在我们产品页面的右侧看到客户对性能的评价。您可以免费试用功能齐全的评估版。


.NET组件Excel Reader .NET可能满足您的要求。足以读取XLSX和XLS文件。因此,请尝试以下方法:

http://www.devtriogroup.com/ExcelReader


最近,部分是为了使LINQ更好。...我一直在使用Excel的自动化API将文件保存为XML Spreadsheet,然后使用LINQ to XML处理该文件。


我建议使用FileHelpers库,它是一个免费且易于使用的.NET库,用于从EXCEL,文件中的定长或定界记录,字符串或流中导入/导出数据,字符串或流以及更多内容。

Excel数据链接文档部分
http://filehelpers.sourceforge.net/example_exceldatalink.html


如果只是表格数据。我会推荐Marcos Melli提供的文件数据助手,可以在这里下载。


我们使用的解决方案需要:

  • 允许读取/写入Excel产生的文件
  • 性能快速(不像使用COM)
  • 是独立于MS Office的(需要在没有安装MS Office的客户端的情况下可用)
  • 是免费的还是开源的(但积极开发)

有多种选择,但是我们发现NPoi(Java长期存在的Poi开源项目的.NET端口)是最好的:
http://npoi.codeplex.com/

它还允许使用.doc和.ppt文件格式


SpreadsheetGear很棒。是的,这是一种支出,但与花钱与其他解决方案相比,这是值得的。它快速,可靠,非常全面,我不得不说在我的全职软件工作中使用该产品一年半之后,他们的客户支持非常棒!


晚了聚会,但我是LinqToExcel的粉丝


您可以尝试使用此开放源代码解决方案,该解决方案使与Excel的处理更加简洁。

http://excelwrapperdotnet.codeplex.com/


您可以编写一个Excel电子表格,该电子表格可以加载给定的Excel电子表格并将其保存为csv(而不是手动执行)。

那么您可以通过c#将其自动化。

并且一旦在csv中,C#程序就可以解决该问题。

(同样,如果有人要求您使用excel编程,最好假装您不知道如何操作)

(编辑:是的,抢劫和瑞安都是对的)


Take.io电子表格将为您免费完成此工作。看看这个。


刚刚做了一个快速演示项目,需要管理一些excel文件。来自GemBox软件的.NET组件足以满足我的需求。它有一个免费版本,但有一些限制。

http://www.gemboxsoftware.com/GBSpreadsheet.htm


Excel Package是用于读取/写入Excel 2007文件的开源(GPL)组件。我在一个小项目上使用了它,API很简单。仅适用于XLSX(Excel 200&),不适用于XLS。

源代码看起来也井井有条,易于解决(如果您需要像我一样扩展功能或解决小问题)。

最初,我尝试使用ADO.Net(Excel连接字符串)方法,但是这种方法充满了讨厌的骇客-例如,如果第二行包含数字,它将为下面列中的所有字段返回整数,并静默删除任何数据那不合适。


我们在相当大的系统中使用ClosedXML。

  • 自由
  • 易于安装
  • 直接编码
  • 响应迅速的支持
  • 开发人员团队非常乐意接受新建议。通常会在一周内实施新功能和错误修复

我知道人们已经为此目的进行了Excel"扩展"。
您或多或少在Excel中创建一个按钮,显示"导出到程序X",然后以程序可以读取的格式导出并发送数据。

http://msdn.microsoft.com/zh-cn/library/ms186213.aspx应该是一个不错的起点。

祝好运


Excel Data Reader是必经之路!

它是开放源代码,位于http://exceldatareader.codeplex.com/,并得到积极开发。

几年来(在财务应用程序中),我们一直在使用它来阅读表格(有时不是表格)工作表。

就像一种魅力一样,可以从人类可读的工作表中读取单元测试数据。

只需避免尝试返回DateTime的功能,因为对于Excel,DateTime只是双精度数。


我只是使用ExcelLibrary将.xls电子表格加载到DataSet中。对我来说很棒。


如果同一工作表中有多个表,则可以给每个表一个对象名,并使用OleDb方法读取该表,如下所示:http://vbktech.wordpress.com/2011/05/10/c-net-reading -and写作与多桌,在最同微软的Excel工作表/


推荐阅读