2011-01-22 31 views
9

Tengo algunos datos tabulares que me gustaría convertir en una tabla de Excel.¿Cuál es la forma más fácil de crear una tabla de Excel con C#?

Software disponible:

  • .NET 4 (C#)
  • Excel 2010 (utilizando la API de Excel está bien)
  • que prefieren no utilizar ninguna bibliotecas 3 ª parte

Información sobre la información:

  • Un par de millones de ro ws
  • 5 columnas, todas las cadenas (muy simples y estructura de la tabla periódica)
  • En mi guión que estoy actualmente utilizan una estructura de datos de lista anidada pero puedo cambiar eso
  • Rendimiento del guión no es crítica

Buscar en línea da muchos resultados, y estoy confundido si debo usar OleDb, ADO RecordSets, o algo más. Algunas de estas tecnologías parecen excesivas para mi escenario, y algunas parecen que podrían estar obsoletas.

¿Cuál es la forma más simple de hacer esto?

Editar: esta es una secuencia de comandos de una sola vez que tengo la intención de ejecutar desde mi escritorio asistido.

+0

La manera más fácil consiste en una biblioteca de tercera parte decente :-) Busque "automatización de Excel". Debería haber algunos artículos de KB en MSDN y tal. Tenga en cuenta que el uso de las interoperaciones COM de Excel es * significativamente más lento * que la mayoría de las herramientas de terceros y espera ejecutarse en un entorno que no sea de servicio, etc. También puede haber problemas al tratar con "un par de millones de filas" (nunca intentado en cualquier lugar cerca de estos límites!), incluso excluyendo la sobrecarga adicional de recursos/tiempo - no critico no excluye "algún día hoy" :) –

+1

Además, para ese * simple * volcado, considere CSV -> Excel (manualmente o mediante automatización) en lugar de agregar todo las filas una a la vez (¡un par de millones es un par de millones!). Otra opción es descargar directamente a XSLX (XML, simplemente tomar "una plantilla") a través de un escritor de transmisión, etc. Por supuesto, estos pasos simplemente no están presentes en una biblioteca de terceros. –

+0

¿Cuál es su enfoque para ajustar "un par de millones de filas" en las 1.048.576 filas que veo en mi hoja de trabajo de Excel 2010? Estoy de acuerdo con Tyler en gastar el dinero en una biblioteca de terceros como Aspose.Cells para .NET (Developer Enterprise Subscription $ 899). – tawman

Respuesta

5

Cumpliendo con su solicitud para evitar herramientas de terceros y el uso de objetos COM, así es como lo haría.

  1. Agregue referencia al proyecto: objeto Com Microsoft Excel 11.0.
  2. Tapa de módulo adicional:

    using Microsoft.Office.Interop.Excel; 
    
  3. añadir lógica evento como este:

    private void DoThatExcelThing() 
    { 
    
        ApplicationClass myExcel; 
        try 
        { 
         myExcel = GetObject(,"Excel.Application") 
        } 
        catch (Exception ex) 
        { 
         myExcel = New ApplicationClass() 
        } 
    
        myExcel.Visible = true; 
        Workbook wb1 = myExcel.Workbooks.Add(""); 
        Worksheet ws1 = (Worksheet)wb1.Worksheets[1]; 
    
        //Read the connection string from App.Config 
        string strConn = System.Configuration.ConfigurationManager.ConnectionStrings["NewConnString"].ConnectionString; 
    
        //Open a connection to the database 
        SqlConnection myConn = new SqlConnection(); 
        myConn.ConnectionString = strConn; 
        myConn.Open(); 
    
        //Establish the query 
        SqlCommand myCmd = new SqlCommand("select * from employees", myConn); 
        SqlDataReader myRdr = myCmd.ExecuteReader(); 
    
        //Read the data and put into the spreadsheet. 
        int j = 3; 
        while (myRdr.Read()) 
        { 
         for (int i=0 ; i < myRdr.FieldCount; i++) 
         { 
          ws1.Cells[j, i+1] = myRdr[i].ToString(); 
         } 
         j++; 
        } 
    
        //Populate the column names 
        for (int i = 0; i < myRdr.FieldCount ; i++) 
        { 
         ws1.Cells[2, i+1] = myRdr.GetName(i); 
        } 
        myRdr.Close(); 
        myConn.Close(); 
    
        //Add some formatting 
        Range rng1 = ws1.get_Range("A1", "H1"); 
        rng1.Font.Bold = true; 
        rng1.Font.ColorIndex = 3; 
        rng1.HorizontalAlignment = XlHAlign.xlHAlignCenter; 
    
        Range rng2 = ws1.get_Range("A2", "H50"); 
        rng2.WrapText = false; 
        rng2.EntireColumn.AutoFit(); 
    
        //Add a header row 
        ws1.get_Range("A1", "H1").EntireRow.Insert(XlInsertShiftDirection.xlShiftDown, Missing.Value); 
        ws1.Cells[1, 1] = "Employee Contact List"; 
        Range rng3 = ws1.get_Range("A1", "H1"); 
        rng3.Merge(Missing.Value); 
        rng3.Font.Size = 16; 
        rng3.Font.ColorIndex = 3; 
        rng3.Font.Underline = true; 
        rng3.Font.Bold = true; 
        rng3.VerticalAlignment = XlVAlign.xlVAlignCenter; 
    
        //Save and close 
        string strFileName = String.Format("Employees{0}.xlsx", DateTime.Now.ToString("HHmmss")); 
        System.IO.File.Delete(strFileName); 
        wb1.SaveAs(strFileName, XlFileFormat.xlWorkbookDefault, Missing.Value, Missing.Value, Missing.Value, Missing.Value, 
         XlSaveAsAccessMode.xlExclusive, Missing.Value, false, Missing.Value, Missing.Value, Missing.Value); 
        myExcel.Quit(); 
    
    } 
    
+0

+1 Por ... uhm ... tratando de decir algo bueno ... "respondiendo la pregunta": p –

+0

¡Gracias por escribir eso, Rap! Lo probaré en una muestra pequeña y veré cómo se compara con la automatización de una importación de CSV en Excel. – RexE

8

Evite usando interoperabilidad COM a toda costa. Use una API de terceros. De Verdad. De hecho, si está haciendo esto en el servidor, prácticamente tiene que hacerlo. Hay muchas opciones gratuitas. Recomiendo usar EPPlus, pero también hay soluciones de nivel empresarial disponibles. He usado EPPlus una buena cantidad, y funciona muy bien. A diferencia de la interoperabilidad, le permite generar archivos de Excel sin requerir que Excel esté instalado en la máquina, lo que significa que tampoco debe preocuparse por los objetos COM que permanecen como procesos en segundo plano. Incluso con la eliminación adecuada de objetos, los procesos de Excel no siempre terminan.

http://epplus.codeplex.com/releases/view/42439

Sé que dijo que desea evitar las bibliotecas de terceros, pero que en realidad son el camino a seguir. Microsoft no recomienda automatizar Office. En realidad, no está destinado a ser automatizado de todos modos.

http://support.microsoft.com/kb/257757

Sin embargo, es posible que desee volver a examinar la inserción de "un par de millones de filas" en una sola hoja de cálculo.

+0

¿Alguna experiencia/sugerencia en un volcado directo de XSLX? (El formato en la pregunta es muy simple). –

+0

@pst: nunca he hecho eso, ni sé de ninguna biblioteca que lo soporte. Independientemente, OP probablemente debería reconsiderar la inserción de un par de millones de registros en una sola hoja de cálculo. –

+1

+1 por mi dolor y sufrimiento cuando utilicé la interoperabilidad COM para esto. Nunca más. –

1

Estoy de acuerdo que un tercero DLL partido sería más limpio que el com, pero si vas a la ruta de interoperabilidad ...

Sin duda la mejor manera de rellenar una hoja de Excel es poner en primer lugar los datos de una Arrastre de cadena de 2 dimensiones, luego obtenga un objeto de rango de Excel con las mismas dimensiones y configúrelo (range.set_value2 (oarray), creo). Usar cualquier otro método es terriblemente lento.

También asegúrese de usar el código de limpieza apropiado en su bloque finally.

2

Algunas cosas para su consideración ...

Si es un cliente solución lateral, no hay nada de malo con el uso de Interops. Si se trata de una solución del lado del servidor, no utilice Interops. Una buena alternativa es OpenXML SDK de Microsoft si no desea una solución de terceros. Es gratis. Creo que el último tiene un modelo de objetos similar al de Excel. Es mucho más rápido, MUCHO, en la generación del libro de trabajo que en la interoperabilidad, lo que puede atascar tu servidor.

+0

En un navegador tonto en el aeropuerto en este momento, no se puede cortar y pegar, pero simplemente busque OpenXML SDK 2 en línea para enlaces. –

3

Una vez leí que la forma más fácil de crear una tabla de Excel era escribir una tabla HTML, incluyendo su estructura y datos, y simplemente nombrar el archivo .xls.

Excel podrá convertirlo, pero mostrará una advertencia que diga que el contenido no coincide con la extensión.

1

he implementado "exportar a Excel" con el MS-Access-ole-db-controlador que también puede leer y escribir archivos de Excel de la manera follwoing:

preparación (hecho una vez)

  • crear un archivo de Excel que contiene todos (cabecera, el formato, fórmulas, diagramas) con un área de datos vacío como una plantilla para ser llenado
  • dar a la zona de datos (incluyendo las cabeceras) un nombre (es decir, "MyData")

La implementación de la exportación

  • archivo de plantilla copia a la carpeta de destino
  • abrir una conexión oledb-base de datos para el archivo de destino
  • utilizar SQL para insertar datos

Ejemplo

Excel table with Named area "MyData" 
Name, FamilyName, Birthday 

open System.Data.OleDb.OleDbConnection 
execute sql "Insert into MyData(Name, FamilyName, Birthday) values(...)" 

He usado esta cadena de conexión

private const string FORMAT_EXCEL_CONNECT = 
     // @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=""Excel 8.0;HDR={1}"""; 
     @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0;HDR={1}"""; 


    private static string GetExcelConnectionString(string excelFilePath, bool header) 
    { 
     return string.Format(FORMAT_EXCEL_CONNECT, 
      excelFilePath, 
      (header) ? "Yes" : "No" 
      ); 
    } 
Cuestiones relacionadas