C#からExcelファイルを読み取る


233

C#プログラムから直接Excelファイル(.xls)を読み取るための無料またはオープンソースのライブラリはありますか?

ワークシートを選択してデータを文字列として読み取るだけで、それほど凝ったものにする必要はありません。これまでは、ExcelのUnicodeテキストへのエクスポート機能を使用して、結果の(タブ区切り)ファイルを解析してきましたが、手動の手順は省きたいと思います。

回答:


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"),
                    });

このアプローチの選択のように思われる場合は、列のデータ型を推測し、推測されたデータ型を強制しようとします。たとえば、主にdouble値を持つ列がある場合、x.Field <string>を渡すのは望ましくありませんが、x.Field <double>が必要です。これは本当ですか?
Kevin Le-Khnle

1
MSDNで調べたところです。<T>は、列の内容を型にキャストするために使用されているようです。この例では、列のデータを文字列にキャストしています。doubleが必要な場合は、double.Parse(x.Field <string>( "Cost")またはそのようなものを呼び出す必要があります。FieldはDataRowの拡張メソッドであり、非ジェネリックバージョンがないようです。
Robin Robinson

Linqクエリにdouble.Parseを追加すると、速度が大幅に低下しますか?
匿名タイプ

23
注あなたが読んでいる場合というxlsx、あなたの代わりにこの接続文字列を使用する必要がありますstring.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", fileName)
アンドレアス・グレック

7
残念ながら、Jet.OLEDBドライバーは64ビット互換ではありません。Any CPUではなくターゲットx86に切り替える必要があります(この方法を続行する場合)。あるいは64ビットACEドライバをインストールし、(アンドレアスによって示されるように)、このドライバを使用するCONN文字列を変更- microsoft.com/en-us/download/...
ダンカン

83

Excelファイルに含まれる単純なデータの場合は、ADO.NET経由でデータを読み取ることができます。ここにリストされている接続文字列を参照してください。

http://www.connectionstrings.com/?carrier=excel2007 または http://www.connectionstrings.com/?carrier=excel

-ライアン

更新:その後、次のような方法でワークシートを読み取ることができます select * from [Sheet1$]


1
この方法は断然最速です。
StingyJack 2009年

17
もちろん、そうではありません、スティンギー。すべてのデータをふるいにかけ、くだらないDBコードを作成する必要があります(モデルを手作りし、列をプロパティにマップし、yadda yadda)。最も簡単な方法は、他の貧弱なSOBにこれを実行させることです。そのため、人々はすべてを下から上に書く代わりにフレームワークを使用しています。

12
無駄な方法!読み取ったときにテキスト列を255文字に切り捨てます。注意してください!参照:stackoverflow.com/questions/1519288/…ACE エンジンは同じことをします!
Triynko

5
ADO.NETを使用してexelからデータを読み取るには、Microsoft AccessまたはMicrosoft Accessデータベースエンジンの再頒布可能パッケージをインストールする必要があることに注意してください。
zihotki

3
ドライバーは、最初の数行に基づいて、列の型も推測します。最初の行に整数のように見える列がある場合、非整数(フロート、文字列など)を
Brian Low

27

ADO.NETのアプローチは迅速かつ簡単ですが、特にDataTypeの処理方法に関して、注意すべきいくつかの癖があります。

この優れた記事は、いくつかの一般的な落とし穴を回避するのに役立ちます: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、2011

21

Excelデータリーダーはどうですか?

http://exceldatareader.codeplex.com/

私は、さまざまなExcelファイルからSQL Server Compactに大量のデータを引き出すために、運用環境で怒りの中で使用しました。それは非常にうまく機能し、かなり堅牢です。


2
私は2番目のExcelデータリーダーです。また、NUnit 2.5のTestCaseSource属性を使用してExcelスプレッドシートを使用したデータ駆動型テストを驚くほど簡単にする、非常に便利なExcelデータ駆動型テストライブラリにもつながりました。ResharperはまだTestCaseSourceをサポートしていないため、NUnitランナーを使用する必要があることに注意してください。
David Keaveny、

残念ながら、このライブラリにはいくつかの問題があります。まず、日付として表示される通貨フィールドがいくつかありました。次に、ワークブックに空のシートが含まれているとクラッシュします。そのため、統合は非常に簡単でしたが、このライブラリを引き続き使用するかどうかを再評価しています。積極的に開発されているようには見えません。
Ian1971 2012年

また、xlsxファイルにいくつかのオプションの要素が存在し、それらが存在しない場合にデータの読み取りに失敗することも想定しています。
RichieHindle、

SQL Server Reporting ServicesからのExcelファイルに問題があります。それらを開いて保存しない限り(編集されていない場合でも)、機能しません。@RichieHindle:どんなオプションの要素について話しているのですか(これが私のSSRS Excelファイルで役立つことを願っています)?
Peter

@ピーター:それは私にとって問題を引き起こし<dimension><worksheet>いた欠落した要素だったと思います。
RichieHindle 2013年

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

これ以上のチェリアンに同意できませんでした。このコードは何年も前のものです... Resharperに習熟する前でした:)
hitec

2
コードは醜いですが、シート名を取得する方法を示しています。
サム

15

Koograは、C#で記述されたオープンソースのコンポーネントで、Excelファイルの読み取りと書き込みを行います。


たとえば、NPOIと比較して、特にアクティブに見えない
デビッドバートン


8

少し前にC#でExcelファイルから多くの読み取りを行い、2つの方法を使用しました。

  • COMAPI。Excelのオブジェクトに直接アクセスし、メソッドとプロパティを介してそれらを操作します。
  • データベースのようにExcelを使用できるようにするODBCドライバー。

後者のアプローチははるかに高速でし。20列と200行の大きなテーブルを読み取る場合、COM経由で30秒、ODBC経由で0.5秒かかります。したがって、必要なのがデータだけの場合は、データベースアプローチをお勧めします。

乾杯、

カール


6

ExcelMapperは、Excelワークシートを厳密に型指定されたオブジェクトとして読み取るために使用できるオープンソースツール(http://code.google.com/p/excelmapper/)です。xlsとxlsxの両方のフォーマットをサポートしています。


6

.NETでxls / xlsxファイルを読み取る簡単な方法を紹介します。以下がお役に立てば幸いです。

 プライベートDataTable ReadExcelToTable(文字列パス)    
 {

     //接続文字列

     string connstring = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source =" + path + "; Extended Properties = 'Excel 8.0; HDR = NO; IMEX = 1';";  
     //同じ名前 
     // string connstring = Provider = Microsoft.JET.OLEDB.4.0; Data Source = "+ path + //"; Extended Properties = 'Excel 8.0; HDR = NO; IMEX = 1'; "; 

     using(OleDbConnection conn = new OleDbConnection(connstring))
     {
        conn.Open();
        //すべてのシート名を取得
        DataTable sheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables、new object [] {null、null、null、 "Table"});  

        //最初のシート名を取得します
        string firstSheetName = sheetName.Rows [0] [2] .ToString(); 

        //クエリ文字列 
        string sql = string.Format( "SELECT * FROM [{0}]"、firstSheetName); 
        OleDbDataAdapter ada = new OleDbDataAdapter(sql、connstring);
        DataSet set = new DataSet();
        ada.Fill(set);
        set.Tables [0];を返します。   
   }
 }

コードは記事からです:http : //www.c-sharpcorner.com/uploadfile/d2dcfc/read-excel-file-with-net/。あなたはそれからより多くの詳細を得ることができます。


2
それはだった、sheetnamesを読んだ程度、特に一部役に立ちます。
martinstoeckli 2012年

4

無料ではありませんが、最新のOfficeには非常に優れたオートメーション.Net APIがあります。(長い間APIが使用されていましたが、厄介なCOMでした)Officeアプリが非表示のバックグラウンドプロセスのままで、コード内で必要なすべてのことを実行できます。


3
@ Anonymous-type私は質問を読み、希望するOSS実装の有用な代替案を提供していました...なぜなら、まあ、利用できるものが何もないことはかなり確信していたからです。また、受け入れられた回答から判断すると、Officeをインストールする要件は問題ではありません。
xanadont 2010

3

ここで私がベースから外れていても許してください、しかしこれはOffice PIAの目的ではありませんか?


5
はい。ただし、Excel.Applicationインスタンスの作成、xlsファイルの読み込みなどが含まれます。純粋にファイルからデータを読み取る必要がある場合は、説明したADO.NETメソッドのいずれかを使用する方がはるかに簡単ではるかに軽量です。他の答えで。
アダムラルフ

遅すぎて、Office PIAをベースラインとして使用すると、.Value2プロパティから渡されたオブジェクト配列を使用するだけでも、他のすべてが速くなります。まだPIAを使用しています。
匿名タイプ

3

最近、部分的にLINQを改善するために... Excelの自動化APIを使用してファイルをXMLスプレッドシートとして保存し、LINQ to XMLを使用してそのファイルを処理しています。


私はあなたがそれをExcelから保護することができると思いますが、コンパイラを持つ人からではありません...他のように...それは単なるバイトです。
ケニー

@ gsvirdi、Excelファイルのセキュリティに関する別の質問を投稿してください。この質問はパフォーマンスに関するものです。
匿名タイプ


3

SmartXLSは、Excelチャート、数式エンジンのほとんどの機能をサポートする別のExcelスプレッドシートコンポーネントで、excel2007 openxml形式の読み取り/書き込みができます。



2

無料で使いやすい.NETライブラリであるFileHelpersライブラリをお勧めします。これは、EXCELからデータをインポート/エクスポートしたり、ファイル、文字列、ストリームなどの固定長または区切りレコードをインポートしたり、その他の機能を追加したりするために使用します。

Excelデータリンクのドキュメントセクション http://filehelpers.sourceforge.net/example_exceldatalink.html


1
私はあなたを倒しませんが、最近FileHelpersを使い始めて、それがいかに... たとえば、csvの列をプロパティにマップする唯一の方法は、失礼ですが、モデルのFIELDS は、列の順序でフィールドを作成することです。私はあなたのことを知りませんが、私のf8kingフレームワークの最も中心的な設計上の考慮事項の1つについて、コンパイラーの癖に頼るつもりはありません。


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でプログラムするように頼んだら、あなたが方法がわからないふりをするのが最善です)

(編集:ああそう、ロブとライアンはどちらも正しい)


1

私は人々がこの目的のためにExcelの「拡張」を作成していることを知っています。
あなたは多かれ少なかれExcelに「プログラムXにエクスポートする」と書かれたボタンを作り、そしてプログラムが読むことができるフォーマットでデータをエクスポートして送り出します。

http://msdn.microsoft.com/en-us/library/ms186213.aspxから始めるのが良いでしょう。

幸運を


1

いくつかのExcelファイルの管理を必要とする簡単なデモプロジェクトを実行しました。GemBoxソフトウェアの.NETコンポーネントは、私のニーズには十分でした。それはいくつかの制限付きの無料版を持っています。

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


参考:試してみましたが、暗号化されたファイルを読み取ることができなかったためです。
チャド

1

Excelパッケージは、Excel 2007ファイルを読み書きするためのオープンソース(GPL)コンポーネントです。小さなプロジェクトで使用しましたが、APIは単純です。XLSXでは機能せず、XLSXでのみ機能します(Excel 200&)。

ソースコードもよく整理されており、簡単に移動できます(機能を拡張したり、マイナーな問題を修正したりする必要がある場合)。

最初はADO.Net(Excel接続文字列)のアプローチを試しましたが、厄介なハッキングに悩まされていました。たとえば、2行目に数値が含まれていると、下の列のすべてのフィールドにintが返され、静かにデータがドロップされますそれは適合しません。


1

かなり大きなシステムではClosedXMLを使用します。

  • 自由
  • インストールが簡単
  • 簡単なコーディング
  • 非常に迅速なサポート
  • 開発者チームは新しい提案を非常に受け入れることができます。多くの場合、新機能とバグ修正は同じ週に実装されます

1

Take.ioスプレッドシートはこの作業を無料で行います。ただ、見とるこれを


これは本当に素晴らしい小さなライブラリです。それはすべてを文字列のリストのリストに変換するだけです。
Drewmate

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.