【问题标题】:Open Excel, Parse Data?打开 Excel,解析数据?
【发布时间】:2015-03-03 11:31:35
【问题描述】:

(替代标题:ReadAllLines Analogue for Excel?:加载和操作 Excel 数据的最佳方法是什么?)

我想快速打开一个 Excel 表格并执行文本操作。我希望该操作像 ReadAllLines (https://msdn.microsoft.com/en-us/library/s2tte0y1(v=vs.110).aspx) 一样工作,但适用于 Excel。

我发现了以下问题,但该问题已有 7 年历史。 Reading Excel files from C# (此外,这是一个具有历史意义的问题,已被冻结。此外,我没有 50 分,所以如果它打开,我将无法发表评论。)我将 Robin Robinson 的答案剪切并粘贴到 Visual Studio 中,仅更改路径:

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

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

var query = data.Where(x => x.Field<string>("id") != string.Empty).Select(x =>
            new 
            {
                id= x.Field<string>("id"),
            });

Fill 方法失败,“外部表不是预期格式”。

今天优秀的程序员都这样做吗?即,我应该调查 Jet 并查看是否有针对最新 Excel 的更新,还是有新的改进方法?

【问题讨论】:

  • 除了“似乎不起作用”之外,您没有说明发生了什么。它完全有可能工作,但您遇到了配置失败。与其提出一个新的模糊问题,不如在现有答案中添加评论。我知道您还没有足够的代表发表评论 - 但这并不意味着提出一个糟糕的问题是正确的前进方向。
  • 谢谢 - 但我不是在寻找您来解决问题。我问的是近七年后是否推荐这种做法。如果是,那么我会担心它为什么不起作用。我将通过这些 cmets 改进问题。
  • 老实说,我认为这不太可能成为一个很好的主题问题。
  • 谢谢,乔恩。这就是我的目标:我想快速拉入一个 Excel 文件以供控制台应用程序操作。有 LINQ to XML、LINQ to SQL,我有点期待 LINQ to Excel。 OLEDB是最好的方法吗?和数据集?似乎有更现代的东西。
  • 我可能会使用 Excel 互操作 API:msdn.microsoft.com/en-us/library/…

标签: c# excel-2013


【解决方案1】:

我根据 Jon Skeet 的使用 Interop 的建议拼凑了一个原型,以及 juliusz 在How do I import from Excel to a DataSet using Microsoft.Office.Interop.Excel? 上的回答

但是,有两点我真的不喜欢这个:首先,我似乎必须输入所有列名。其次,它将整个电子表格加载到内存中,而不是作为流读取(即使对于相对较小的电子表格也需要一分钟。

private static void Main(string[] args)
{
    var dataT = Import(@"C:\Users\jlambert\Desktop\dSmall_encrypted.xlsx");

    var data = dataT.AsEnumerable();
...
}
public static System.Data.DataTable Import(String path)
{
    var app = new Application();
    Workbook workBook = app.Workbooks.Open(path, 0, true, 5, "", "", true, XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);

    Worksheet workSheet = (Worksheet)workBook.ActiveSheet;

    int index = 0;
    object rowIndex = 2;

    System.Data.DataTable dt = new System.Data.DataTable();
    dt.Columns.Add("Facility_code");                    
    dt.Columns.Add("MRN");
    dt.Columns.Add("first_name");
    dt.Columns.Add("middle_name");
    dt.Columns.Add("last_name");
    dt.Columns.Add("address_line_1");
    dt.Columns.Add("address_line_2");
    dt.Columns.Add("city");
    dt.Columns.Add("state");
    dt.Columns.Add("zip");
    dt.Columns.Add("date_of_birth");
    dt.Columns.Add("gender");
    dt.Columns.Add("ssn");
    dt.Columns.Add("home_phone");
    dt.Columns.Add("work_phone");
    dt.Columns.Add("cell_phone");
    dt.Columns.Add("PCP");
    dt.Columns.Add("Practice Location");

    DataRow row;

    while (((Range)workSheet.Cells[rowIndex, 1]).Value2 != null)
    {
        rowIndex = 2 + index;
        row = dt.NewRow();
        row[0] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 1]).Value2);
        row[1] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 2]).Value2);
        row[2] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 3]).Value2);
        row[3] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 4]).Value2);
        row[4] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 5]).Value2);
        row[5] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 6]).Value2);
        row[6] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 7]).Value2);
        row[7] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 8]).Value2);
        row[8] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 9]).Value2);
        row[9] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 10]).Value2);
        row[10] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 11]).Value2);
        row[11] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 12]).Value2);
        row[12] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 13]).Value2);
        row[13] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 14]).Value2);
        row[14] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 15]).Value2);
        row[15] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 16]).Value2);
        row[16] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 17]).Value2);
        row[17] = Convert.ToString(((Range)workSheet.Cells[rowIndex, 18]).Value2);
        index++;
        dt.Rows.Add(row);
    }
    app.Workbooks.Close();
    return dt;
}

【讨论】:

    【解决方案2】:

    这是闪电般的快;我不能说我没有使用 ReadAllLines 和 Regex 进行文本操作。 (删除了文本操作细节)。

    原始问题的 cmets 中解释了我是如何使其工作的。

    不知道为什么它比 Interop.Excel 快得多。编码效率低?更高效的 API?

    感谢任何见解!

            var path = string.Format(@"C:\Users\jlambert\Desktop\encryptedSSNs.xlsx");
            var connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";
    
    
            var adapter = new OleDbDataAdapter("SELECT * FROM [sheetName$]", connStr);
            var ds = new DataSet();
    
            adapter.Fill(ds, "anyNameHere");
    
            var data = ds.Tables["anyNameHere"].AsEnumerable();
    
            var query = data.Where(x => x.Field<string>("MRN") != string.Empty).Select(x =>
                new 
                {
                    mrn = x.Field<string>("MRN"),
                    ssn = x.Field<string>("ssn"),
                });
    
            foreach (var q in query)
            {
                Console.WriteLine(q);    
            }
            Console.ReadLine();
    

    【讨论】:

      猜你喜欢
      • 2015-08-17
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多