我正在使用以下代码在asp.net c#中上传excel文件。它工作正常但问题是在excel文件中,某些列值始终是数字,如果其中一些数值是文本格式,则上传为null值。这是我的代码 - 请提出任何建议。
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;
}
}
答案 0 :(得分:0)
欢迎来到处理Excel怪癖的有趣和令人兴奋的世界,以及为什么使用Excel电子表格作为数据源是个坏主意。可悲的是,为了让你的工作正常,你需要做更多的工作。
您需要审核每一行并根据每列执行类型转换。最简单的可能是将源数据读入DataTable
并将其传递给WriteToServer
方法。
所以...创建一个兼容的DataTable
并通过使用IDataReader
在Ole Read()
实例上进行迭代来填充它以推进和各种Get*()
方法来读取字段数据。当它无法读取数字时,因为它是一个字符串,使用Int32.TryConvert(...)
或类似字符串将字符串转换为正确的数字格式。一旦到达数据末尾(Read()
返回false),就可以使用DataTable
将SqlBulkCopy
转储到SQL服务器,方法与上面相同。
一种捷径是使用as
关键字来检测类型错误,使用??
null合并运算符来调用类型转换:
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;
}
答案 1 :(得分:0)
我已经解决了在现有代码中更改以下部分的问题。
"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'
可以导入混合数据类型。
感谢