SqlBulkCopy를 사용하여 asp.net의 Excel 파일 업로드

asp.net c# excel sqlbulkcopy

문제

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

수락 된 답변

안녕 내 기존 코드에서 다음 섹션을 변경하는 문제를 해결했습니다.

"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' 이 혼합 데이터 유형을 가져 오기위한 트릭을 수행한다고 생각합니다.

감사


인기 답변

Excel의 단점을 다루는 재미 있고 흥미 진진한 세계에 오신 것을 환영합니다. 또한 Excel 스프레드 시트를 데이터 소스로 사용하는 것이 나쁜 생각입니다. 슬프게도이 부분은 올바르게 작동하기 위해 더 많은 노력을 기울일 것입니다.

각 행을 확인하고 각 열에 적합한 유형 변환을 수행해야합니다. 가장 간단한 방법은 원본 데이터를 DataTable 에 읽어서 WriteToServer 메서드에 전달하는 것입니다.

그래서 ... 호환되는 DataTable 만들고 Read() 를 사용하여 Ole IDataReader 인스턴스 전체를 반복하고 필드 데이터를 읽는 다양한 Get*() 메서드를 채워서 채 웁니다. 문자열이기 때문에 숫자를 읽지 못하면 문자열을 Int32.TryConvert(...) 또는 유사하게 사용하여 문자열을 올바른 숫자 형식으로 변환합니다. 데이터의 끝에 도달하면 ( Read() 가 false를 반환 함) DataTable 을 위에서 설명한 것과 같은 방법으로 SqlBulkCopy 를 사용하여 SQL 서버에 덤프 할 수 있습니다.

한 가지 바로 가기는 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;
}


아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.