Reputation: 3859
I would like to know how I can read multiple excel worksheet with different worksheet name in c# and with the used of oledb.
I have this existing way to read multiple sheets (but with fixed worksheet name):
DataSet ds = new DataSet();
var excelConnectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=Excel 8.0", path);
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = excelConnectionString;
var i = 1;
while (i <= 4)
{
string query = "SELECT * FROM [Sheet" + i + "$]";
ds.Clear();
OleDbDataAdapter data = new OleDbDataAdapter(query, connection);
data.Fill(ds);
// other stuff
i = i + 1;
}
This one works. But I'm now in different situation wherein the worksheets names are not fixed, example: Sheet1 is Dog, Sheet2 is Cat Sheet3 is Bird.
Now my concern is how I can loop on those worksheet names with the use of my existing code.
Upvotes: 3
Views: 17551
Reputation: 1
i use code below , it worked on my different sheets in one excel file.
using (SpreadsheetDocument doc = SpreadsheetDocument.Open(ratesFilePath, false))
{
WorkbookPart workbookPart = doc.WorkbookPart;
Sheets sheets = workbookPart.Workbook.GetFirstChild<Sheets>();
foreach (Sheet sheet in sheets)
{
if (sheet.Name == "Sheet Name")
{
Worksheet worksheet = ((WorksheetPart)workbookPart.GetPartById(sheet.Id)).Worksheet;
SheetData sheetData = (SheetData)worksheet.GetFirstChild<SheetData>();
foreach (Row row in sheetData)
{
if ((row.FirstChild as Cell).CellReference.ToString().Contains("A") && (row.FirstChild as Cell).CellValue != null && row.RowIndex != 1)
{
RateInformation RateInformationElement = new RateInformation();
foreach (Cell c in row)
{
string cellValue = null;
if ((c.DataType != null) && (c.DataType == CellValues.SharedString))
{
int id = -1;
if (Int32.TryParse(c.InnerText, out id))
{
SharedStringItem item = GetSharedStringItemById(workbookPart, id);
if (item.Text != null)
{
//code to take the string value
cellValue = item.Text.Text;
}
else if (item.InnerText != null)
{
if (Convert.ToDouble(item.InnerText).ToString() != null)
{
cellValue = Convert.ToDouble(item.InnerText).ToString();
}
else
{
cellValue = item.InnerText;
}
}
else if (item.InnerXml != null)
{
cellValue = item.InnerXml;
}
}
}
else
{
cellValue = c.InnerText;
}
if (c.CellReference.ToString().Contains("A"))
{
RateInformationElement.Unit = cellValue;
}
else if (c.CellReference.ToString().Contains("B"))
{
Decimal.TryParse(cellValue, NumberStyles.Any, CultureInfo.InvariantCulture, out decimal result);
RateInformationElement.Price = Convert.ToDecimal(result);
}
}
rateInformations.Add(RateInformationElement);
}
}
}
}
}
Upvotes: 0
Reputation: 3850
This is from VB.net but not sure how well it translates, returns a list of strings containing all sheet names:
OleDbConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "TABLE"})
Once you have a list of sheet names you can do a simple For Each
loop to iterate.
Edit:
This should work in C#
Add function
static DataTable GetSchemaTable(string connectionString)
{
using (OleDbConnection connection = new
OleDbConnection(connectionString))
{
connection.Open();
DataTable schemaTable = connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
new object[] { null, null, null, "TABLE" });
return schemaTable;
}
}
Your code would change to:
DataSet ds = new DataSet();
var excelConnectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=Excel 8.0", path);
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = excelConnectionString;
DataTable sheets = GetSchemaTable(excelConnectionString);
foreach (dataRow r in sheets.rows)
{
string query = "SELECT * FROM [" + r.Item(0).ToString + "]";
ds.Clear();
OleDbDataAdapter data = new OleDbDataAdapter(query, connection);
data.Fill(ds);
}
Just be sure to do something with ds
after each iteration.
Upvotes: 4