使用SqlBulkCopy在asp.net中上传Excel文件

我在asp.net c#中使用下面的代码上传Excel文件。它工作正常,但问题是,在Excel文件中,某些列值始终是数字,如果这些数值中的一些是文本格式,那么它是上传空值。 这是我的代码 – 请任何build议。

if (!Convert.IsDBNull(FileUpload.PostedFile) & FileUpload.PostedFile.ContentLength > 0) { //FIRST, SAVE THE SELECTED FILE IN THE ROOT DIRECTORY. FileUpload.SaveAs(Server.MapPath(".") + "\\" + FileUpload.FileName); // File.Delete(Server.MapPath(FileUpload.FileName)); SqlBulkCopy oSqlBulk = null; // SET A CONNECTION WITH THE EXCEL FILE. OleDbConnection myExcelConn = new OleDbConnection( "Provider=Microsoft.ACE.OLEDB.12.0; " + "Data Source=" + Server.MapPath(".") + "\\" + FileUpload.FileName + ";Extended Properties=Excel 12.0;"); try { myExcelConn.Open(); // GET DATA FROM EXCEL SHEET. OleDbCommand objOleDB = new OleDbCommand("SELECT SSS.*,'" + Session["vUserName"].ToString() + "' FROM [Sheet1$] SSS", myExcelConn); // READ THE DATA EXTRACTED FROM THE EXCEL FILE. OleDbDataReader objBulkReader = null; objBulkReader = objOleDB.ExecuteReader(); // SET THE CONNECTION STRING. // con = new SqlConnection(dbcon); using (con = new SqlConnection(dbcon)) { con.Open(); // FINALLY, LOAD DATA INTO THE DATABASE TABLE. oSqlBulk = new SqlBulkCopy(con); oSqlBulk.DestinationTableName = "tmpStuffing"; // TABLE NAME. oSqlBulk.WriteToServer(objBulkReader); } lblConfirm.Text = "DATA IMPORTED SUCCESSFULLY."; lblConfirm.Attributes.Add("style", "color:green"); } catch (Exception ex) { lblConfirm.Text = ex.Message; lblConfirm.Attributes.Add("style", "color:red"); } finally { // CLEAR. oSqlBulk.Close(); oSqlBulk = null; myExcelConn.Close(); myExcelConn = null; } } 

欢迎来到处理Excel怪癖的有趣和令人兴奋的世界,以及为什么使用Excel电子表格作为数据源是一个坏主意。 不幸的是,为了让你的工作做得更好,你需要做更多的工作。

您需要审核每一行,并根据每列执行types转换。 最简单的可能是将源数据读入DataTable并将其传递给WriteToServer方法。

所以…创build一个兼容的DataTable ,并通过使用Read()遍历Ole IDataReader实例来遍历并填充它以及各种Get*()方法来读取字段数据。 当它无法读取数字,因为它是一个string使用Int32.TryConvert(...)或类似的将string转换为正确的数字格式。 一旦你到达数据的末尾( Read()返回false), DataTable就可以像上面那样用SqlBulkCopy转储到SQL服务器。

一个捷径是使用as关键字来检测types错误和?? null合并运算符来调用types转换:

 int? num = (reader.Item[1] as int?) ?? ParseInt(reader.GetString(1)); 

或者,如果可能,可以使用扩展方法进行转换:

 public static int? AsInt32(this IDataReader rdr, int index) { Type ft = rdr.GetFieldType(index); if (ft == typeof(int)) return rdr.GetInt32(index); else if (ft == typeof(string)) { int v; if (Int32.TryParse(rdr.GetString(index), out v)) return v; } else if (ft == typeof(object)) { object fv = rdr.GetValue(index); int? v = fv as int?; if (v != null) return v.Value; } return null; } 

添加一个类似的AsString (这是相当简单的),你可以使用这样的东西,将您的Excel IDataReader转换为DataTable

 public DataTable ImportData(IDataReader reader) { DataTable table = new DataTable(); table.Columns.Add("ID", typeof(int)); table.Columns.Add("UserName", typeof(string)); int rownum = 0; while (reader.Read()) { ++rownum; int? id = reader.AsInt32(0); if (id == null) throw new Exception(string.Format("Invalid ID on row {0}, value: {1}", rownum, reader.GetValue(0))); string name = reader.AsString(1); table.Rows.Add(id.Value, name); } return table; } 

嗨,我已经解决了我现有的代码中更改以下部分的问题。

 "Provider=Microsoft.ACE.OLEDB.12.0; " + "Data Source=" + Server.MapPath(".") + "\\" + FileUpload.FileName + ";Extended Properties='Excel 12.0;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0';" 

我认为IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0'伎俩导入混合的数据types。

谢谢