ExcelDataReader
轻量级和快速库编写的C#读取Microsoft Excel文件(2.0-2021,365)。
请随时向叉子提交拉动请求,向开发分支提交。
如果您要报告一个问题,如果您可以提供示例Excel文件,那么这确实有用,因为这会使调试变得更加容易,并且没有它,我们可能无法解决任何问题。
连续整合
| 分支 | 建立状态 |
|---|---|
| 发展 | |
| 掌握 |
支持的文件格式和版本
| 文件类型 | 容器格式 | 文件格式 | Excel版本 |
|---|---|---|---|
| .xlsx | ZIP,CFB+ZIP | OpenXML | 2007年和更新 |
| .xlsb | Zip,CFB | OpenXML | 2007年和更新 |
| .xls | CFB | Biff8 | 97,2000,XP,2003年 98,2001,VX,2004(MAC) |
| .xls | CFB | Biff5 | 5.0,95 |
| .xls | – | Biff4 | 4.0 |
| .xls | – | Biff3 | 3.0 |
| .xls | – | Biff2 | 2.0,2.2 |
| .csv | – | CSV | (全部) |
找到二进制文件
建议通过VS软件包管理台Install-Package <package>使用Nuget或使用VS“管理Nuget软件包…”扩展名。
从ExcelDataReader版本3.0开始,该项目被分为多个软件包:
安装ExcelDataReader基本软件包以使用“低级”读取器接口。与Net462,NetStandard2.0和NetStandard2.1兼容。
安装ExcelDataReader .DataSet扩展程序包以使用AsDataSet()方法填充System.Data.DataSet 。这也将拉入基本包。与Net462,NetStandard2.0和NetStandard2.1兼容。
如何使用
using ( var stream = File . Open ( filePath , FileMode . Open , FileAccess . Read ) ) { // Auto-detect format, supports: // - Binary Excel files (2.0-2003 format; *.xls) // - OpenXml Excel files (2007 format; *.xlsx, *.xlsb) using ( var reader = ExcelReaderFactory . CreateReader ( stream ) ) { // Choose one of either 1 or 2: // 1. Use the reader methods do { while ( reader . Read ( ) ) { // reader.GetDouble(0); } } while ( reader . NextResult ( ) ) ; // 2. Use the AsDataSet extension method var result = reader . AsDataSet ( ) ; // The result of each spreadsheet is in result.Tables } }
读取.csv文件
使用ExcelReaderFactory.CreateCsvReader而不是CreateReader来解析具有逗号分隔值的纯文本。
另请参阅配置选项FallbackEncoding和AutodetectSeparators 。
输入CSV总是一次完全解析,以设置FieldCount,RowCount,编码,分离器(如果CSV缺乏BOM而不是UTF8,则两次),然后在迭代行记录时再次解析。 throws System.Text.DecoderFallbackException如果输入无法用指定的编码解析。
读者将所有CSV字段值作为字符串返回,并且没有尝试将数据转换为数字或日期。该呼叫者负责解释CSV数据。
使用阅读器方法
AsDataSet()扩展方法是快速获取数据的方便助手,但并非总是可用或可取的。我ExcelDataReader扩展了System.Data.IDataReader和IDataRecord Interfaces,以较低级别导航和检索数据。最重要的读取器方法和属性:
| 方法 | 财产 |
|---|---|
Read() |
从当前表读取一行。 |
NextResult()
|
将光标推向下一张纸。 |
ResultsCount
|
返回当前工作簿中的床单。 |
Name
|
返回当前表的名称。 |
CodeName
|
返回当前表的VBA代码名称标识符。 |
FieldCount
|
返回当前表中的列数。 |
RowCount
|
返回当前表中的行数。这包括终端空行,否则这些行被Asdataset()排除在外。与AnalyzeInitialCsvRows一起使用时,在CSV文件上抛出InvalidOperationException 。 |
HeaderFooter
|
返回一个具有有关标头和页脚的信息的对象,或者如果没有的话,则null 。 |
MergeCells
|
返回当前表中合并的单元格范围。 |
RowHeight
|
返回当前行的视觉高度。如果隐藏行,则可能是0。 |
GetColumnWidth()
|
返回字符单元中的列的宽度。如果列隐藏,则可能是0。 |
GetFieldType()
|
返回当前行中值的类型。如果没有值,则始终是Excel支持的类型之一: double , int , bool , DateTime , TimeSpan , string或null 。 |
IsDBNull()
|
检查当前行中的值是否为null。 |
GetValue()
|
从当前行返回一个值作为object ,如果没有值,则null 。 |
GetDouble()GetInt32()GetBoolean()GetDateTime()GetString()
|
从当前行铸造的值返回其各自类型。 |
GetNumberFormatString()
|
返回一个包含格式代码的字符串,用于当前行中的值,如果没有值,则返回null 。另请参见下面的格式部分。 |
GetNumberFormatIndex()
|
返回当前行中值的数字格式索引。索引值低于164,请参阅内置数字格式,否则表示自定义数字格式。 |
GetCellStyle()
|
返回当前行中包含单元格的样式信息的对象:凹痕,水平对齐,隐藏,锁定。 |
键入的Get*()方法 |
除非类型完全匹配,否则投掷InvalidCastException 。 |
CreateAder()配置选项
ExcelReaderFactory.CreateReader() , CreateBinaryReader() , CreateOpenXmlReader() , CreateCsvReader()方法接受可选的配置对象,以修改阅读器的行为:
ExcelDataReader object is disposed. Default: false
LeaveOpen = false,
// Gets or sets a value indicating the number of rows to analyze for
// encoding, separator and field count in a CSV. When set, this option
// causes the I ExcelDataReader .RowCount property to throw an exception.
// Default: 0 – analyzes the entire file (CSV only, has no effect on other
// formats)
AnalyzeInitialCsvRows = 0,
});\”>
var reader = ExcelReaderFactory . CreateReader ( stream , new ExcelReaderConfiguration ( ) { // Gets or sets the encoding to use when the input XLS lacks a CodePage // record, or when the input CSV lacks a BOM and does not parse as UTF8. // Default: cp1252 (XLS BIFF2-5 and CSV only) FallbackEncoding = Encoding . GetEncoding ( 1252 ) , // Gets or sets the password used to open password protected workbooks. Password = \"password\" , // Gets or sets an array of CSV separator candidates. The reader // autodetects which best fits the input data. Default: , ; TAB | # // (CSV only) AutodetectSeparators = new char [ ] { \',\' , \';\' , \' \\t \' , \'|\' , \'#\' } , // Gets or sets a value indicating whether to trim white space values for CSV (Default \'true\'). // (CSV only) TrimWhiteSpace = true , // Gets or sets a value indicating whether to leave the stream open after // the I ExcelDataReader object is disposed. Default: false LeaveOpen = false , // Gets or sets a value indicating the number of rows to analyze for // encoding, separator and field count in a CSV. When set, this option // causes the I ExcelDataReader .RowCount property to throw an exception. // Default: 0 - analyzes the entire file (CSV only, has no effect on other // formats) AnalyzeInitialCsvRows = 0 , } ) ;
Asdataset()配置选项
AsDataSet()方法接受可选的配置对象,以修改数据集转换的行为:
var result = reader . AsDataSet ( new ExcelDataSetConfiguration ( ) { // Gets or sets a value indicating whether to set the DataColumn.DataType // property in a second pass. UseColumnDataType = true , // Gets or sets a callback to determine whether to include the current sheet // in the DataSet. Called once per sheet before ConfigureDataTable. FilterSheet = ( tableReader , sheetIndex ) => true , // Gets or sets a callback to obtain configuration options for a DataTable. ConfigureDataTable = ( tableReader ) => new ExcelDataTableConfiguration ( ) { // Gets or sets a value indicating the prefix of generated column names. EmptyColumnNamePrefix = \"Column\" , // Gets or sets a value indicating whether to use a row from the // data as column names. UseHeaderRow = false , // Gets or sets a callback to determine which row is the header row. // Only called when UseHeaderRow = true. ReadHeaderRow = ( rowReader ) => { // F.ex skip the first row and use the 2nd row as column headers: rowReader . Read ( ) ; } , // Gets or sets a callback to determine whether to include the // current row in the DataTable. FilterRow = ( rowReader ) => { return true ; } , // Gets or sets a callback to determine whether to include the specific // column in the DataTable. Called once per column after reading the // headers. FilterColumn = ( rowReader , columnIndex ) => { return true ; } } } ) ;
设置AsDataSet()配置,使用FilterRow回调在加载时实现“进度指示器”,例如:
var result = reader . AsDataSet ( new ExcelDataSetConfiguration ( ) { ConfigureDataTable = ( tableReader ) => new ExcelDataTableConfiguration ( ) { FilterRow = ( rowReader ) => { int progress = ( int ) Math . Ceiling ( ( decimal ) rowReader . Depth / ( decimal ) rowReader . RowCount * ( decimal ) 100 ) ; // progress is in the range 0..100 return true ; } } } ) ;
格式化
ExcelDataReader不直接支持格式化。用户可以通过I ExcelDataReader .GetNumberFormatString(i)重新删除单元格的数字格式字符串,并使用第三方excelnumberformat库进行格式化。
使用ExcelDataReader和excelnumberformat的示例辅助方法,以格式化一个值:
ExcelDataReader reader, int columnIndex, CultureInfo culture)
{
var value = reader.GetValue(columnIndex);
var formatString = reader.GetNumberFormatString(columnIndex);
if (formatString != null)
{
var format = new NumberFormat(formatString);
return format.Format(value, culture);
}
return Convert.ToString(value, culture);
}\”>
string GetFormattedValue ( I ExcelDataReader reader , int columnIndex , CultureInfo culture ) { var value = reader . GetValue ( columnIndex ) ; var formatString = reader . GetNumberFormatString ( columnIndex ) ; if ( formatString != null ) { var format = new NumberFormat ( formatString ) ; return format . Format ( value , culture ) ; } return Convert . ToString ( value , culture ) ; }
参见:
- https://gi*th*ub*.com/andersnm/excelnumberformat
- https://www.*nug**et.org/packages/excelnumberformat
从ExcelDataReader 2.x升级时要注意
ExcelDataReader 3发生了一些破裂的变化,较旧的代码可能会产生类似的错误消息:
ExcelDataReader\’ does not contain a definition for \’AsDataSet\’…
\’I ExcelDataReader \’ does not contain a definition for \’IsFirstRowAsColumnNames\’…\”>
\'I ExcelDataReader \' does not contain a definition for \'AsDataSet\'...
\'I ExcelDataReader \' does not contain a definition for \'IsFirstRowAsColumnNames\'...
修复:
-
确保将代码中的任何
Excel名称空间引用重命名为新名称空间ExcelDataReader -
确保该项目对
ExcelDataReader .DataSet软件包的参考来使用AsDataSet() -
使用
IsFirstRowAsColumnNames删除代码行,然后将呼叫更改为Asdataset()以下内容:
var result = reader . AsDataSet ( new ExcelDataSetConfiguration ( ) { ConfigureDataTable = ( _ ) => new ExcelDataTableConfiguration ( ) { UseHeaderRow = true } } ) ;
在.NET核心上的重要说明
默认情况下, ExcelDataReader抛出了一个notsupportedException“没有用于编码1252的数据。”在.NET Core和.NET 5.0或更高版本上。
要修复,请将依赖项添加到package System.Text.Encoding.CodePages ,然后在应用程序初始化期间添加代码以注册代码页提供商(instup.cs中的F.EX):
System . Text . Encoding . RegisterProvider ( System . Text . CodePagesEncodingProvider . Instance ) ;
这是在二进制BIFF2-5 excel文档中解析字符串所必需的,该文档编码了DOS-era代码页面。这些编码默认情况下在完整的.NET框架中注册,但在.NET Core和.NET 5.0或更高版本上不注册。
