Использование ExcelDataReader для чтения данных Excel, начиная с определенной ячейки
Я использую ExcelDataReader
для чтения данных из моей книги Excel в С#.
Но структура моего листа Excel такова, что считываемые данные могут начинаться с любой конкретной ячейки и не обязательно A1
.
Может ли кто-нибудь, пожалуйста, предложить способ, как это может быть достигнуто с помощью ExcelDataReader
?
Ответы
Ответ 1
Если вы используете ExcelDataReader 3+
вы обнаружите, что нет никакого метода для AsDataSet()
для вашего объекта читателя. Вам также нужно установить другой пакет для ExcelDataReader.DataSet
, тогда вы можете использовать метод AsDataSet()
.
Также нет свойства для IsFirstRowAsColumnNames
вместо этого вам нужно установить его внутри ExcelDataSetConfiguration
.
Пример:
using (var stream = File.Open(originalFileName, FileMode.Open, FileAccess.Read))
{
IExcelDataReader reader;
// Create Reader - old until 3.4+
////var file = new FileInfo(originalFileName);
////if (file.Extension.Equals(".xls"))
//// reader = ExcelDataReader.ExcelReaderFactory.CreateBinaryReader(stream);
////else if (file.Extension.Equals(".xlsx"))
//// reader = ExcelDataReader.ExcelReaderFactory.CreateOpenXmlReader(stream);
////else
//// throw new Exception("Invalid FileName");
// Or in 3.4+ you can only call this:
reader = ExcelDataReader.ExcelReaderFactory.CreateReader(stream)
//// reader.IsFirstRowAsColumnNames
var conf = new ExcelDataSetConfiguration
{
ConfigureDataTable = _ => new ExcelDataTableConfiguration
{
UseHeaderRow = true
}
};
var dataSet = reader.AsDataSet(conf);
var dataTable = dataSet.Tables[0];
//...
}
Вы можете найти номер строки и номер столбца ссылки на ячейку следующим образом:
var cellStr = "AB2"; // var cellStr = "A1";
var match = Regex.Match(cellStr, @"(?<col>[A-Z]+)(?<row>\d+)");
var colStr = match.Groups["col"].ToString();
var col = colStr.Select((t, i) => (colStr[i] - 64) * Math.Pow(26, colStr.Length - i - 1)).Sum();
var row = int.Parse(match.Groups["row"].ToString());
Теперь вы можете использовать несколько циклов для чтения данных из этой ячейки, например:
for (var i = row; i < dataTable.Rows.Count; i++)
{
for (var j = col; j < dataTable.Columns.Count; j++)
{
var data = dataTable.Rows[i][j];
}
}
Обновить:
Вы можете фильтровать строки и столбцы вашего листа Excel во время чтения с помощью этой конфигурации:
var i = 0;
var conf = new ExcelDataSetConfiguration
{
UseColumnDataType = true,
ConfigureDataTable = _ => new ExcelDataTableConfiguration
{
FilterRow = rowReader => fromRow <= ++i - 1,
FilterColumn = (rowReader, colIndex) => fromCol <= colIndex,
UseHeaderRow = true
}
};
Ответ 2
Чтобы быть более ясным, я начну с самого начала.
Я опишу пример кода, найденный в https://exceldatareader.codeplex.com/, но с некоторыми изменениями, чтобы избежать неудобств.
Следующий код определяет формат файла: xls или xlsx.
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader;
//1. Reading Excel file
if (Path.GetExtension(filePath).ToUpper() == ".XLS")
{
//1.1 Reading from a binary Excel file ('97-2003 format; *.xls)
excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
}
else
{
//1.2 Reading from a OpenXml Excel file (2007 format; *.xlsx)
excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
}
//2. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
//3. DataSet - Create column names from first row
excelReader.IsFirstRowAsColumnNames = false;
Теперь мы можем получить доступ к содержимому файла более удобным способом. Для этого я использую DataTable. Ниже приведен пример доступа к определенной ячейке и печать его значения в консоли:
DataTable dt = result.Tables[0];
Console.WriteLine(dt.Rows[rowPosition][columnPosition]);
Если вы не хотите делать DataTable, вы можете сделать то же самое:
Console.WriteLine(result.Tables[0].Rows[rowPosition][columnPosition]);
Важно не пытаться читать за пределами таблицы, для этого вы можете увидеть количество строк и столбцов следующим образом:
Console.WriteLine(result.Tables[0].Rows.Count);
Console.WriteLine(result.Tables[0].Columns.Count);
Наконец, когда вы закончите, вы должны закрыть читателя и свободные ресурсы:
//5. Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
Надеюсь, вы сочтете это полезным.
(Я понимаю, что вопрос старый, но я делаю этот вклад для улучшения базы знаний, потому что мало информации о конкретных реализациях этой библиотеки).
Ответ 3
Я нашел это полезным для чтения из определенного столбца и строки
FileStream stream = File.Open(@"C:\Users\Desktop\ExcelDataReader.xlsx", FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
DataSet result = excelReader.AsDataSet();
excelReader.IsFirstRowAsColumnNames = true;
DataTable dt = result.Tables[0];
string text = dt.Rows[1][0].ToString();
Ответ 4
Один из способов сделать это:
FileStream stream = File.Open(@"c:\working\test.xls", FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
result.Tables
содержит листы, а result.tables[0].Rows
содержит строки ячеек.
Ответ 5
Очень легко с ExcelReaderFactory 3.1 и выше:
using (var openFileDialog1 = new OpenFileDialog { Filter = "Excel Workbook|*.xls;*.xlsx;*.xlsm", ValidateNames = true })
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
var fs = File.Open(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
var reader = ExcelReaderFactory.CreateBinaryReader(fs);
var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration
{
ConfigureDataTable = _ => new ExcelDataTableConfiguration
{
UseHeaderRow = true // Use first row is ColumnName here :D
}
});
if (dataSet.Tables.Count > 0)
{
var dtData = dataSet.Tables[0];
// Do Something
}
}
}
Ответ 6
Вы можете использовать библиотеку .NET, чтобы сделать то же самое, что я считаю более простым.
string ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; data source={path of your excel file}; Extended Properties=Excel 12.0;";
OleDbConnection objConn = null;
System.Data.DataTable dt = null;
//Create connection object by using the preceding connection string.
objConn = new OleDbConnection(connString);
objConn.Open();
//Get the data table containg the schema guid.
dt = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string sql = string.Format("select * from [{0}$]", sheetName);
var adapter = new System.Data.OleDb.OleDbDataAdapter(sql, ConnectionString);
var ds = new System.Data.DataSet();
string tableName = sheetName;
adapter.Fill(ds, tableName);
System.Data.DataTable data = ds.Tables[tableName];
После того, как у вас есть данные в datatable, вы можете получить к ним доступ, как обычно, с классом DataTable.