문제

Excel에서 데이터를 가져온 다음 처리하는 C#/. 순 작업이 있습니다. 우리의 클라이언트는 파일을 제거하고 파일을 처리합니다 (원본 파일을 제어하지 않기 때문에 중요).

나는 OLEDB 라이브러리를 사용하여 데이터 세트를 작성합니다 (나는 그 코드를 쓰는 것을 싫어합니다. 진지하게, .NET 개발자가 그보다 더 많은 글을 쓰는 코드가 있습니까?). 파일에는 30829300, 30071500 등과 같은 일부 숫자가 포함되어 있습니다 ... 해당 열의 데이터 유형은 "텍스트"입니다.

이 숫자는 데이터를 가져올 때 과학 표기법으로 변환됩니다. 어쨌든 이런 일이 발생하지 않도록해야합니까?

-Chris

도움이 되었습니까?

해결책

OLEDB 라이브러리 ~ 할 것이다, 더 자주, Excel 스프레드 시트에서 데이터를 엉망으로 만들었습니다. 이것은 대부분 모든 것을 고정형 열 레이아웃으로 강제하기 때문입니다. 추측 각 열의 첫 8 셀의 값으로부터 각 열의 유형에서. 그것이 잘못되었다고 생각하면, 당신은 과학적 구조로 변환 된 숫자 문자열로 끝납니다. 블레치!

이를 피하기 위해 OLEDB를 건너 뛰고 시트를 직접 읽는 것이 좋습니다. Excel의 COM 인터페이스 (Blech!) 또는 타사 .NET Excel 호환 리더의 COM 인터페이스를 사용하여이를 수행 할 수 있습니다. 스프레드 시트 기어 합리적으로 잘 작동하는 라이브러리 중 하나이며 Excel의 COM 인터페이스와 매우 유사한 인터페이스가 있습니다.

다른 팁

이 문제에 대한 한 가지 해결 방법은 선택 * 대신 선택 문을 변경하는 것입니다.

"SELECT Format([F1], 'General Number')  From [Sheet1$]"
 -or-
"SELECT Format([F1], \"#####\")  From [Sheet1$]"

그러나 셀에 다음 오류가있는 255 개 이상의 문자가 포함 된 경우 그렇게하면 "다중 단계 OLE DB 작업 생성 오류. 가능한 경우 각 OLE DB 상태 값을 확인하십시오. 작업이 완료되지 않았습니다."

다행히도 내 고객은이 시나리오에서 오류를 오류하는 것에 신경 쓰지 않았습니다.

이 페이지에는 시도해야 할 좋은 것들도 있습니다.http://www.dicks-blog.com/archives/2004/06/03/external-data-mixed-data-tata-types/

이 연결 문자열 사용 :

Provider=Microsoft.ACE.OLEDB.12.0; data source={0}; Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1\"

Excel 2010을 사용하면 다음을 발견했습니다. OLEDB를 실행할 때 Excel 파일이 열려 있으면 SELECT를 선택하면 저장된 파일 값이 아닌 현재 버전의 셀을 얻습니다. 또한 문자열 값은 긴 숫자로 반환되며 소수점 값 및 날짜는 다음과 같습니다.

5.0130370071e+012
4.08
36808

파일이 열리지 않으면 반환 된 값은 다음과 같습니다.

5013037007084
£4.08
Monday, October 09, 2000

Open XML SDK 2.0 생산성 도구를 사용하여 실제 .XSLX 파일을 살펴보면 (또는 파일을 압축하고 메모장에서 XML을 보는 것만) Excel 2007이 실제로 원시 데이터를 과학적 형식으로 저장한다는 것을 알 수 있습니다.

예를 들어 0.00001은 1.0000000000000001E-5로 저장됩니다

<x:c r="C18" s="11" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  <x:v>1.0000000000000001E-5</x:v>
</x:c>

Excel에서 셀을 보면 셀과 포뮬러 바 둘 다에서 0.00001로 표시됩니다. 따라서 OLEDB가 문제를 일으키는 것은 항상 사실이 아닙니다.

가장 쉬운 방법은 '숫자'가 큰 열에 대한 텍스트 형식보다는 Zip 형식을 선택하는 것입니다.

필드의 가치를 읽을 때 필드의 가치를 (int) 또는 아마도 (int64)로 캐스팅 해 보셨습니까?

imex = 1 연결 문자열 옵션 및 Google에서 TypeGuessrows 레지스트리 설정을 찾으십시오. 사실, 독자는 처음 몇 행 (기본적으로 8)을 보면서 열 데이터 유형을 유추하기 때문에 쉽게 이런 방법이 없습니다. 행에 모든 숫자가 포함되어 있으면 운이 좋지 않습니다.

내가 과거에 사용한 불행한 해결 방법은 HDR = 연결 문자열 옵션을 사용하고 TypeGuessrows 레지스트리 설정 값을 1로 설정하는 것입니다. 헤더. 해킹이지만 작동합니다. 코드는 첫 번째 행 (헤더 포함)을 텍스트로 읽은 다음 그에 따라 데이터 유형을 설정합니다.

레지스트리를 변경하는 것은 통증이지만 (항상 가능하지는 않습니다), 나중에 원래 값을 복원하는 것이 좋습니다.

가져 오기 데이터에 헤더 행이없는 경우 대체 옵션은 파일을 사전 처리하고 불쾌한 열의 각 숫자 앞에 '문자를 삽입하는 것입니다. 이로 인해 열 데이터가 텍스트로 취급됩니다.

대체로,이 문제를 해결하기 위해 많은 해킹이 있지만 실제로는 완벽하지 않습니다.

나는이 같은 문제가 있었지만 Excel Com 인터페이스 또는 타사 소프트웨어에 의지하지 않고도 일할 수있었습니다. 약간의 처리 오버 헤드가 포함되지만 저에게 효과가있는 것 같습니다.

  1. 칼럼 이름을 얻으려면 먼저 데이터를 읽으십시오.
  2. 그런 다음 각 열에 새 데이터 세트를 작성하여 각 데이터 유형을 문자열로 설정하십시오.
  3. 이 새로운 데이터 세트에 다시 데이터를 읽으십시오. Voila- 과학 표기법은 이제 사라지고 모든 것이 문자열로 읽습니다.

다음은 이것을 보여주는 몇 가지 코드입니다. 추가 보너스로서 스타일링됩니다!

public void ImportSpreadsheet(string path)
{
    string extendedProperties = "Excel 12.0;HDR=YES;IMEX=1";
    string connectionString = string.Format(
        CultureInfo.CurrentCulture,
        "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"{1}\"",
        path,
        extendedProperties);

    using (OleDbConnection connection = new OleDbConnection(connectionString))
    {
        using (OleDbCommand command = connection.CreateCommand())
        {
            command.CommandText = "SELECT * FROM [Worksheet1$]";
            connection.Open();

            using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
            using (DataSet columnDataSet = new DataSet())
            using (DataSet dataSet = new DataSet())
            {
                columnDataSet.Locale = CultureInfo.CurrentCulture;
                adapter.Fill(columnDataSet);

                if (columnDataSet.Tables.Count == 1)
                {
                    var worksheet = columnDataSet.Tables[0];

                    // Now that we have a valid worksheet read in, with column names, we can create a
                    // new DataSet with a table that has preset columns that are all of type string.
                    // This fixes a problem where the OLEDB provider is trying to guess the data types
                    // of the cells and strange data appears, such as scientific notation on some cells.
                    dataSet.Tables.Add("WorksheetData");
                    DataTable tempTable = dataSet.Tables[0];

                    foreach (DataColumn column in worksheet.Columns)
                    {
                        tempTable.Columns.Add(column.ColumnName, typeof(string));
                    }

                    adapter.Fill(dataSet, "WorksheetData");

                    if (dataSet.Tables.Count == 1)
                    {
                        worksheet = dataSet.Tables[0];

                        foreach (var row in worksheet.Rows)
                        {
                            // TODO: Consume some data.
                        }
                    }
                }
            }
        }
    }
}

나는이 상태를 둘러 보았다 .. 여기 내 용매 단계가있다

  • 템플릿 엑셀 파일의 경우

1- 텍스트로서의 1- 형식 Excel Coloumn 2- 숫자에 대한 오류 경고를 비활성화하기 위해 매크로를 쓰기-> 텍스트 변환

  Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.ErrorCheckingOptions.BackgroundChecking = Ture
End Sub
Private Sub Workbook_Open()
Application.ErrorCheckingOptions.BackgroundChecking = False
End Sub
  • CodeBehind에

3- 가져 오기 위해 데이터를 읽는 동안 들어오는 데이터를 INT64 또는 Int32로 구문 분석하려고 시도합니다 ....

누군가가 이것에 대한 답을 얻었는지 알고 싶습니다. 나는 인터 웹을 모두 위아래로했고 IMEX와 HDR의 모든 조합을 시도했습니다. IMEX = 1은 날짜, 통화 및 일반 숫자 값을 추출한 유일한 것입니다. 그러나 큰 숫자는 여전히 과학적으로 보여줍니다. 파일 만 읽고 스프레드 시트를 변경하면 제 3자가 옵션이 아닙니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top