none
trabajar con excel desde c# RRS feed

  • Pregunta

  • Hola a todos,

    Estoy teniendo algunas dificultades para trabajar con dos planillas excel desde C#.

    Para leer un excel con info desde mi pc implemente el siguiente codigo:

     DataTable dt1 = Util.openExcel(C:\test.xlsx);
     foreach (DataRow item in dt1.Rows)
     {            
            Console.WriteLine(item[0]);
            Console.WriteLine(item[1]);
            Console.WriteLine(item[2]);
     }
     Console.ReadKey();

            public static DataTable openExcel(string file)
            {
                OleDbConnection conn = new OleDbConnection();
                OleDbCommand cmd = new OleDbCommand();
                OleDbDataAdapter da = new OleDbDataAdapter();
                DataTable dt = new DataTable();
                try
                {               
                    conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + file + ";Mode=Read;Extended Properties=Excel 8.0;Persist Security Info=False;";
                    cmd.CommandText = "SELECT * FROM [Hoja1$]";
                    cmd.Connection = conn;
                    da.SelectCommand = cmd;
                    conn.Open();
                    da.Fill(dt);
                    return dt;
    
                }
                catch (Exception ex)
                {
                    Util.log(ex.Message);
                    return dt;
                }
                finally
                {
                    conn.Close();
                    conn.Dispose();
                }
            }

    Esto funciono muy bien "SIEMPRE Y CUANDO" ya tuviese el archivo excel abierto en mi PC.

    Si el archivo estaba cerrado, me daba el error: La tabla externa no tiene el formato esperado.

    Ante esto busque como abrir un Excel desde C# y modifique mi código de la siguiente manera:


            public static DataTable openExcel(string file)
            {
                OleDbConnection conn = new OleDbConnection();
                OleDbCommand cmd = new OleDbCommand();
                OleDbDataAdapter da = new OleDbDataAdapter();
                DataTable dt = new DataTable();
                try
                {
                    ProcessStartInfo startInfo = new ProcessStartInfo();
                    startInfo.FileName = "EXCEL.EXE";
                    startInfo.Arguments = file;
                    Process.Start(startInfo);
                    
                    conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + file + ";Mode=Read;Extended Properties=Excel 8.0;Persist Security Info=False;";
                    cmd.CommandText = "SELECT * FROM [Hoja1$]";
                    cmd.Connection = conn;
                    da.SelectCommand = cmd;
                    conn.Open();
                    da.Fill(dt);
                    return dt;
    
                }
                catch (Exception ex)
                {
                    Util.log(ex.Message);
                    return dt;
                }
                finally
                {
                    conn.Close();
                    conn.Dispose();
                }
            }

    Al hacer el debug funcionó a la perfección, pero al correrlo sin debug vuelve a presentar el mismo error. (La tabla externa no tiene el formato esperado.)

    Encontré que el problema se debe a que el archivo Excel no alcanza a levantar antes de querer leer, es por eso que si pongo una pausa luego de abrir el Excel (fue lo que paso cuando hice el debug) esto si funciona.

    Alguien me puede orientar para una solución mas efectiva...


    Desde ya muchas gracias!




    Cristian

    martes, 13 de marzo de 2018 12:21

Respuestas

  • Estimados,

    Lo que tengo que hacer es comparar dos Excel y eliminar las filas repetidas en uno de los dos archivos comparados.

    He logrado leer dos libros de Excel al mismo tiempo sin problemas con OleDbConnection con el siguiente método:

    public static DataTable openExcel(string file)
            {
                OleDbConnection conn = new OleDbConnection();
                OleDbCommand cmd = new OleDbCommand();
                OleDbDataAdapter da = new OleDbDataAdapter();
                DataTable dt = new DataTable();
                try
                {
                    ProcessStartInfo startInfo = new ProcessStartInfo();
                    startInfo.FileName = "EXCEL.EXE";
                    startInfo.Arguments = file;
                    var proceso = Process.Start(startInfo);
                    proceso.WaitForInputIdle();
    
                    conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + file + ";Mode=Read;Extended Properties=Excel 8.0;Persist Security Info=False;";
                    cmd.CommandText = "SELECT * FROM [Hoja1$]";
                    cmd.Connection = conn;
                    da.SelectCommand = cmd;
                    conn.Open();
                    da.Fill(dt);
                    return dt;
                }
                catch (Exception ex)
                {
                    Util.log(ex.Message);
                    Console.WriteLine(ex);
                    return dt;
                }
                finally
                {
                    conn.Close();
                    conn.Dispose();
                }
            }

    Ahora mi problema es como elimino una fila determinada???

    Buscando encontré que se debe usar la sentencia DELETE, pero no he logrado que me funcione.

    Favor ayúdenme...

    desde ya muchas gracias!


    Cristian

    martes, 13 de marzo de 2018 23:48

Todas las respuestas

  • hola

    >>Esto funciono muy bien "SIEMPRE Y CUANDO" ya tuviese el archivo excel abierto en mi PC.

    esto que comentas es raro, porque si el archivo se esta editando desde office esta lockeado, con lo cual al acceder desde ado.net deberia tener problemas

    >>Si el archivo estaba cerrado, me daba el error: La tabla externa no tiene el formato esperado

    recomendaria evalues un mejor libreria

    estas se basan en open xml con lo cual no necesitas de office en la pc, solo que el excel debe ser un .xlsx

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 13 de marzo de 2018 13:52
  • No es posible asegurar que el archivo sea xlsx, necesito abarcar ambas opciones (xls y xlsx).

    Estoy evaluando cambiar a interop, pero me gustaría leer el libro de excel en caso que ya este abierto en caso contrario abrirlo y obtener y llerlo.

    Actualmente si el libro esta abierto, el programa lo vuelve a abrir lo que me proporcionará conflictos.

    En resumen me gustaría hacer algo así:

    Excel.Application oXL;
    Excel._Workbook oWB;
    Excel._Worksheet oSheet;
                
    oXL = new Excel.Application();
    oXL.Visible = true;
    
    if(archivo.xlsx isOpen)
    {
         leer libro...
    }
    else
    {
         oWB = oXL.Workbooks.Open("C:\\archivo.xlsx");
         oSheet = (Excel._Worksheet)oWB.ActiveSheet;
    }
    gracias!


    Cristian

    martes, 13 de marzo de 2018 22:26
  • Estimados,

    Lo que tengo que hacer es comparar dos Excel y eliminar las filas repetidas en uno de los dos archivos comparados.

    He logrado leer dos libros de Excel al mismo tiempo sin problemas con OleDbConnection con el siguiente método:

    public static DataTable openExcel(string file)
            {
                OleDbConnection conn = new OleDbConnection();
                OleDbCommand cmd = new OleDbCommand();
                OleDbDataAdapter da = new OleDbDataAdapter();
                DataTable dt = new DataTable();
                try
                {
                    ProcessStartInfo startInfo = new ProcessStartInfo();
                    startInfo.FileName = "EXCEL.EXE";
                    startInfo.Arguments = file;
                    var proceso = Process.Start(startInfo);
                    proceso.WaitForInputIdle();
    
                    conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + file + ";Mode=Read;Extended Properties=Excel 8.0;Persist Security Info=False;";
                    cmd.CommandText = "SELECT * FROM [Hoja1$]";
                    cmd.Connection = conn;
                    da.SelectCommand = cmd;
                    conn.Open();
                    da.Fill(dt);
                    return dt;
                }
                catch (Exception ex)
                {
                    Util.log(ex.Message);
                    Console.WriteLine(ex);
                    return dt;
                }
                finally
                {
                    conn.Close();
                    conn.Dispose();
                }
            }

    Ahora mi problema es como elimino una fila determinada???

    Buscando encontré que se debe usar la sentencia DELETE, pero no he logrado que me funcione.

    Favor ayúdenme...

    desde ya muchas gracias!


    Cristian

    martes, 13 de marzo de 2018 23:48