是否可以不指定工作表名称和列?

Posted

技术标签:

【中文标题】是否可以不指定工作表名称和列?【英文标题】:Is it possible not specify the sheet name and columns? 【发布时间】:2019-09-27 06:28:41 【问题描述】:

所以,我正在做一个程序,它将一个 excel 文件导入到 sql 数据库中,如果我指定 excel 和数据库列的列以及工作表名称,那么一切正常......看看我的代码,然后我将详细说明问题所在:

protected void Upload_Click(object sender, EventArgs e)

    string excelPath = Server.MapPath("~/Nova pasta/") + Path.GetFileName(FileUpload1.PostedFile.FileName);

    string filepath = Server.MapPath("~/Nova pasta/") + Path.GetFileName(FileUpload1.FileName);
    string filename = Path.GetFileName(filepath);
    FileUpload1.SaveAs(excelPath);
    string ext = Path.GetExtension(filename);

    String strConnection = @"Data Source=PEDRO-PC\SQLEXPRESS;Initial Catalog=costumizado;Persist Security Info=True;User ID=sa;Password=1234";
    string excelConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=\"Excel 12.0 Xml;HRD=YES;IMEX=1;\"";

    OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);

    OleDbCommand cmd = new OleDbCommand("Select * from [rptListaMovs_4$]", excelConnection);

    excelConnection.Open();

    cmd.ExecuteNonQuery();

    DataSet ds = new DataSet();

    SqlDataAdapter da = new SqlDataAdapter("Select * from [rptListaMovs_4$] ", strConnection);

    OleDbDataReader dReader;
    dReader = cmd.ExecuteReader();

    using (SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection))
    
        sqlBulk.DestinationTableName = "Dados";
        sqlBulk.ColumnMappings.Add("Data Mov", "Data Mov.");
        sqlBulk.ColumnMappings.Add("Data Valor", "Data Valor");
        sqlBulk.ColumnMappings.Add("Descrição do Movimento", "Descrição do Movimento");
        sqlBulk.ColumnMappings.Add("Valor em EUR", "Valor em EUR");

        sqlBulk.WriteToServer(dReader);
    

    excelConnection.Close();

安装于此:"Select * from [rptListaMovs_4$]"

我想要这个:"Select * from ["+SheetNameWithoutCopyPastHisName+"]"

并安装了这个

sqlBulk.ColumnMappings.Add("Data Mov", "Data Mov.");
sqlBulk.ColumnMappings.Add("Data Valor", "Data Valor");
sqlBulk.ColumnMappings.Add("Descrição do Movimento", "Descrição do Movimento");
sqlBulk.ColumnMappings.Add("Valor em EUR", "Valor em EUR");

我想要一些东西,不需要放置列名,因为有时我想导入具有不同架构的 excel,但它不允许我

【问题讨论】:

cmd.ExecuteNonQuery(); 没有意义。您稍后使用dReader = cmd.ExecuteReader(); 正确执行该命令。 ExecuteNonQuery 用于插入、删除、更新和 DDL 语句。 @OlivierJacot-Descombes 是的,谢谢你说已经拿出来了 【参考方案1】:

您应该能够通过以下方式获得第一个工作表名称:

DataTable schema = excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string sheetName = schema.Rows[0]["TABLE_NAME"].ToString();

至于字段名称,这应该可以解决问题:

for(int i = 0; i < dReader.FieldCount; i++)

    sqlBulk.ColumnMappings.Add(dReader.GetName(i), dReader.GetName(i));

【讨论】:

嘿!所以它的工作表名称,真的很好!谢谢,但是对于字段名称,它出现了这个异常“指定的 ColumnMapping 与源或目标的任何列都不匹配。” 我的经验是这些模式表一团糟。可用的表和列名称因提供者而异。在string sheetName = schema.Rows[0]["TABLE_NAME"].ToString(); 行上设置断点并快速查看schema.Rows[0],然后向下钻取列集合以查看可用的列名。

以上是关于是否可以不指定工作表名称和列?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET 如何获取 Excel 中工作表的名称。

用vba新建工作表,并命名

Excel 怎样知道一个工作簿中工作表的个数?

同一个工作簿中的两张工作表调试错误?

GreenDao 使用二

数据库索引