2017-02-09 5 views
1

Я загружаю файл excel в asp.net C# с помощью следующего кода. Он работает нормально, но проблема в том, что в файле excel некоторые значения столбцов всегда являются числовыми, и если некоторые из этих числовых значений находятся в текстовом формате, а затем загружают нулевое значение. Это мой код - любое предложение, пожалуйста.Excel Загрузка файла в asp.net с использованием SqlBulkCopy

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

Ha вы проверяете погоду, ваш запрос возвращает все данные ??? –

+0

@NayanKatkani Не относится. Это проблема преобразования типов. – Corey

+0

@Corey, я думаю, что если это проблема с преобразованием типа, тогда он будет генерировать исключение. –

ответ

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' делает трюк, чтобы импортировать смешанный тип данных.

спасибо

0

Добро пожаловать в веселой и захватывающий мир борьбы с причудами Excel, и почему это плохая идея использовать электронную таблицу Excel в качестве источника данных. К сожалению, с вашей стороны вам потребуется немного больше работы, чтобы работать правильно.

Вам нужно будет проверять каждую строку и выполнять преобразования типов, подходящие для каждого столбца. Проще всего, вероятно, прочитать исходные данные в DataTable и передать это методу WriteToServer.

Итак ... создать совместимую DataTable и заполнить его итерация по IDataReader например Оле с помощью Read() для продвижения и различные Get*() методы для чтения данных полей. Когда ему не удается прочитать число, потому что это строка, используйте Int32.TryConvert(...) или аналогично преобразовать строку в правый цифровой формат. Как только вы достигнете конца данных (Read() вернет false), DataTable затем может быть сброшен на SQL-сервер с помощью SqlBulkCopy так же, как вы делаете выше.

Один ярлыка использовать as ключевое слово для обнаружения ошибок типа и нулевого оператора коалесцирующего ?? вызвать преобразование типа:

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