工作中的碰到的问题,以及处理过程:
问题:
1.读取Excel文件中数据并放到DataTable中;
2.快速找出DataTable中的重复行;
3.比较Excel文件中重复行时遇到的问题;
4.对“i++”和“i++”的重新认识;
5.尝试利用SqlBulkCopy 来插入数据;
解析:
对于第1条,我是从网上找的,发现网上98%都是采用oledb方式实现,我稍微改造了一下,
代码如下:
问题:
1.读取Excel文件中数据并放到DataTable中;
2.快速找出DataTable中的重复行;
3.比较Excel文件中重复行时遇到的问题;
4.对“i++”和“i++”的重新认识;
5.尝试利用SqlBulkCopy 来插入数据;
解析:
对于第1条,我是从网上找的,发现网上98%都是采用oledb方式实现,我稍微改造了一下,
代码如下:
代码
#region 从Excel中读取数据
/// <summary>
/// 从Excel中读取数据
/// </summary>
/// <param name="excelPath">Excel路径</param>
/// <returns>datatable</returns>
public static DataTable ImportTable(string excelPath)
{
DataTable mydt = new DataTable();//定义填充的表
///从导入的Excel中查询数据
string Connstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelPath + ";Extended Properties='Excel 8.0;IMEX=1';";
OleDbConnection Conn = new OleDbConnection(Connstr);
Conn.Open();
//返回Excel的架构,包括各个sheet表的名称,类型,创建时间和修改时间等
DataTable dtSheetName = Conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });
//包含excel中表名的字符串数组
string[] strTableNames = new string[dtSheetName.Rows.Count];
for (int k = 0; k < dtSheetName.Rows.Count; k++)
{
strTableNames[k] = dtSheetName.Rows[k]["TABLE_NAME"].ToString();
}
Conn.Close();
OleDbDataAdapter myCommand = null;
string strExcel = "select * from [" + strTableNames[0] + "A:R]";
myCommand = new OleDbDataAdapter(strExcel, Connstr);
myCommand.Fill(mydt);
return mydt;
}
#endregion
/// <summary>
/// 从Excel中读取数据
/// </summary>
/// <param name="excelPath">Excel路径</param>
/// <returns>datatable</returns>
public static DataTable ImportTable(string excelPath)
{
DataTable mydt = new DataTable();//定义填充的表
///从导入的Excel中查询数据
string Connstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelPath + ";Extended Properties='Excel 8.0;IMEX=1';";
OleDbConnection Conn = new OleDbConnection(Connstr);
Conn.Open();
//返回Excel的架构,包括各个sheet表的名称,类型,创建时间和修改时间等
DataTable dtSheetName = Conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });
//包含excel中表名的字符串数组
string[] strTableNames = new string[dtSheetName.Rows.Count];
for (int k = 0; k < dtSheetName.Rows.Count; k++)
{
strTableNames[k] = dtSheetName.Rows[k]["TABLE_NAME"].ToString();
}
Conn.Close();
OleDbDataAdapter myCommand = null;
string strExcel = "select * from [" + strTableNames[0] + "A:R]";
myCommand = new OleDbDataAdapter(strExcel, Connstr);
myCommand.Fill(mydt);
return mydt;
}
#endregion
对于第二条,为了提高性能,我是这样实现的,每次遍历时只跟它后面的数据比较,因为它前面的数据已经跟它比较过了,没必要它再跟前面的数据比较
代码
#region 比较datatable中的数据行是不是重复
/// <summary>
/// 比较datatable中的数据行是不是重复
/// </summary>
/// <param name="exceldt"></param>
/// <returns></returns>
public static ArrayList arrCFData(DataTable exceldt)
{
ArrayList arrUserData = new ArrayList();
string ret = null;
DataTable dtCompInfo = exceldt;
try
{
if (dtCompInfo.Rows.Count > 0)
{
int count = dtCompInfo.Rows.Count;
int x, y;
for (int i = 0; i < count; i++)
{
for (int j = i + 1; j < count; j++)
{
if (dtCompInfo.Rows[i][0].ToString().Equals(dtCompInfo.Rows[j][0].ToString())
&& dtCompInfo.Rows[i][1].ToString().Equals(dtCompInfo.Rows[j][1].ToString())
&& dtCompInfo.Rows[i][2].ToString().Equals(dtCompInfo.Rows[j][2].ToString()))
{
x = i + 2;
y = j + 2;
ret = string.Format("Excel数据中第{0}行和第{1}行数据重复", x, y);
arrUserData.Add(ret);
}
} //arrUserData.Add(dtCompInfo.Rows[i][0].ToString() + "出来吧" + dtCompInfo.Rows[i][3].ToString());
}
}
}
catch (Exception ex)
{
arrUserData = null;
throw new Exception(ex.Message);
}
finally
{
dtCompInfo = null;
}
return arrUserData;
}
#endregion
/// <summary>
/// 比较datatable中的数据行是不是重复
/// </summary>
/// <param name="exceldt"></param>
/// <returns></returns>
public static ArrayList arrCFData(DataTable exceldt)
{
ArrayList arrUserData = new ArrayList();
string ret = null;
DataTable dtCompInfo = exceldt;
try
{
if (dtCompInfo.Rows.Count > 0)
{
int count = dtCompInfo.Rows.Count;
int x, y;
for (int i = 0; i < count; i++)
{
for (int j = i + 1; j < count; j++)
{
if (dtCompInfo.Rows[i][0].ToString().Equals(dtCompInfo.Rows[j][0].ToString())
&& dtCompInfo.Rows[i][1].ToString().Equals(dtCompInfo.Rows[j][1].ToString())
&& dtCompInfo.Rows[i][2].ToString().Equals(dtCompInfo.Rows[j][2].ToString()))
{
x = i + 2;
y = j + 2;
ret = string.Format("Excel数据中第{0}行和第{1}行数据重复", x, y);
arrUserData.Add(ret);
}
} //arrUserData.Add(dtCompInfo.Rows[i][0].ToString() + "出来吧" + dtCompInfo.Rows[i][3].ToString());
}
}
}
catch (Exception ex)
{
arrUserData = null;
throw new Exception(ex.Message);
}
finally
{
dtCompInfo = null;
}
return arrUserData;
}
#endregion
对于第3条:在查找Excel数据中重复行
代码
if (dtCompInfo.Rows[i][0].Equals(dtCompInfo.Rows[j][0]) && dtCompInfo.Rows[i][3].Equals(dtCompInfo.Rows[j][3]))
{
x = i + 2;
y = j + 2;
ret = string.Format("Excel数据中第{0}行和第{1}行数据重复",x, y);
break;
}
{
x = i + 2;
y = j + 2;
ret = string.Format("Excel数据中第{0}行和第{1}行数据重复",x, y);
break;
}
对于第四条:因为老板要知道excel数据中到底哪些行重复了,所以一旦找到后需要记录这两行的索引,我这读出来的数据跟excel数据实际对应的行数差两行,所以要在程序中读到的行索引基础上在加2
代码
if (dtCompInfo.Rows[i][0].ToString().Equals(dtCompInfo.Rows[j][0].ToString()) && dtCompInfo.Rows[i][3].ToString().Equals(dtCompInfo.Rows[j][3].ToString()
{
ret = string.Format("Excel数据中第{0}行和第{1}行数据重复",i+2, j+2);
break;
}
{
ret = string.Format("Excel数据中第{0}行和第{1}行数据重复",i+2, j+2);
break;
}
对于第五条:没啥好说的就是用SqlBulkCopy 来实现插入
代码
#region 数据批量导入数据库
/// <summary>
/// 数据批量导入数据库
/// </summary>
/// <param name="dt">需要导入的数据</param>
/// <param name="tableName">对应数据库中的表名</param>
public static void ExportDate(DataTable dt,string tableName)
{
SqlConnection mycon = new SqlConnection(conn);
SqlBulkCopy bulkCopy = new SqlBulkCopy(mycon);
bulkCopy.DestinationTableName = tableName;
bulkCopy.BatchSize = dt.Rows.Count;
try
{
mycon.Open();
if (dt != null && dt.Rows.Count != 0)
{
bulkCopy.WriteToServer(dt);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
mycon.Close();
if (bulkCopy != null)
{
bulkCopy.Close();
}
}
}
#endregion
/// <summary>
/// 数据批量导入数据库
/// </summary>
/// <param name="dt">需要导入的数据</param>
/// <param name="tableName">对应数据库中的表名</param>
public static void ExportDate(DataTable dt,string tableName)
{
SqlConnection mycon = new SqlConnection(conn);
SqlBulkCopy bulkCopy = new SqlBulkCopy(mycon);
bulkCopy.DestinationTableName = tableName;
bulkCopy.BatchSize = dt.Rows.Count;
try
{
mycon.Open();
if (dt != null && dt.Rows.Count != 0)
{
bulkCopy.WriteToServer(dt);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
mycon.Close();
if (bulkCopy != null)
{
bulkCopy.Close();
}
}
}
#endregion