I am using ExcelDataReader
to read data from my Excel workbook in C#.
But structure of my Excel sheet is such that data to be read can start from any particular cell and not necessarily A1
.
Can any one Please suggest a way on how this can be achieved using ExcelDataReader
?
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.
ExcelDataReader is for reading, not writing. If you're looking libs for writing, you can start here - stackoverflow.com/questions/151005/…
ExcelDataReader is an open source lightweight API written in C# for reading Microsoft Excel Files. Using the API you can read Microsoft XLS, XLSX, and CSV easily.
If you are using ExcelDataReader 3+
you will find that there isn't any method for AsDataSet()
for your reader object, You need to also install another package for ExcelDataReader.DataSet
, then you can use the AsDataSet()
method.
Also there is not a property for IsFirstRowAsColumnNames
instead you need to set it inside of ExcelDataSetConfiguration
.
Example:
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); // Now you can get data from each sheet by its index or its "name" var dataTable = dataSet.Tables[0]; //... }
You can find row number and column number of a cell reference like this:
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());
Now you can use some loops to read data from that cell like this:
for (var i = row; i < dataTable.Rows.Count; i++) { for (var j = col; j < dataTable.Columns.Count; j++) { var data = dataTable.Rows[i][j]; } }
Update:
You can filter rows and columns of your Excel sheet at read time with this config:
var i = 0; var conf = new ExcelDataSetConfiguration { UseColumnDataType = true, ConfigureDataTable = _ => new ExcelDataTableConfiguration { FilterRow = rowReader => fromRow <= ++i - 1, FilterColumn = (rowReader, colIndex) => fromCol <= colIndex, UseHeaderRow = true } };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With