有没有一个免费或开源的库可以直接从C#程序读取Excel文件(.xls)?
它不需要太花哨,只需要选择一个工作表并将数据作为字符串读取。到目前为止,我一直在使用Excel的导出Unicode文本功能,并解析生成的(制表符分隔的)文件,但我想消除手动步骤。
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():
var data = ds.Tables["anyNameHere"].AsEnumerable();
这让我可以使用LINQ来搜索和从字段构建结构体。
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"),
});
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 中使用的内容:
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#代码。不确定这是否正好是你所需要的(也许不是我最好的代码 :))。
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;
}
}
}
虽然你明确要求使用.xls,暗示使用较旧的文件格式,但对于OpenXML格式(例如.xlsx),我强烈推荐使用OpenXML SDK (http://msdn.microsoft.com/en-us/library/bb448854.aspx)。
我之前在C#中读取Excel文件的时候做了很多阅读,我们采用了两种方法:
后一种方法要快得多:通过COM读取具有20列和200行的大表需要30秒钟,而通过ODBC只需要半秒钟。因此,如果您只需要数据,则建议使用数据库方法。
谢谢,
Carl
ExcelMapper 是一个开源工具 (http://code.google.com/p/excelmapper/),可以将 Excel 工作表读取为强类型对象。 它支持 xls 和 xlsx 格式。
xlsx
文件,则需要使用以下连接字符串:string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", fileName)
。 - Andreas Grech