如何从DataTable中删除空行

我正在从Excel工作表导入数据到数据库。 Excel工作表包含几个空行,我想删除这些空行,然后将清除的数据插入数据库。
我通过引用其他代码来编写代码,这是插入值的代码:

OleDbConnection cnn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + txtExcelFile.Text + "';Extended Properties= 'Excel 8.0;HDR=Yes;IMEX=1'"); //DataTable dt = new DataTable(); try { cnn.Open(); OleDbDataAdapter data = new OleDbDataAdapter("select * from [Customers$]", cnn); data.Fill(dsExcel); dgvCustomers.ColumnHeadersVisible = false; SqlConnection connection = new SqlConnection("Data Source=COMPUTER-8EB749;Initial Catalog=KITS;Integrated Security=true"); connection.Open(); for (int i = 0; i < dsExcel.Tables[0].Rows.Count; i++) { string ID = ds.Tables[0].Rows[i][0].ToString(); Int16 CustID = Convert.ToInt16(ID); string CustName = dsExcel.Tables[0].Rows[i][1].ToString(); string CardScheme = dsExcel.Tables[0].Rows[i][2].ToString(); string Outlet = dsExcel.Tables[0].Rows[i][3].ToString(); string TerminalNum = dsExcel.Tables[0].Rows[i][4].ToString(); Int32 Terminal = Convert.ToInt32(TerminalNum); string Date1 = dsExcel.Tables[0].Rows[i][5].ToString(); DateTime Date = Convert.ToDateTime(Date1); string Time = dsExcel.Tables[0].Rows[i][6].ToString(); DateTime DateTime = Convert.ToDateTime(Time); string Amount1 = ds.Tables[0].Rows[i][7].ToString(); double Amount = Convert.ToDouble(Amount1); SqlCommand com = new SqlCommand("insert into Customer(CustID,CustName,CardScheme,Outlet,TerminalNum,TranDate,TranDateTime,Amount) values ('" + CustID + "','" + CustName + "','" + CardScheme + "','" + Outlet + "','" + Terminal + "','" + Date + "','" + DateTime + "','" + Amount + "')", connection); com.ExecuteNonQuery(); } connection.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { MessageBox.Show("Data Inserted Successfully."); } 

任何人都可以说我如何删除空行,以便我只能插入数据?!

Excel工作表

尝试这个。

 public bool InsertRowsToDataBase() { try { DataTable excelTable = new DataTable(); string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + txtExcelFile.Text + "';Extended Properties= 'Excel 8.0;HDR=Yes;IMEX=1'"; using (OleDbConnection cnn = new OleDbConnection(connString)) { string query = "select * from [Customers$]"; using (OleDbDataAdapter data = new OleDbDataAdapter(query, cnn)) { data.Fill(excelTable); } } dgvCustomers.ColumnHeadersVisible = false; connString = "Data Source=COMPUTER-8EB749;Initial Catalog=KITS;Integrated Security=true"; using (SqlConnection connection = new SqlConnection(connString)) { connection.Open(); for (int i = 0; i < excelTable.Rows.Length; i++) { //takes from the 3rd row if (i > 1) { DataRow row = excelTable.Rows[i]; object ID = row[0]; if (ID != null && !String.IsNullOrEmpty(ID.ToString().Trim())) { Int16 CustID = Convert.ToInt16(ID); string CustName = row[1].ToString(); string CardScheme = row[2].ToString(); string Outlet = row[3].ToString(); string TerminalNum = row[4].ToString(); Int32 Terminal = Convert.ToInt32(TerminalNum); string Date1 = row[5].ToString(); DateTime Date = Convert.ToDateTime(Date1); string Time = row[6].ToString(); DateTime DateTime = Convert.ToDateTime(Time); string Amount1 = row[7].ToString(); double Amount = Convert.ToDouble(Amount1); string columnNames = "CustID,CustName,CardScheme,Outlet,TerminalNum,TranDate,TranDateTime,Amount"; string query = String.Format("insert into Customer(0}) values ('{1}', '{2}','{3}','{4}','{5}','{6}','{7}','{8}')", columnNames, CustID, CustName, CardScheme, Outlet, Terminal, Date, DateTime, Amount); using (SqlCommand com = new SqlCommand(query, connection)) { com.ExecuteNonQuery(); } } } //this is your last row. do whatever you want with this DataRow lastRow = excelTable.Rows[excelTable.Rows.Count - 1]; } } return true; } catch (Exception exception) { Elmah.ErrorSignal.FromCurrentContext().Raise(exception); return false; } } 

请注意,我只是检查ID是否为空,不插入任何这样的行,因为ID将是您的表中的PK。

这将删除它的每个列都包含任何内容或空白的所有行:

 dataTable = dataTable.Rows .Cast<DataRow>() .Where(row => !row.ItemArray.All(field => field is DBNull || string.IsNullOrWhiteSpace(field as string))) .CopyToDataTable(); 
 try { OpenOleDBConnection(); OleDbDataAdapter dataAdapter = new OleDbDataAdapter("select * from [" + SelectedSheet + "]", Connection); dataAdapter.Fill(DataTable); if ((DataTable != null) && (DataTable.Rows != null) && (DataTable.Rows.Count > 0)) { List<System.Data.DataRow> removeRowIndex = new List<System.Data.DataRow>(); int RowCounter = 0; foreach (System.Data.DataRow dRow in DataTable.Rows) { for(int index = 0; index < DataTable.Columns.Count; index++) { if (dRow[index] == DBNull.Value) { removeRowIndex.Add(dRow); break; } else if (string.IsNullOrEmpty(dRow[index].ToString().Trim())) { removeRowIndex.Add(dRow); break; } } RowCounter++; } // Remove all blank of in-valid rows foreach (System.Data.DataRow rowIndex in removeRowIndex) { DataTable.Rows.Remove(rowIndex); } } } catch(Exception e) { WPFMessageBox.Show(e.Message, Globalization.GetValue("Import_ImportOption_FormHeader"), WPFMessageBoxButtons.OK, WPFMessageBoxImage.Error); } finally { CloseOleDBConnection(); } 

这里我也跳过行,如果他们在任何行的空白条目。

我已经做了这个私人的方法,做伎俩。 它将DataTable作为参数,并返回相同的DataTable,而不包含空行。

 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; } 

为什么不在插入之前直接忽略空行呢?

 if(string.IsNullOrEmpty(ID + CustName + CardScheme /*.. and so on */)) { continue; } 

喜欢这个:

 for (int i = 0; i < dsExcel.Tables[0].Rows.Count; i++) { string ID = ds.Tables[0].Rows[i][0].ToString(); Int16 CustID = Convert.ToInt16(ID); string CustName = dsExcel.Tables[0].Rows[i][1].ToString(); string CardScheme = dsExcel.Tables[0].Rows[i][2].ToString(); string Outlet = dsExcel.Tables[0].Rows[i][3].ToString(); string TerminalNum = dsExcel.Tables[0].Rows[i][4].ToString(); Int32 Terminal = Convert.ToInt32(TerminalNum); string Date1 = dsExcel.Tables[0].Rows[i][5].ToString(); DateTime Date = Convert.ToDateTime(Date1); string Time = dsExcel.Tables[0].Rows[i][6].ToString(); DateTime DateTime = Convert.ToDateTime(Time); string Amount1 = ds.Tables[0].Rows[i][7].ToString(); double Amount = Convert.ToDouble(Amount1); /*** Add this if-statement to you code! ***/ if(string.IsNullOrEmpty(ID + CustName + CardScheme + Outlet + TerminalNum + Date1 + Time + Amount1)) { continue; } SqlCommand com = new SqlCommand("insert into Customer(CustID,CustName,CardScheme,Outlet,TerminalNum,TranDate,TranDateTime,Amount) values ('" + CustID + "','" + CustName + "','" + CardScheme + "','" + Outlet + "','" + Terminal + "','" + Date + "','" + DateTime + "','" + Amount + "')", connection); com.ExecuteNonQuery(); } 

你的数据库本身有空行? 这很奇怪。 可以通过说一个主键列不是NULL做一个select查询来过滤它

 public static DataTable RemoveEmptyRows(DataTable dt) { List removeRowIndex = new List(); foreach (DataRow dRow in dt.Rows) { for (int index = 0; index < dt.Columns.Count; index++) { if (string.IsNullOrEmpty(dRow[index].ToString().Trim())) { removeRowIndex.Add(dRow); break; } else if (dRow[index] == DBNull.Value) { removeRowIndex.Add(dRow); break; } } } foreach (DataRow rowIndex in removeRowIndex) { dt.Rows.Remove(rowIndex); } return dt; } 

检查空行

 Foreach(DataRow as row in datable.Rows) { var isEmpty = row.ItemArray.All(c => c is DBNull); if(!isEmpty) { //Your Logic } } 

这对我来说是完美的:

 dt.Load(cmd.ExecuteReader()); var x = dt.Rows.Cast<DataRow>() .Where(row => !Array.TrueForAll(row.ItemArray, value => { return value.ToString().Length == 0; } )); dt = x.CopyToDataTable(); 

我修改了Cfrim的答案。 你需要检查空string和空白string。 白色空间来自已删除的单元格,空白空间来自已删除的数据。

 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 dr.ItemArray) { if (string.IsNullOrEmpty(i.ToString()) || 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; }