I read excel but dataGridView show data than lines excel file, So I can't write datagridview.Rowcount(). I use the below given code to read the excel file.
Code:
filePath = txtExcelFile.Text;
string[] fileSpit = filePath.Split('.');
if (filePath.Length > 1 && fileSpit[1] == "xls")
{
connString = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=" + filePath + ";Extended Properties='Excel 8.0;HDR=No'";
}
else
{
connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties='Excel 12.0;HDR=No'";
}
OleDbCommand cmd = new OleDbCommand(#"Select * from [" +comboBox1.SelectedValue.ToString() + "]", ole);
OleDbDataAdapter oledata = new OleDbDataAdapter();
oledata.SelectCommand = cmd;
DataSet ds = new DataSet();
oledata.Fill(ds);
dataGridView1.DataSource = ds.Tables[0].DefaultView;
Either strip out the blank lines from the data table before assigning it to the grid:
private DataTable StripEmptyRows(DataTable dt)
{
List<int> rowIndexesToBeDeleted = new List<int>();
int indexCount = 0;
foreach(var row in dt.Rows)
{
var r = (DataRow)row;
int emptyCount = 0;
int itemArrayCount = r.ItemArray.Length;
foreach(var i in r.ItemArray) if(string.IsNullOrWhiteSpace (i.ToString())) emptyCount++;
if(emptyCount == itemArrayCount) rowIndexesToBeDeleted.Add(indexCount);
indexCount++;
}
int count = 0;
foreach(var i in rowIndexesToBeDeleted)
{
dt.Rows.RemoveAt(i-count);
count++;
}
return dt;
}
Or do your own row count ignoring blank rows.
Related
I have the following code which will import my excel file. But for some reason it will not show all of the data from the orginal spread sheet.
Here is the original spreadsheet:
Here is the output:
For some reason some of the columns under the benefit period months get lost or do not show up.
private void btnLoadExcel_Click(object sender, EventArgs e){
string pathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtPath.Text +
";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
OleDbConnection conn = new OleDbConnection(pathConn);
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select * from [" + txtSheet.Text+ "$]",conn);
conn.Open();
DataTable dt = new DataTable();
myDataAdapter.Fill(dt);
dataGridView1.AutoResizeColumns();
dataGridView1.DataSource = dt;
for (int i = 0; i < dataGridView1.Columns.Count - 1; i++)
{
dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
dataGridView1.Columns[dataGridView1.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
int colw = dataGridView1.Columns[i].Width;
dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
dataGridView1.Columns[i].Width = colw;
}
}
Copying your code produced the same results you explained. The only change I made was to the pathConn string by adding the parameter IMEX=1 which will set the column types as strings. I am guessing that the columns may have different “types” for different rows in the excel file.
string pathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtPath.Text +
";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1;\";";
Hope this helps.
I'm initially populating my DataGridView with data from Excel Sheet.
private void btnChooseAndRead_Click(object sender, EventArgs e)
{
Refresh();
string filePath = string.Empty;
string fileExt = string.Empty;
OpenFileDialog file = new OpenFileDialog();//open dialog to choose file
if (file.ShowDialog() == System.Windows.Forms.DialogResult.OK)//if there is a file choosen by the user
{
filePath = file.FileName;//get the path of the file
fileExt = Path.GetExtension(filePath);//get the file extension
if (fileExt.CompareTo(".xls") == 0 || fileExt.CompareTo(".xlsx") == 0)
{
try
{
cmbSheetName.Text = "";
cmbSheetName.Items.Clear();
string[] names = GetExcelSheetNames(file.FileName);
//Populate Combobox with Sheet names
foreach (string name in names)
{
cmbSheetName.Items.Add(name);
}
DataTable dtExcel = new DataTable();
dtExcel = ReadExcel(filePath, fileExt); //read excel file
cmbSheetName.Visible = true;
lblFileName.Text = file.SafeFileName.ToString();
BindingSource theBindingSource = new BindingSource();
dgvViewData.Visible = true;
dgvViewData.DataSource = dtExcel;
//dgvViewData.ColumnDisplayIndexChanged = true;
//cmbSheetName_SelectedIndexChanged(sender, e);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
else
{
MessageBox.Show("Please choose .xls or .xlsx file only.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error);//custom messageBox to show error
}
}
}
public DataTable ReadExcel(string fileName, string fileExt)
{
string conn = string.Empty;
DataTable dtexcel = new DataTable();
if (fileExt.CompareTo(".xls") == 0)//compare the extension of the file
conn = #"provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties='Excel 8.0;HRD=Yes;IMEX=1';";//for below excel 2007
else
conn = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1';";//for above excel 2007
using (OleDbConnection con = new OleDbConnection(conn))
{
try
{
OleDbDataAdapter oleAdpt = new OleDbDataAdapter("select * from [Sheet1$]", con);//here we read data from sheet1
oleAdpt.Fill(dtexcel);//fill excel data into dataTable
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
return dtexcel;
}
Which works perfectly fine, now the Excel file that I'm reading from has more than one sheets.
I also have a combobox populating the Sheetnames.
What needs to happen is that when the user selects for example "Sheet5" from the combo I want to refresh the Gridview with the selected sheet details. How do I do this? How do I even know that all sheets are all in the Gridview?
I did not test this thoroughly, but it appears to work correctly. Assuming you are using OLEDB... basically the code below uses a DataSet to hold all the worksheets. While gathering the worksheets I also create a simple List<string> to hold the names of each worksheet to display into the combo box. Since the worksheet and the combo box are added at the same time, we can use the combo boxes selected index to identify the proper worksheet (data table in the data set) to display. The names of worksheets have a “$” sign in their name. I removed this “$” when displayed to the combo box.
The code below is a form with a DataGridView to display the data tables, a ComboBox to select a data table and a Label to give info about the currently selected data table. Hope this helps.
public partial class Form1 : Form {
private string Excel07ConString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\YourFilePath\YourFile.xls;Extended Properties='Excel 12.0 Xml;IMEX=1;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text'";
string sheetName;
DataSet ds;
List<string> comboBoxData = new List<string>();
public Form1() {
InitializeComponent();
SetDataTablesFromExcel();
dataGridView1.DataSource = ds.Tables[0];
comboBox1.DataSource = comboBoxData;
label1.Text = "TableName: " + ds.Tables[0].TableName + " has " + ds.Tables[0].Rows.Count + " rows";
}
private void SetDataTablesFromExcel() {
ds = new DataSet();
using (OleDbConnection con = new OleDbConnection(Excel07ConString)) {
using (OleDbCommand cmd = new OleDbCommand()) {
using (OleDbDataAdapter oda = new OleDbDataAdapter()) {
cmd.Connection = con;
con.Open();
DataTable dtExcelSchema = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
for (int i = 0; i < dtExcelSchema.Rows.Count; i++) {
sheetName = dtExcelSchema.Rows[i]["TABLE_NAME"].ToString();
DataTable dt = new DataTable();
cmd.Connection = con;
cmd.CommandText = "SELECT * FROM [" + sheetName + "]";
oda.SelectCommand = cmd;
oda.Fill(dt);
dt.TableName = sheetName;
comboBoxData.Add(sheetName.Replace("$", ""));
ds.Tables.Add(dt);
}
}
}
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
int index = comboBox1.SelectedIndex;
dataGridView1.DataSource = ds.Tables[index];
label1.Text = "TableName: " + ds.Tables[index].TableName + " has " + ds.Tables[index].Rows.Count + " rows";
}
}
I am trying to fetch data from excel using below C# code. I am getting the value from two
columns into single variable(str).
I want that value into different variables.So that i can send that value at runtime for two different statements.
How to bring them into two different variable?
string currentSheet = "Sheet1";
excelApp = new Excel.Application();
//Opening/adding Excel file
excelWorkbook = excelApp.Workbooks.Add(workbookPath);
excelSheets = excelWorkbook.Sheets;
excelWorksheet = (Excel.Worksheet)excelSheets.get_Item(currentSheet);
//Gives the used cells in the sheet
range = excelWorksheet.UsedRange;
for (rowCnt = 1; rowCnt <= range.Rows.Count; rowCnt++)
{
for (colCnt = 1; colCnt <= range.Rows.Count;colCnt++)
{
str = (string)(range.Cells[rowCnt,colCnt] as Excel.Range).Value2;
System.Console.WriteLine(str);
}
}
string Connection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=1\";";
OleDbConnection con = new OleDbConnection(Connection);
OleDbCommand command = new OleDbCommand();
System.Data.DataTable dt = new System.Data.DataTable();
OleDbDataAdapter myCommand = new OleDbDataAdapter("select * from [Sheet1$]", con);
myCommand.Fill(dt);
con.Close();
for (rowCnt = 1; rowCnt <= range.Rows.Count; rowCnt++)
{
string Charity = (string)(range.Cells[rowCnt, 1] as Excel.Range).Value;
string Country = (string)(range.Cells[rowCnt, 2] as Excel.Range).Value;
System.Console.WriteLine(Charity + " --- " + Country);
}
The problem is that the first column is empty and it can not be read.
To read the file, I wrote the following code:
MyConnection = new OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + "'" + filename + "'" + ";Extended Properties=\"Excel 8.0;IMEX=1;HDR=NO;TypeGuessRows=0\"");
DtSet = new DataSet();
MyConnection.Open();
var dt = MyConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
MyCommand = new OleDbDataAdapter("select * from [$first]", MyConnection);
MyCommand.Fill(DtSet); // filldata
dataExcel.AddRange(fillData(DtSet.Tables["Table"]).Select(info => info.ToList()));
}
List<List<string>> fillData(DataTable DtSet) //reader
{
List<List<string>> data = new List<List<string>>();
foreach (DataRow item in DtSet.Rows)
{
if (item == null) continue;
List<string> gettedData = new List<string>();
int i = 0;
foreach (var columnitem in item.ItemArray)
{
if (i == 0 && columnitem.ToString() == "") ;
else gettedData.Add(columnitem.ToString()); //add data
i++;
}
data.Add(gettedData);
}
return data;
}
This code works but the first column, he does not see. Thank you!
I'm using the code below to read my Excel spreadsheet (Sample.xls, also below).
Sample.xls
[Sheet 1]
Column 0, Row 0 = "Test 1"
Column 0, Row 1 = "Test 2"
Column 0, Row 2 = "Test 3"
[Sheet 2]
All columns/rows are blank and empty
public void importFileButton_Click(object sender, EventArgs e)
{
string sourcefile = "C:\\Sample.xls";
string sqlQuery = null;
if (File.Exists(sourceFile))
{
DataTable fileSheetInfo = null;
OleDbConnection connection = new OleDbConnection(#"Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + sourceFile + ";Extended Properties=\"Excel 8.0;HDR=No;IMEX=1;\"");
connection.Open();
fileSheetInfo = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
int fileSheetCount = fileSheetInfo.Rows.Count;
OleDbCommand command = new OleDbCommand();
String[] sheetNames = new String[fileSheetInfo.Rows.Count];
int i = 0;
foreach (DataRow row in fileSheetInfo.Rows)
{
sheetNames[i] = row["TABLE_NAME"].ToString();
sqlQuery1 = "SELECT * FROM [" + sheetNames[i] + "]";
command.CommandText = sqlQuery1;
OleDbDataAdapter adapter1 = new OleDbDataAdapter(sqlQuery, connection);
DataTable sheetData = new DataTable();
adapter1.Fill(sheetData);
int iRow = sheetData.Rows.Count;
MessageBox.Show("Sheet Name: " + sheetNames[i], "Sheet Name", MessageBoxButtons.OK);
MessageBox.Show("Rows: " + iRow.ToString(), "Row Count", MessageBoxButtons.OK);
i++;
}
}
}
Why does the code return a rowcount of 1 or 2 for the blank sheet (Sheet2)? Why isn't the rowcount displaying as 0 for Sheet 2? I have noticed that the rowcount is 1 if I have the file open in Excel; 2 if the file is closed in Excel.
Thanks for the help!