问题
I am uploading excel file in asp.net c# using following code.It is working fine but problem is that in excel file some column values are always numeric and if some of those numeric values are in text format then it is uploading null value. This is my code - any suggestion please.
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;
}
}
回答1:
Welcome to the fun and exciting world of dealing with Excel's quirks, and why it's a bad idea to use an Excel spreadsheet as a data source. Sadly this one is going to take a bit more work on your part to get working right.
You'll need to vet each row and perform type conversions as appropriate for each column. Simplest is probably to read the source data into a DataTable
and pass that to the WriteToServer
method.
So... create a compatible DataTable
and fill it by iterating across the Ole IDataReader
instance using Read()
to advance and the various Get*()
methods to read the field data. When it fails to read a number because it's a string use Int32.TryConvert(...)
or similar to convert the string to the right numeric format. Once you reach the end of the data (Read()
returns false) the DataTable
can then be dumped to the SQL server with the SqlBulkCopy
the same way as you're doing above.
One shortcut is to use the as
keyword to detect type errors and the ??
null coalescing operator to invoke a type conversion:
int? num = (reader.Item[1] as int?) ?? ParseInt(reader.GetString(1));
Alternatively you can use an extension method to do the conversion if possible:
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;
}
Add a similar one for AsString
(which is fairly simple) and you can convert your Excel IDataReader
to a DataTable
using something like this:
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;
}
回答2:
hi i have solved the issue changing following section in my existing code.
"Provider=Microsoft.ACE.OLEDB.12.0; " +
"Data Source=" + Server.MapPath(".") + "\\" + FileUpload.FileName +
";Extended Properties='Excel 12.0;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0';"
i think IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0'
does the trick to import mixed data type.
thanks
来源:https://stackoverflow.com/questions/42128419/excel-file-upload-in-asp-net-using-sqlbulkcopy