Henehefu 用 ウィキ

メニュー



- Views

最近の更新

取得中です。

CSharp > OleDbOffice


※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

C#でCSV、Excel、Accessファイル(.csv, .xls, .xlsx, .mdb, .accdb)をOLE DBで開く


OLE DBですべてのテーブル(シート)のデータを表示する。
2003,2007いずれでも開ける(ハズ)。

サンプルコード

class Program
    {
        static void Main(string[] args)
        {
#if !false
            var path = @"r:\hoge.mdb";
#else
            var path = @"r:\hoge.xls";
#endif
            try {
                OpenOleDb(path);
            }
            catch(Exception ex) {
                Console.Error.WriteLine(ex.Message);
            }
            Console.WriteLine("終わり");
            Console.ReadLine();
        }
 
        private static void OpenOleDb(string path)
        {
            var print = GetPrintMethod("cui");
            path.ToConnectionString().OpenDatabase(cmd => {
                var queries =
                    from tableName in cmd.Connection.GetTableNames().ToArray()
                    select string.Format("SELECT * FROM [{0}] ", tableName);
 
                foreach(var query in queries) {
                    Debug.WriteLine(query);
                    cmd.Execute(query, reader => reader.Dump(print));
                }
            });
        }
 
        private static Action<IEnumerable<object>> GetPrintMethod(string mode)
        {
            switch(mode) {
#if false
                case "gui":
                    return row => {
                        Console.WriteLine("あばばばば");
                    };
#endif
                case "cui":
                    return row => {
                        var cells = row.Select(cell => cell.ToString()).ToArray();
                        var line = string.Join(", ", cells);
                        Console.WriteLine(line);
                    };
                default:
                    return row => {};
            }
        }
    }
 
    public static class OleDbExtensions
    {
        public static string ToConnectionString(this string path)
        {
            return path.ToConnectionString(true);
        }
 
        public static string ToConnectionString(this string path, bool hasHeader)
        {
            var mode = Path.GetExtension(path).ToLower();
            return path.ToConnectionString(hasHeader, mode);
        }
 
        public static string ToConnectionString(this string path, bool hasHeader, string mode)
        {
            var hdr = (hasHeader ? "Yes" : "No");
 
            // Make tuple func
            Func<string, string, KeyValuePair<string, string>> _ =
                (key, value) => new KeyValuePair<string, string>(key, value);
 
            // keywords
            var kProvider = "Provider";
            var kDatasource = "Data Source";
            var kExtendedProperties = "Extended Properties";
 
            var kpMicrosoftJet4 = "Microsoft.Jet.OLEDB.4.0";
            var kpMicrosoftAce12 = "Microsoft.ACE.OLEDB.12.0";
 
            // dictionary { key => tuple[] }
            var dict = new Dictionary<string, KeyValuePair<string, string>[]>(){
                {
                    ".csv", // CSV
                    new[]{
                        _(kProvider, kpMicrosoftJet4),
                        _(kDatasource, Path.GetDirectoryName(path)),
                        _(kExtendedProperties, string.Format("text;HDR={0};FMT=Delimited", hdr)),
                    }
                },
                {
                    ".xls", // excel 2003
                    new[]{
                        _(kProvider, kpMicrosoftJet4),
                        _(kDatasource, path),
                        _(kExtendedProperties, string.Format("Excel 8.0;HDR={0};IMEX=1", hdr)),
                    }
                },
                {
                    ".xlsx", // excel 2007
                    new[]{
                        _(kProvider, kpMicrosoftAce12),
                        _(kDatasource, path),
                        _(kExtendedProperties, string.Format("Excel 12.0 Xml;HDR={0};IMEX=1", hdr)),
                    }
                },
                {
                    ".mdb",// access 2003
                    new[]{
                        _(kProvider, kpMicrosoftJet4),
                        _(kDatasource, path),
                    }
                },
                {
                    ".accdb",// access 2007
                    new[]{
                        _(kProvider, kpMicrosoftAce12),
                        _(kDatasource, path),
                        _("Persist Security Info", "False")
                    }
                },
            };
 
            // create connection string
            KeyValuePair<string, string>[] ps;
            if(dict.TryGetValue(mode, out ps)){
                var builder = new OleDbConnectionStringBuilder();
                foreach(var p in ps) {
                    builder[p.Key] = p.Value;
                }
                return builder.ConnectionString;
            }
            else{
                throw new NotImplementedException();
            }
        }
 
        public static void OpenDatabase(this string connectionString, Action<OleDbCommand> act)
        {
            using(var cnn = new OleDbConnection(connectionString))
            using(var cmd = cnn.CreateCommand()) {
                cnn.Open();
                act(cmd);
            }
        }
 
        public static IEnumerable<string> GetTableNames(this OleDbConnection cnn)
        {
            var table = cnn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,
                new object[] { null, null, null, "TABLE" });
            var names =
                from row in table.Rows.OfType<DataRow>()
                select row["TABLE_NAME"].ToString();
            return names;
 
        }
 
        public static void Execute(this OleDbCommand cmd, string query, Action<OleDbDataReader> act)
        {
            cmd.CommandText = query;
            try {
                using(var reader = cmd.ExecuteReader()) {
                    act(reader);
                }
            }
            catch(Exception ex) {
                Console.Error.WriteLine(ex.Message);
            }
        }
 
        public static IEnumerable<string> GetColumnNames(this OleDbDataReader reader)
        {
            var columns =
                from index in Enumerable.Range(0, reader.FieldCount)
                select reader.GetName(index);
            return columns;
        }
 
        public static IEnumerable<IEnumerable<object>> GetRows(this OleDbDataReader reader)
        {
            Func<DbDataRecord,IEnumerable<object>> getCells = row => {
                var values = new object[row.FieldCount];
                var count = row.GetValues(values);
                return values.Take(count);
            };
 
            var rows =
                from row in reader.OfType<DbDataRecord>()
                select getCells(row);
            return rows;
        }
 
        public static void Dump(this OleDbDataReader reader, Action<IEnumerable<object>> print)
        {
            var columns = reader.GetColumnNames().Cast<object>();
 
            var rows = reader.GetRows();
 
            print(columns);
            foreach(var row in rows) {
                print(row);
            }
        }
    }
 
う~ん、また一つ他人が読めないコードを書いてしまった。

注記

CSVの場合、Data Sourceにファイル名ではなくディレクトリを指定する。
ファイル名がテーブル名になるみたい。

CSVやExcelの場合、ほとんどの人はフリーダムにレイアウトするので
すべてのデータは読み込めないかもしれない。

OLE DBの制限で列数が255以下のテーブルしか読めない(たしか)。

その他のConnectionStringについては http://www.connectionstrings.com/ 参照。
MS Office 2007 がインストールされていない環境で2007のファイルを開くには
2007 Office system ドライバ: データ接続コンポーネントが必要かもしれない。

タグ一覧