在C#中读取XLSX数据

18

我刚接触C#,正在尝试使用以下代码读取XLSX文件:

string Connection = "Provider=Microsoft.ACE.OLEDB.12.0;DataSource=c:\\Temp\\source.xlsx;Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=1\";";

//code to read the content of format file 
OleDbConnection con = new OleDbConnection(Connection);
OleDbCommand command = new OleDbCommand();

DataTable dt = new DataTable();
OleDbDataAdapter myCommand = new OleDbDataAdapter("select * from [Tabelle1$]", con);

myCommand.Fill(dt);
Console.Write(dt.Rows.Count);

我能得到正确的输出数量,但我还有两个问题:

1. 如何创建一个带有条件语句的select查询(如何访问行)?

 select * from [Tabelle1$] where A = '123' (A being an existing Excel row)

会抛出一个提到错误参数的错误...

2.有人能提供给我一个教程链接或者简短示例,如何访问这些数据吗?


请查看微软的此教程 http://support.microsoft.com/kb/316934 。 - Eugen
请务必仔细阅读 Eugen 提供的教程链接。你会意识到为什么 A = '123' 不起作用(但将 HDR=No 转换并编写 WHERE F1 = '123' 就可以)。 - nantito
我用F1让它工作了,但不明白为什么A不起作用,以及如何访问默认表名... - RRZ Europe
HDR 表示是否存在表头行。如果设置为“是”,则意味着您将使用第一行的单元格作为列名称的指示器,而不是自动设置的“F1、F2...”等。 - nantito
至于为什么"A,B..."无法工作,我会猜测一下。在OleDbDataAdapter中选择数据时,您可以在“FROM”语句之后定义您的工作表。在那里,您还可以附加所需的范围(如链接中所示)。现在,从这样的选择返回的结果将是一个数据结构,与默认的Excel列命名没有关系。如果您能够编写SELECT * FROM [Tabelle1$A1:B10] where C = '123',那将很糟糕(这没有任何意义)。 - nantito
2个回答

20
请参考以下示例代码:
private DataTable LoadXLS(string strFile, String sheetName, String column, String value)
{
    DataTable dtXLS = new DataTable(sheetName);

    try
    {
       string strConnectionString = "";

       if(strFile.Trim().EndsWith(".xlsx")) {

           strConnectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";", strFile);

       } else if(strFile.Trim().EndsWith(".xls")) {

           strConnectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\";", strFile);

       }

       OleDbConnection SQLConn = new OleDbConnection(strConnectionString);

       SQLConn.Open();

       OleDbDataAdapter SQLAdapter = new OleDbDataAdapter();

       string sql = "SELECT * FROM [" + sheetName + "$] WHERE " + column + " = " + value;

       OleDbCommand selectCMD = new OleDbCommand(sql, SQLConn);

       SQLAdapter.SelectCommand = selectCMD;

       SQLAdapter.Fill(dtXLS);

       SQLConn.Close();
    }

    catch (Exception e)
    {
       Console.WriteLine(e.ToString());
    }

    return dtXLS;

}

我在哪里可以下载oledb提供程序? - Johnny_D
3
请从http://www.microsoft.com/en-us/download/details.aspx?id=13255下载。选择32位或64位取决于操作系统。 - Romil Kumar Jain
1
你忘记在finally或者using中关闭SQLConn,所以你的代码存在内存泄漏问题。对于任何实现它的人:将OleDbConnection SQLConn = new OleDbConnection(strConnectionString);改为using OleDbConnection SQLConn = new OleDbConnection(strConnectionString) {,并在SQLConn.Close();之后添加一个闭合的} - Tedd Hansen

1
我知道这是一个旧问题,但它有一个很好的答案,而且在谷歌搜索结果中排名靠前,关键词是“import xlsx c#”,所以我想添加一种更现代、更简单的方法来使用NPOI库读取xls/xlsx数据。我希望确保新的C#开发人员知道,除了使用ado.net之外,还有更容易导入Excel数据的方法。
我使用NPOI和Npoi.Mapper(来自donnytian:https://github.com/donnytian/Npoi.Mapper)的组合轻松地导入Excel文件。添加对NPOI和Npoi.Mapper的nuget引用,然后您就可以使用强类型类来导入与要导入的列直接相关的xls/xlsx数据。
```using System.IO; using System.Linq; using Npoi.Mapper; using Npoi.Mapper.Attributes; using NPOI.SS.UserModel; using UserManagementService.Models;

namespace JobCustomerImport.Processors { public class ExcelEmailProcessor { private UserManagementServiceContext DataContext { get; }

    public ExcelEmailProcessor(int customerNumber)
    {
        DataContext = new UserManagementServiceContext();
    }

    public void Execute(string localPath, int sheetIndex)
    {
        IWorkbook workbook;
        using (FileStream file = new FileStream(localPath, FileMode.Open, FileAccess.Read))
        {
            workbook = WorkbookFactory.Create(file);
        }

        var importer = new Mapper(workbook);
        var items = importer.Take<MurphyExcelFormat>(sheetIndex);
        foreach(var item in items)
        {
            var row = item.Value;
            if (string.IsNullOrEmpty(row.EmailAddress))
                continue;

            UpdateUser(row);
        }

        DataContext.SaveChanges();
    }

    private void UpdateUser(MurphyExcelFormat row)
    {
        //LOGIC HERE TO UPDATE A USER IN DATABASE...
    }

    private class MurphyExcelFormat
    {
        [Column("District")]
        public int District { get; set; }

        [Column("DM")]
        public string FullName { get; set; }

        [Column("Email Address")]
        public string EmailAddress { get; set; }

        [Column(3)]
        public string Username { get; set; }

        public string FirstName
        {
            get
            {
                return Username.Split('.')[0];
            }
        }

        public string LastName
        {
            get
            {
                return Username.Split('.')[1];
            }
        }
    }
}

如果您感兴趣,我在我的博客上涵盖了一些细节:如何轻松导入Excel文件

谢谢! 丹


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接