C #에서 Excel 파일 읽기


233

C # 프로그램에서 직접 Excel 파일 (.xls)을 읽을 수있는 무료 또는 오픈 소스 라이브러리가 있습니까?

워크 시트를 선택하고 데이터를 문자열로 읽는 것만으로는 너무 화려 할 필요는 없습니다. 지금까지 Excel의 유니 코드로 내보내기 텍스트 기능을 사용하고 결과 (탭으로 구분 된) 파일을 구문 분석했지만 수동 단계를 제거하고 싶습니다.

답변:


153
var fileName = string.Format("{0}\\fileNameHere", Directory.GetCurrentDirectory());
var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", fileName);

var adapter = new OleDbDataAdapter("SELECT * FROM [workSheetNameHere$]", connectionString);
var ds = new DataSet();

adapter.Fill(ds, "anyNameHere");

DataTable data = ds.Tables["anyNameHere"];

이것이 내가 일반적으로 사용하는 것입니다. 테이블을 편집 할 때 일반적으로 AsEnumerable ()을 고정하기 때문에 약간 다릅니다.

var data = ds.Tables["anyNameHere"].AsEnumerable();

LINQ를 사용하여 필드에서 구조체를 검색하고 빌드 할 수 있습니다.

var query = data.Where(x => x.Field<string>("phoneNumber") != string.Empty).Select(x =>
                new MyContact
                    {
                        firstName= x.Field<string>("First Name"),
                        lastName = x.Field<string>("Last Name"),
                        phoneNumber =x.Field<string>("Phone Number"),
                    });

이 접근 방식의 선택처럼 보이는 경우 열의 데이터 유형을 추측하고 추측 된 데이터 유형을 강제합니다. 예를 들어, 주로 두 배의 값을 가진 열이 있으면 x.Field <string>을 전달하는 것이 좋지 않지만 x.Field <double>이 필요합니다. 이것이 사실입니까?
Kevin Le-Khnle

1
MSDN에서 찾아 보았습니다. <T>는 열의 내용을 유형으로 캐스팅하려고 시도한 것처럼 보입니다. 이 예제에서는 열의 데이터를 문자열로 캐스트합니다. double을 원한다면 double.Parse (x.Field <string> ( "Cost") 또는 이와 유사한 것을 호출해야합니다. Field는 DataRow의 확장 방법이며 일반 버전이 아닌 것 같습니다.
로빈 로빈슨

Linq 쿼리에 double.Parse를 추가하면 속도가 느려 집니까?
익명 유형

23
읽는 경우 xlsx대신이 연결 문자열을 사용해야합니다.string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", fileName)
Andreas Grech

7
안타깝게도 Jet.OLEDB 드라이버는 64 비트와 호환되지 않습니다. 모든 CPU 대신 대상 x86으로 전환해야합니다 (여전히이 방법으로 진행하려는 경우). 또는 64 비트 ACE 드라이버를 설치하고이 드라이버를 사용하도록 conn 문자열을 변경하십시오 (Andreas에 의해 표시됨) -microsoft.com/en-us/download/…
Duncan

83

Excel 파일에 포함 된 단순한 데이터 인 경우 ADO.NET을 통해 데이터를 읽을 수 있습니다. 여기에 나열된 연결 문자열을 참조하십시오.

http://www.connectionstrings.com/?carrier=excel2007 또는 http://www.connectionstrings.com/?carrier=excel

라이언

업데이트 : 그런 다음과 같은 것을 통해 워크 시트를 읽을 수 있습니다 select * from [Sheet1$]


1
이 방법은 훨씬 빠릅니다.
StingyJack

17
물론 사실이 아닙니다, Stingy. 모든 데이터를 조사하고 엉터리 DB 코드를 작성해야합니다 (손으로 모델을 작성하고 열을 속성에 매핑, yadda yadda). 가장 빠른 방법은 다른 가난한 SOB가 당신을 위해 이것을하도록하는 것 입니다. 그래서 사람들은 모든 것을 처음부터 작성하는 대신 프레임 워크를 사용합니다.

12
쓸모없는 방법! 읽을 때 텍스트 열을 255 자로 자릅니다. 조심해! 참조 : stackoverflow.com/questions/1519288/... ACE 엔진이 같은 일을!
Triynko

5
ADO.NET을 사용하여 exel에서 데이터를 읽으려면 Microsoft Access 또는 Microsoft Access Database Engine 재배포 가능 패키지가 설치되어 있어야합니다.
zihotki

3
또한 드라이버는 처음 몇 행을 기준으로 열 유형을 추측합니다. 첫 번째 행에 정수처럼 보이는 열이 있으면 정수가 아닌 (예 : 부동 소수점, 문자열)을 칠 때 오류가 발생합니다
Brian Low

27

ADO.NET 접근 방식은 쉽고 빠르지 만 특히 DataTypes 처리 방법과 관련하여 알아야 할 몇 가지 단점이 있습니다.

이 훌륭한 기사는 일반적인 함정을 피하는 데 도움이됩니다 : http://blog.lab49.com/archives/196


당신은 내 질문에 대답했습니다 (위의 의견 양식으로).
Kevin Le-Khnle

22

이것이 내가 Excel 2003에 사용한 것입니다.

Dictionary<string, string> props = new Dictionary<string, string>();
props["Provider"] = "Microsoft.Jet.OLEDB.4.0";
props["Data Source"] = repFile;
props["Extended Properties"] = "Excel 8.0";

StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> prop in props)
{
    sb.Append(prop.Key);
    sb.Append('=');
    sb.Append(prop.Value);
    sb.Append(';');
}
string properties = sb.ToString();

using (OleDbConnection conn = new OleDbConnection(properties))
{
    conn.Open();
    DataSet ds = new DataSet();
    string columns = String.Join(",", columnNames.ToArray());
    using (OleDbDataAdapter da = new OleDbDataAdapter(
        "SELECT " + columns + " FROM [" + worksheet + "$]", conn))
    {
        DataTable dt = new DataTable(tableName);
        da.Fill(dt);
        ds.Tables.Add(dt);
    }
}

2
워크 시트가 정의되지 않았습니다 ... 다른 모든 것을 명확하게 정의한 후에 조금 이상한 것 같습니다.
Jeremy Holovacs

21

Excel 데이터 리더는 어떻습니까?

http://exceldatareader.codeplex.com/

프로덕션 환경에서 다양한 Excel 파일에서 SQL Server Compact로 많은 양의 데이터를 가져 오기 위해 분노했습니다. 그것은 잘 작동하고 오히려 강력합니다.


2
두 번째 Excel 데이터 리더입니다. 또한 NUnit 2.5의 TestCaseSource 속성을 사용하여 Excel 스프레드 시트를 사용한 데이터 기반 테스트를 엄청나게 쉽게 만드는 매우 유용한 Excel 데이터 기반 테스트 라이브러리를 만들었습니다. Resharper는 아직 TestCaseSource를 지원하지 않으므로 NUnit 러너를 사용해야합니다.
David Keaveny 5

불행히도, 우리가 방금 겪은이 라이브러리에는 몇 가지 문제가 있습니다. 먼저 일부 통화 필드가 날짜로 표시되었습니다. 둘째, 통합 문서에 빈 시트가 있으면 충돌이 발생합니다. 따라서 통합이 매우 쉽지만이 라이브러리를 계속 사용할지 여부를 다시 평가하고 있습니다. 적극적으로 개발되고 있지 않은 것 같습니다.
Ian1971

또한 xlsx 파일에 데이터가없는 경우 데이터를 읽지 못하게하는 일부 선택적 요소가 있다고 가정합니다.
RichieHindle

SQL Server Reporting Services에서 제공되는 Excel 파일에 문제가 있습니다. 그것들을 열어서 저장하지 않으면 (편집되지 않은 경우에도) 작동하지 않습니다. @RichieHindle : 무슨 선택적 요소에 대해 이야기하고 있습니까?
피터

@ 피터 : 나는 그것이 문제를 일으킨 <dimension>요소에서 누락 된 요소 라고 생각합니다 <worksheet>.
RichieHindle

16

몇 년 전에 .NET 1.1을 사용하여 C #으로 작성한 코드가 있습니다. 이것이 정확히 필요한 것인지 확실하지 않습니다 (최고의 코드가 아닐 수도 있습니다 :).

using System;
using System.Data;
using System.Data.OleDb;

namespace ExportExcelToAccess
{
    /// <summary>
    /// Summary description for ExcelHelper.
    /// </summary>
    public sealed class ExcelHelper
    {
        private const string CONNECTION_STRING = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<FILENAME>;Extended Properties=\"Excel 8.0;HDR=Yes;\";";

        public static DataTable GetDataTableFromExcelFile(string fullFileName, ref string sheetName)
        {
            OleDbConnection objConnection = new OleDbConnection();
            objConnection = new OleDbConnection(CONNECTION_STRING.Replace("<FILENAME>", fullFileName));
            DataSet dsImport = new DataSet();

            try
            {
                objConnection.Open();

                DataTable dtSchema = objConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

                if( (null == dtSchema) || ( dtSchema.Rows.Count <= 0 ) )
                {
                    //raise exception if needed
                }

                if( (null != sheetName) && (0 != sheetName.Length))
                {
                    if( !CheckIfSheetNameExists(sheetName, dtSchema) )
                    {
                        //raise exception if needed
                    }
                }
                else
                {
                    //Reading the first sheet name from the Excel file.
                    sheetName = dtSchema.Rows[0]["TABLE_NAME"].ToString();
                }

                new OleDbDataAdapter("SELECT * FROM [" + sheetName + "]", objConnection ).Fill(dsImport);
            }
            catch (Exception)
            {
                //raise exception if needed
            }
            finally
            {
                // Clean up.
                if(objConnection != null)
                {
                    objConnection.Close();
                    objConnection.Dispose();
                }
            }


            return dsImport.Tables[0];
            #region Commented code for importing data from CSV file.
            //              string strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source=" + System.IO.Path.GetDirectoryName(fullFileName) +";" +"Extended Properties=\"Text;HDR=YES;FMT=Delimited\"";
            //
            //              System.Data.OleDb.OleDbConnection conText = new System.Data.OleDb.OleDbConnection(strConnectionString);
            //              new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM " + System.IO.Path.GetFileName(fullFileName).Replace(".", "#"), conText).Fill(dsImport);
            //              return dsImport.Tables[0];

            #endregion
        }

        /// <summary>
        /// This method checks if the user entered sheetName exists in the Schema Table
        /// </summary>
        /// <param name="sheetName">Sheet name to be verified</param>
        /// <param name="dtSchema">schema table </param>
        private static bool CheckIfSheetNameExists(string sheetName, DataTable dtSchema)
        {
            foreach(DataRow dataRow in dtSchema.Rows)
            {
                if( sheetName == dataRow["TABLE_NAME"].ToString() )
                {
                    return true;
                }   
            }
            return false;
        }
    }
}

더 많은 Cherian에 동의하지 못했습니다. 이 코드는 오래되었습니다 ... Resharper에 능숙하기 전에 :)
hitec

2
코드는 추악하지만 시트 이름을 얻는 방법을 보여줍니다.
Sam



8

얼마 전에 C #에서 Excel 파일을 많이 읽었으며 두 가지 접근 방식을 사용했습니다.

  • COM API : Excel 개체에 직접 액세스하고 메서드 및 속성을 통해 개체를 조작하는 COM API
  • 데이터베이스처럼 Excel을 사용할 수있는 ODBC 드라이버입니다.

후자의 접근 방식은 훨씬 빠릅니다. 20 개의 열과 200 개의 행이있는 큰 테이블을 읽으려면 COM을 통해 30 초, ODBC를 통해 0.5 초가 걸립니다. 따라서 데이터 만 있으면 데이터베이스 접근 방식을 권장합니다.

건배,



6

.NET으로 xls / xlsx 파일을 읽는 간단한 방법을 보여주고 싶습니다. 다음 내용이 도움이 되길 바랍니다.

 개인 DataTable ReadExcelToTable (문자열 경로)    
 {

     // 연결 문자열

     문자열 connstring = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source ="+ path + "; 확장 속성 = 'Excel 8.0; HDR = NO; IMEX = 1';";  
     // 같은 이름 
     // string connstring = Provider = Microsoft.JET.OLEDB.4.0; Data Source = "+ path + //"; 확장 속성 = 'Excel 8.0; HDR = NO; IMEX = 1'; "; 

     using (OleDbConnection conn = 새로운 OleDbConnection (connstring))
     {
        conn.Open ();
        // 모든 시트 이름 가져 오기
        DataTable sheetsName = conn.GetOleDbSchemaTable (OleDbSchemaGuid.Tables, 새 객체 [] {null, null, null, "Table"});  

        // 첫 번째 시트 이름 얻기
        string firstSheetName = sheetsName.Rows [0] [2] .ToString (); 

        // 쿼리 문자열 
        문자열 sql = string.Format ( "SELECT * FROM [{0}]", firstSheetName); 
        OleDbDataAdapter ada = new OleDbDataAdapter (sql, connstring);
        DataSet 세트 = 새로운 DataSet ();
        ada. 채우기 (세트);
        반환 집합. 테이블 [0];   
   }
 }

코드는 http://www.c-sharpcorner.com/uploadfile/d2dcfc/read-excel-file-with-net/ 기사에 있습니다. 더 자세한 정보를 얻을 수 있습니다.


2
특히 시트 이름을 읽는 데 도움 이 되었습니다 .
martinstoeckli

4

무료는 아니지만 최신 Office에는 매우 유용한 자동화 .Net API가 있습니다. (오래 동안 API가 있었지만 COM이 불쾌했습니다.) Office 앱이 숨겨진 백그라운드 프로세스로 유지되는 동안 코드에서 원하는 모든 작업을 수행 할 수 있습니다.


3
@ Anonymous-type 질문을 읽고 원하는 OSS 구현에 유용한 대안을 제공하고있었습니다. 허용 된 답변으로 판단하면 Office 설치 요구 사항은 문제가되지 않습니다.
xanadont

3

제가 기본이 아닌 경우 용서하십시오. 그러나 이것이 Office PIA의 목적 이 아닙니까?


5
예. 그러나 Excel.Application 인스턴스 생성, xls 파일로드 등이 필요합니다. 파일에서 일부 데이터를 읽어야하는 요구 사항이있는 경우 설명 된 ADO.NET 메서드 중 하나를 사용하는 것이 훨씬 쉽고 훨씬 쉽습니다. 다른 답변에서.
Adam Ralph

Office PIA를 기준으로 사용하면 너무 느립니다. .Value2 속성에서 전달 된 Object 배열을 사용하는 것만으로도 모든 것이 더 빠릅니다. 여전히 PIA를 사용하고 있습니다.
익명 유형

3

최근에 LINQ에서 더 나은 결과를 얻기 위해 ... Excel의 자동화 API를 사용하여 파일을 XML 스프레드 시트로 저장 한 다음 LINQ to XML을 사용하여 해당 파일을 처리했습니다.


Excel에서 보호 할 수는 있지만 컴파일러와 같은 사람 (예 : 바이트)은 아닙니다.
kenny

@gsvirdi, Excel 파일 보안에 대한 별도의 질문을 게시하십시오.이 질문은 성능에 관한 것입니다.
익명 유형


3

SmartXLS 는 Excel 차트, 수식 엔진의 대부분의 기능을 지원하고 excel2007 openxml 형식을 읽고 쓸 수있는 또 다른 Excel 스프레드 시트 구성 요소입니다.



2

EXCEL, 고정 길이 또는 파일, 문자열 또는 스트림의 구분 된 레코드 등에서 데이터를 가져 오거나 내보내려면 무료로 사용하기 쉬운 .NET 라이브러리 인 FileHelpers Library를 사용하는 것이 좋습니다.

Excel 데이터 링크 설명서 섹션 http://filehelpers.sourceforge.net/example_exceldatalink.html


1
나는 당신을 쓰러 뜨리지 않을 것이지만 최근에 FileHelpers를 사용하기 시작했고 그것이 얼마나 엉망인지 충격을 받았습니다. 예를 들어 csv의 열을 속성에 매핑하는 유일한 방법은 모델의 FIELDS 입니다. 열 순서대로 필드를 만드는 것 입니다. 나는 당신에 대해 모르지만 f8king 프레임 워크의 가장 중심적인 디자인 고려 사항 중 하나는 컴파일러에 의존하지 않을 것입니다.


2

SpreadsheetGear는 대단합니다. 예, 비용이지만 다른 솔루션과 비교하면 비용 가치가 있습니다. 빠르고 믿을 수 있으며 매우 포괄적이며 1 년 반 동안 풀 타임 소프트웨어 작업에서이 제품을 사용한 후에는 고객 지원이 환상적입니다.


Excel에서 읽고 쓸 수있는 간단하고 효과적인 방법 (무료)이 너무 많으면 정당화하기 어렵습니다.
익명 유형

2

우리가 사용한 솔루션은 다음을 필요로했습니다.

  • Excel 제작 파일 읽기 / 쓰기 허용
  • 빠른 성능 (안 COM이를 사용하여 같은)
  • MS Office 독립성 (MS Office가 설치된 클라이언트없이 사용할 수 있어야 함)
  • 무료 또는 오픈 소스 (그러나 적극적으로 개발)

몇 가지 선택 사항이 있지만 우리는 NPoi (Java의 기존 Poi 오픈 소스 프로젝트 의 .NET 포트)가 최고임을 발견 했습니다 . http://npoi.codeplex.com/

또한 .doc 및 .ppt 파일 형식으로 작업 할 수 있습니다


2

테이블 형식의 데이터 인 경우 여기에서 다운로드 할 수있는 Marcos Melli의 파일 데이터 도우미를 추천합니다 .



1

주어진 Excel 스프레드 시트를로드하고 csv (수동으로 수행하는 대신)로 저장하는 Excel 스프레드 시트를 작성할 수 있습니다.

C #에서 자동화 할 수 있습니다.

그리고 일단 csv에 들어가면 c # 프로그램이 그 사실을 알 수 있습니다.

(또한 누군가 누군가가 Excel로 프로그래밍하도록 요청하는 경우 방법을 모르는 척하는 것이 가장 좋습니다)

(편집 : 아 예, rob와 라이언은 모두 옳습니다)


1

나는 사람들이 이런 목적으로 Excel "확장자"를 만들고 있다는 것을 알고 있습니다.
Excel에서 "프로그램 X로 내보내기"라는 단추를 만든 다음 프로그램이 읽을 수있는 형식으로 데이터를 내보내고 보냅니다.

http://msdn.microsoft.com/en-us/library/ms186213.aspx 를 시작하는 것이 좋습니다.

행운을 빕니다


1

Excel 파일을 관리 해야하는 빠른 데모 프로젝트를 방금 수행했습니다. GemBox 소프트웨어의 .NET 구성 요소는 내 요구에 적합했습니다. 몇 가지 제한이있는 무료 버전이 있습니다.

http://www.gemboxsoftware.com/GBSpreadsheet.htm


참고 : 나는 그것을 시도했지만 암호화 된 파일을 읽을 수있는 필요성을 충족시키지 못했습니다.
Chad

1

Excel 패키지 는 Excel 2007 파일을 읽고 쓰는 데 필요한 오픈 소스 (GPL) 구성 요소입니다. 작은 프로젝트에서 사용했으며 API는 간단합니다. XLS가 아닌 XLSX (Excel 200 &)에서만 작동합니다.

소스 코드는 체계적으로 구성되어 있고 쉽게 해결할 수 있습니다 (기능을 확장하거나 사소한 문제를 해결 해야하는 경우).

처음에는 ADO.Net (Excel 연결 문자열) 접근 방식을 시도했지만 불쾌한 해킹이 발생했습니다. 예를 들어 두 번째 행에 숫자가 포함되어 있으면 아래 열의 모든 필드에 대해 정수를 반환하고 데이터를 자동으로 삭제합니다 맞지 않습니다.


1

우리 는 다소 큰 시스템에서 ClosedXML 을 사용 합니다.

  • 비어 있는
  • 설치가 용이
  • 직접 코딩
  • 매우 반응적인 지원
  • 개발자 팀입니다 이며 매우 새로운 제안을 엽니 다. 종종 같은 기능으로 새로운 기능과 버그 수정이 이루어집니다

1

Take.io스프레드 시트가 무료로이 작업을 수행합니다. 그냥 한 번 봐 가지고 .


이것은 정말 멋진 작은 도서관입니다. 모든 것을 문자열 목록으로 변환합니다. 필요한 작업에 적합합니다.
Drewmate

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.