2009-03-18 33 views
58

¿Cómo leer un archivo de Excel usando C#? Abrí un archivo de Excel para leerlo y copiarlo en el portapapeles para buscar el formato de correo electrónico, pero no sé cómo hacerlo.¿Cómo se leen los datos de un archivo Excel usando C#?

FileInfo finfo; 
Excel.ApplicationClass ExcelObj = new Excel.ApplicationClass(); 
ExcelObj.Visible = false; 

Excel.Workbook theWorkbook; 
Excel.Worksheet worksheet; 

if (listView1.Items.Count > 0) 
{ 
    foreach (ListViewItem s in listView1.Items) 
    { 
     finfo = new FileInfo(s.Text); 
     if (finfo.Extension == ".xls" || finfo.Extension == ".xlsx" || finfo.Extension == ".xlt" || finfo.Extension == ".xlsm" || finfo.Extension == ".csv") 
     { 
      theWorkbook = ExcelObj.Workbooks.Open(s.Text, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, false, false); 

      for (int count = 1; count <= theWorkbook.Sheets.Count; count++) 
      { 
       worksheet = (Excel.Worksheet)theWorkbook.Worksheets.get_Item(count); 
       worksheet.Activate(); 
       worksheet.Visible = false; 
       worksheet.UsedRange.Cells.Select(); 
      } 
     } 
    } 
} 
+0

nuevos usuarios que vienen de una solución puede ser que desee ver esto [thread] (https://stackoverflow.com/questions/33302235/how-to-read-from-xlsx-excel). –

Respuesta

17

¿Por qué no creas OleDbConnection? Hay muchos recursos disponibles en Internet. Este es un ejemplo

OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+filename+";Extended Properties=Excel 8.0"); 
con.Open(); 
try 
{ 
    //Create Dataset and fill with imformation from the Excel Spreadsheet for easier reference 
    DataSet myDataSet = new DataSet(); 
    OleDbDataAdapter myCommand = new OleDbDataAdapter(" SELECT * FROM ["+listname+"$]" , con); 
    myCommand.Fill(myDataSet); 
    con.Close(); 
    richTextBox1.AppendText("\nDataSet Filled"); 

    //Travers through each row in the dataset 
    foreach (DataRow myDataRow in myDataSet.Tables[0].Rows) 
    { 
      //Stores info in Datarow into an array 
      Object[] cells = myDataRow.ItemArray; 
      //Traverse through each array and put into object cellContent as type Object 
      //Using Object as for some reason the Dataset reads some blank value which 
      //causes a hissy fit when trying to read. By using object I can convert to 
      //String at a later point. 
      foreach (object cellContent in cells) 
      { 
       //Convert object cellContect into String to read whilst replacing Line Breaks with a defined character 
       string cellText = cellContent.ToString(); 
       cellText = cellText.Replace("\n", "|"); 
       //Read the string and put into Array of characters chars 
       richTextBox1.AppendText("\n"+cellText); 
      } 
    } 
    //Thread.Sleep(15000); 
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.ToString()); 
    //Thread.Sleep(15000); 
} 
finally 
{ 
    con.Close(); 
} 
+7

El enlace está muerto ahora –

+2

Un problema que tuve con OleDbConnection (con el adaptador de datos Oracle) fue con una columna que contenía números y texto. Obtuve una DataTable con la columna formateada como número y faltaron todas las celdas donde los datos fueron formateados como texto. Mi solución fue usar interoperabilidad para convertir todo el rango utilizado de la columna al formato TEXTO antes de usar OleDBC para obtener los datos. –

+0

Último archivo de trabajo [aquí] (https://web.archive.org/web/20130731065653/http://blog.brezovsky.net/en-text-38.html). Solo 40 líneas ... probablemente solo puedan editar la publicación y agregarlas. * Encogerse de hombros * – Quantic

84

OK,

Uno de los conceptos más difíciles de entender acerca de la programación de Excel VSTO es que no se refieren a las células como una matriz, Worksheet[0][0] no dará que la celda A1 , se equivocará en ti. Incluso cuando escribe en A1 cuando Excel está abierto, en realidad está ingresando datos en el rango A1. Por lo tanto, se refiere a las celdas como Rangos con nombre. He aquí un ejemplo:

Excel.Worksheet sheet = workbook.Sheets["Sheet1"] as Excel.Worksheet; 
Excel.Range range = sheet.get_Range("A1", Missing.Value) 

Ahora puede escribir literalmente:

range.Text // this will give you the text the user sees 
range.Value2 // this will give you the actual value stored by Excel (without rounding) 

Si quieres hacer algo como esto:

Excel.Range range = sheet.get_Range("A1:A5", Missing.Value) 

if (range1 != null) 
    foreach (Excel.Range r in range1) 
    { 
     string user = r.Text 
     string value = r.Value2 

    } 

Puede haber una mejor manera, pero esto tiene trabajó para mi.

La razón es necesario utilizar Value2 y no Value es porque la propiedad es un Value parametrizada y C# no es compatible con ellos todavía.

En cuanto al código de limpieza, voy a publicar que cuando llegue a trabajar mañana, no tengo el código conmigo, pero es muy repetitivo. Simplemente cierre y suelte los objetos en el orden inverso al que los creó. No puede usar un bloque Using() porque Excel.Application o Excel.Workbook no implementa IDisposable, y si no realiza la limpieza, se quedará con un objeto colgante de Excel en la memoria.

Nota:

  • Si no establece la propiedad Visibility Excel no muestra, que puede ser desconcertante para los usuarios, pero si sólo quiere extraer los datos de salida, que es probablemente bueno suficiente
  • Podrías OleDb, eso funcionará también.

Espero que lo haga comenzar, hágame saber si necesita más aclaraciones. Voy a publicar un completo

Este es un ejemplo completo:

using System; 
using System.IO; 
using System.Reflection; 
using NUnit.Framework; 
using ExcelTools = Ms.Office; 
using Excel = Microsoft.Office.Interop.Excel; 

namespace Tests 
{ 
    [TestFixture] 
    public class ExcelSingle 
    { 
     [Test] 
     public void ProcessWorkbook() 
     { 
      string file = @"C:\Users\Chris\Desktop\TestSheet.xls"; 
      Console.WriteLine(file); 

      Excel.Application excel = null; 
      Excel.Workbook wkb = null; 

      try 
      { 
       excel = new Excel.Application(); 

       wkb = ExcelTools.OfficeUtil.OpenBook(excel, file); 

       Excel.Worksheet sheet = wkb.Sheets["Data"] as Excel.Worksheet; 

       Excel.Range range = null; 

       if (sheet != null) 
        range = sheet.get_Range("A1", Missing.Value); 

       string A1 = String.Empty; 

       if(range != null) 
        A1 = range.Text.ToString(); 

       Console.WriteLine("A1 value: {0}", A1); 

      } 
      catch(Exception ex) 
      { 
       //if you need to handle stuff 
       Console.WriteLine(ex.Message); 
      } 
      finally 
      { 
       if (wkb != null) 
        ExcelTools.OfficeUtil.ReleaseRCM(wkb); 

       if (excel != null) 
        ExcelTools.OfficeUtil.ReleaseRCM(excel); 
      } 
     } 
    } 
} 

Voy a publicar las funciones de ExcelTools mañana, no tengo ese código conmigo tampoco.

Editar: Según lo prometido, aquí están las funciones de ExcelTools que pueda necesitar.

public static Excel.Workbook OpenBook(Excel.Application excelInstance, string fileName, bool readOnly, bool editable, 
     bool updateLinks) { 
     Excel.Workbook book = excelInstance.Workbooks.Open(
      fileName, updateLinks, readOnly, 
      Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
      Type.Missing, editable, Type.Missing, Type.Missing, Type.Missing, 
      Type.Missing, Type.Missing); 
     return book; 
    } 

public static void ReleaseRCM(object o) { 
     try { 
      System.Runtime.InteropServices.Marshal.ReleaseComObject(o); 
     } catch { 
     } finally { 
      o = null; 
     } 
    } 

Para ser sincero, esto es mucho más fácil si utiliza VB.NET. Está en C# porque no lo escribí. VB.NET hace bien los parámetros de las opciones, C# no, por lo tanto, el Tipo.Missing. Una vez que escribiste Tipo.Faltan dos veces seguidas, ¡corres gritando desde la habitación!

En cuanto a usted pregunta, puede intentar lo siguiente:

http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.find(VS.80).aspx

Voy a publicar un ejemplo cuando vuelva de mi reunión ... Saludos

Edit: Aquí está un ejemplo

range = sheet.Cells.Find("Value to Find", 
               Type.Missing, 
               Type.Missing, 
               Type.Missing, 
               Type.Missing, 
               Excel.XlSearchDirection.xlNext, 
               Type.Missing, 
               Type.Missing, Type.Missing); 

range.Text; //give you the value found 

Aquí es otro ejemplo inspirado en este site:

range = sheet.Cells.Find("Value to find", Type.Missing, Type.Missing,Excel.XlLookAt.xlWhole,Excel.XlSearchOrder.xlByColumns,Excel.XlSearchDirection.xlNext,false, false, Type.Missing); 

Ayuda a comprender los parámetros.

P.S. Soy una de esas personas raras que disfruta aprendiendo automatización COM. Todo este código salpicado de una herramienta que escribí para el trabajo que me requería procesar más de 1000 hojas de cálculo del laboratorio cada lunes.

+0

Quiero leer el archivo de Excel de Listview para buscar el ID de correo electrónico del archivo de Excel ... estoy tratando de hacer esto ... pero yo no sé el tipo de codificación de Excel me refiero a los formatos de datos ... ¿cómo puedo leer un archivo de Excel para buscar el ID de correo electrónico ... no quiero utilizar la conexión de datos – ankush

+0

+1 excelente respuesta en profundidad. Acabo de perder todo el nombre/fecha de más de 400 archivos xls de un disco duro recuperado, y esto me ayudó a volver a la pista en una hora – Joe

+1

por qué la línea de declaración "using ExcelTools = Ms.Office;" diciendo "El tipo o el nombre del espacio de nombres 'Ms' no se pudo encontrar"? – Rishi

5

En primer lugar, es importante saber qué quiere decir con "abrir un archivo de Excel para leer y copiar al portapapeles ..."

Esto es muy importante porque hay muchas maneras que usted puede hacer que dependiendo solo en lo que piensas hacer Me explico:

  1. Si desea leer un conjunto de datos y copiar que en el portapapeles y que conoce el formato de datos (por ejemplo, nombres de columna), le sugiero que utilice un OleDbConnection para abrir el archivo , de esta forma puede tratar el contenido del archivo xls como una Tabla de base de datos, de modo que pueda leer datos con instrucciones SQL y tratar los datos como lo desee.

  2. Si desea realizar operaciones sobre los datos con el modelo de objetos de Excel, ábralo de la manera en que comenzó.

  3. Alguna vez es posible tratar un archivo xls como un tipo de archivo csv, existen herramientas como File Helpers que le permiten tratar y abrir un archivo xls de una manera sencilla mapeando una estructura en un objeto arbitrario.

Otro punto importante es en qué versión de Excel es el archivo.

Desafortunadamente, tengo una gran experiencia trabajando con la automatización de Office en todos los sentidos, incluso si está limitado a conceptos como Automatización de aplicaciones, Gestión de datos y complementos, y generalmente sugiero solo como último recurso, a usar la automatización de Excel u ofimática para leer datos; solo si no hay mejores formas de lograr esa tarea.

Trabajar con automatización puede ser pesado en rendimiento, en términos de costo de recursos, podría involucrar en otros asuntos relacionados con la seguridad y más, y por último pero no menos, trabajar con interoperabilidad COM no es tan "libre". Así que mi sugerencia es pensar y analizar la situación dentro de sus necesidades y luego tomar la mejor manera.

20

Puede usar el ensamblaje Microsoft.Office.Interop.Excel para procesar archivos de Excel.

  1. Haga clic derecho en su proyecto y vaya a Add reference. Agregue Microsoft.Office.Interop.Ensamblaje de Excel.
  2. Incluya using Microsoft.Office.Interop.Excel; para hacer uso del ensamblaje.

Aquí es el código de ejemplo:

using Microsoft.Office.Interop.Excel; 

    //create the Application object we can use in the member functions. 
    Microsoft.Office.Interop.Excel.Application _excelApp = new Microsoft.Office.Interop.Excel.Application(); 
    _excelApp.Visible = true; 

    string fileName = "C:\\sampleExcelFile.xlsx"; 

    //open the workbook 
    Workbook workbook = _excelApp.Workbooks.Open(fileName, 
     Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
     Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
     Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
     Type.Missing, Type.Missing); 

    //select the first sheet   
    Worksheet worksheet = (Worksheet)workbook.Worksheets[1]; 

    //find the used range in worksheet 
    Range excelRange = worksheet.UsedRange; 

    //get an object array of all of the cells in the worksheet (their values) 
    object[,] valueArray = (object[,])excelRange.get_Value(
       XlRangeValueDataType.xlRangeValueDefault); 

    //access the cells 
    for (int row = 1; row <= worksheet.UsedRange.Rows.Count; ++row) 
    { 
     for (int col = 1; col <= worksheet.UsedRange.Columns.Count; ++col) 
     { 
      //access each cell 
      Debug.Print(valueArray[row, col].ToString()); 
     } 
    } 

    //clean up stuffs 
    workbook.Close(false, Type.Missing, Type.Missing); 
    Marshal.ReleaseComObject(workbook); 

    _excelApp.Quit(); 
    Marshal.FinalReleaseComObject(_excelApp); 
+0

Descubrí que los siguientes objetos COM deben ser declarados y luego 'ReleaseComObject()' ed durante 'clean stuff's o tengo un exe ejecutable de zombie después de la finalización del código: El objeto' Workbooks' creado en '_excelApp.Workbooks' , el objeto 'Worksheets' creado en' workbook.Worksheets', 'Range' objetos creados en' worksheet.UsedRange.Rows' y 'worksheet.UsedRange.Columns', y el objeto' excelRange'. También creo que reemplazar los dos usos de 'worksheet.UsedRange' con la variable' excelRange' en caso de que se creen más objetos COM a partir de no usar la variable existente. – Quantic

1

Usar conexión OLEDB para comunicarse con los archivos de Excel. que da un mejor resultado

using System.Data.OleDb; 



       string physicalPath = "Your Excel file physical path"; 
       OleDbCommand cmd = new OleDbCommand(); 
       OleDbDataAdapter da = new OleDbDataAdapter(); 
       DataSet ds = new DataSet(); 
       String strNewPath = physicalPath; 
       String connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strNewPath + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\""; 
       String query = "SELECT * FROM [Sheet1$]"; // You can use any different queries to get the data from the excel sheet 
       OleDbConnection conn = new OleDbConnection(connString); 
       if (conn.State == ConnectionState.Closed) conn.Open(); 
       try 
       { 
        cmd = new OleDbCommand(query, conn); 
        da = new OleDbDataAdapter(cmd); 
        da.Fill(ds); 

       } 
       catch 
       { 
        // Exception Msg 

       } 
       finally 
       { 
        da.Dispose(); 
        conn.Close(); 
       } 

los datos de salida se almacenarán en la base de datos, utilizando el objeto de conjunto de datos que se puede acceder fácilmente a los datos básicos. Espero que esto pueda útiles

+0

Recibo un error en conn.Open(); escenario. Comprobado con rutas diferentes ... – izbrannick

0

archivo de Excel lector & escritor sin Excel En Sistema u'r

  • Descargar y añadir el archivo DLL para proyecto NPOI u'r.
  • Usando este código para leer un archivo de Excel.

     using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
         { 
          XSSFWorkbook XSSFWorkbook = new XSSFWorkbook(file); 
         } 
         ISheet objxlWorkSheet = XSSFWorkbook.GetSheetAt(0); 
         int intRowCount = 1; 
         int intColumnCount = 0; 
         for (; ;) 
         { 
          IRow Row = objxlWorkSheet.GetRow(intRowCount); 
          if (Row != null) 
          { 
           ICell Cell = Row.GetCell(0); 
           ICell objCell = objxlWorkSheet.GetRow(intRowCount).GetCell(intColumnCount); }} 
    
-1
public void excelRead(string sheetName) 
     { 
      Excel.Application appExl = new Excel.Application(); 
      Excel.Workbook workbook = null; 
      try 
      { 
       string methodName = ""; 


       Excel.Worksheet NwSheet; 
       Excel.Range ShtRange; 

       //Opening Excel file(myData.xlsx) 
       appExl = new Excel.Application(); 


       workbook = appExl.Workbooks.Open(sheetName, Missing.Value, ReadOnly: false); 
       NwSheet = (Excel.Worksheet)workbook.Sheets.get_Item(1); 
       ShtRange = NwSheet.UsedRange; //gives the used cells in sheet 


       int rCnt1 = 0; 
       int cCnt1 = 0; 

       for (rCnt1 = 1; rCnt1 <= ShtRange.Rows.Count; rCnt1++) 
       { 
        for (cCnt1 = 1; cCnt1 <= ShtRange.Columns.Count; cCnt1++) 
        { 
         if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1].Value2) == "Y") 
         { 

          methodName = NwSheet.Cells[rCnt1, cCnt1 - 2].Value2; 
          Type metdType = this.GetType(); 
          MethodInfo mthInfo = metdType.GetMethod(methodName); 

          if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_AddNum" || Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_SubNum") 
          { 
           StaticVariable.intParam1 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 3].Value2); 
           StaticVariable.intParam2 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 4].Value2); 
           object[] mParam1 = new object[] { StaticVariable.intParam1, StaticVariable.intParam2 }; 
           object result = mthInfo.Invoke(this, mParam1); 
           StaticVariable.intOutParam1 = Convert.ToInt32(result); 
           NwSheet.Cells[rCnt1, cCnt1 + 5].Value2 = Convert.ToString(StaticVariable.intOutParam1) != "" ? Convert.ToString(StaticVariable.intOutParam1) : String.Empty; 
          } 

          else 
          { 
           object[] mParam = new object[] { }; 
           mthInfo.Invoke(this, mParam); 

           NwSheet.Cells[rCnt1, cCnt1 + 5].Value2 = StaticVariable.outParam1 != "" ? StaticVariable.outParam1 : String.Empty; 
           NwSheet.Cells[rCnt1, cCnt1 + 6].Value2 = StaticVariable.outParam2 != "" ? StaticVariable.outParam2 : String.Empty; 
          } 
          NwSheet.Cells[rCnt1, cCnt1 + 1].Value2 = StaticVariable.resultOut; 
          NwSheet.Cells[rCnt1, cCnt1 + 2].Value2 = StaticVariable.resultDescription; 
         } 

         else if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1].Value2) == "N") 
         { 
          MessageBox.Show("Result is No"); 
         } 
         else if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1].Value2) == "EOF") 
         { 
          MessageBox.Show("End of File"); 
         } 

        } 
       } 

       workbook.Save(); 
       workbook.Close(true, Missing.Value, Missing.Value); 
       appExl.Quit(); 
       System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ShtRange); 
       System.Runtime.InteropServices.Marshal.FinalReleaseComObject(NwSheet); 
       System.Runtime.InteropServices.Marshal.FinalReleaseComObject(workbook); 
       System.Runtime.InteropServices.Marshal.FinalReleaseComObject(appExl); 
      } 
      catch (Exception) 
      { 
       workbook.Close(true, Missing.Value, Missing.Value); 
      } 
      finally 
      { 
       GC.Collect(); 
       GC.WaitForPendingFinalizers(); 
       System.Runtime.InteropServices.Marshal.CleanupUnusedObjectsInCurrentContext(); 
      } 
     } 

//code for reading excel data in datatable 
public void testExcel(string sheetName) 
     { 
      try 
      { 
       MessageBox.Show(sheetName); 

       foreach(Process p in Process.GetProcessesByName("EXCEL")) 
       { 
        p.Kill(); 
       } 
       //string fileName = "E:\\inputSheet"; 
       Excel.Application oXL; 
       Workbook oWB; 
       Worksheet oSheet; 
       Range oRng; 


       // creat a Application object 
       oXL = new Excel.Application(); 




       // get WorkBook object 
       oWB = oXL.Workbooks.Open(sheetName); 


       // get WorkSheet object 
       oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oWB.Sheets[1]; 
       System.Data.DataTable dt = new System.Data.DataTable(); 
       //DataSet ds = new DataSet(); 
       //ds.Tables.Add(dt); 
       DataRow dr; 


       StringBuilder sb = new StringBuilder(); 
       int jValue = oSheet.UsedRange.Cells.Columns.Count; 
       int iValue = oSheet.UsedRange.Cells.Rows.Count; 


       // get data columns 
       for (int j = 1; j <= jValue; j++) 
       { 
        oRng = (Microsoft.Office.Interop.Excel.Range)oSheet.Cells[1, j]; 
        string strValue = oRng.Text.ToString(); 
        dt.Columns.Add(strValue, System.Type.GetType("System.String")); 
       } 


       //string colString = sb.ToString().Trim(); 
       //string[] colArray = colString.Split(':'); 


       // get data in cell 
       for (int i = 2; i <= iValue; i++) 
       { 
        dr = dt.NewRow(); 
        for (int j = 1; j <= jValue; j++) 
        { 
         oRng = (Microsoft.Office.Interop.Excel.Range)oSheet.Cells[i, j]; 
         string strValue = oRng.Text.ToString(); 
         dr[j - 1] = strValue; 


        } 
        dt.Rows.Add(dr); 
       } 
       if(StaticVariable.dtExcel != null) 
       { 
        StaticVariable.dtExcel.Clear(); 
        StaticVariable.dtExcel = dt.Copy(); 
       } 
       else 
       StaticVariable.dtExcel = dt.Copy(); 

       oWB.Close(true, Missing.Value, Missing.Value); 
       oXL.Quit(); 
       MessageBox.Show(sheetName); 

      } 

      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
      finally 
      { 

      } 
     } 

//code for class initialize 
public static void startTesting(TestContext context) 
     { 

      Playback.Initialize(); 
      ReadExcel myClassObj = new ReadExcel(); 
      string sheetName=""; 
      StreamReader sr = new StreamReader(@"E:\SaveSheetName.txt"); 
      sheetName = sr.ReadLine(); 
      sr.Close(); 
      myClassObj.excelRead(sheetName); 
      myClassObj.testExcel(sheetName); 
     } 

//code for test initalize 
public void runValidatonTest() 
     { 

      DataTable dtFinal = StaticVariable.dtExcel.Copy(); 
      for (int i = 0; i < dtFinal.Rows.Count; i++) 
      { 
       if (TestContext.TestName == dtFinal.Rows[i][2].ToString() && dtFinal.Rows[i][3].ToString() == "Y" && dtFinal.Rows[i][4].ToString() == "TRUE") 
       { 
        MessageBox.Show(TestContext.TestName); 
        MessageBox.Show(dtFinal.Rows[i][2].ToString()); 
        StaticVariable.runValidateResult = "true"; 
        break; 
       } 
      } 
      //StaticVariable.dtExcel = dtFinal.Copy(); 
     } 
4
try 
     { 
      DataTable sheet1 = new DataTable("Excel Sheet"); 
      OleDbConnectionStringBuilder csbuilder = new OleDbConnectionStringBuilder(); 
      csbuilder.Provider = "Microsoft.ACE.OLEDB.12.0"; 
      csbuilder.DataSource = fileLocation; 
      csbuilder.Add("Extended Properties", "Excel 12.0 Xml;HDR=YES"); 
      string selectSql = @"SELECT * FROM [Sheet1$]"; 
      using (OleDbConnection connection = new OleDbConnection(csbuilder.ConnectionString)) 
      using (OleDbDataAdapter adapter = new OleDbDataAdapter(selectSql, connection)) 
      { 
       connection.Open(); 
       adapter.Fill(sheet1); 
      } 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.Message); 
     } 

Esto funcionó para mí. Pruébalo y comunícate con nosotros para consultas.

+1

Tu código funciona perfecto para mí, sin instalar ninguna biblioteca u otra historia, gracias –

-2

Te recomendaría que utilizaras la hoja de cálculo de Bytescout.

https://bytescout.com/products/developer/spreadsheetsdk/bytescoutspreadsheetsdk.html

he probado con Monodevelop en Unity3D y es bastante sencillo. Compruebe este código de ejemplo para ver cómo funciona la biblioteca:

https://bytescout.com/products/developer/spreadsheetsdk/read-write-excel.html

+0

Gracias por recomendar el SDK de hojas de cálculo ByteScout, me alegro de que funcione bien para usted en Monodevelop en Unity3D. No lo hemos intentado con Unity3D, pero probablemente deberíamos intentar agregarlo a la lista de ejemplos de código fuente –

+0

. ¡De nada, @EugeneM! Siempre es bueno ampliar la lista de soluciones para tener más posibilidades de elegir. – MetalxBeat

0

Uso Open XML.

Aquí hay un código para procesar una hoja de cálculo con una pestaña específica o nombre de hoja y volcarlo en algo así como CSV. (Elegí un tubo en lugar de coma).

Ojalá fuera más fácil obtener el valor de una celda, pero creo que esto es a lo que nos tenemos que atascar. Puede ver que hago referencia a los documentos de MSDN donde obtuve la mayor parte de este código. Eso es lo que Microsoft recomienda.

/// <summary> 
    /// Got code from: https://msdn.microsoft.com/en-us/library/office/gg575571.aspx 
    /// </summary> 
    [Test] 
    public void WriteOutExcelFile() 
    { 
     var fileName = "ExcelFiles\\File_With_Many_Tabs.xlsx"; 
     var sheetName = "Submission Form"; // Existing tab name. 
     using (var document = SpreadsheetDocument.Open(fileName, isEditable: false)) 
     { 
      var workbookPart = document.WorkbookPart; 
      var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == sheetName); 
      var worksheetPart = (WorksheetPart)(workbookPart.GetPartById(sheet.Id)); 
      var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First(); 

      foreach (var row in sheetData.Elements<Row>()) 
      { 
       foreach (var cell in row.Elements<Cell>()) 
       { 
        Console.Write("|" + GetCellValue(cell, workbookPart)); 
       } 
       Console.Write("\n"); 
      } 
     } 
    } 

    /// <summary> 
    /// Got code from: https://msdn.microsoft.com/en-us/library/office/hh298534.aspx 
    /// </summary> 
    /// <param name="cell"></param> 
    /// <param name="workbookPart"></param> 
    /// <returns></returns> 
    private string GetCellValue(Cell cell, WorkbookPart workbookPart) 
    { 
     if (cell == null) 
     { 
      return null; 
     } 

     var value = cell.CellFormula != null 
      ? cell.CellValue.InnerText 
      : cell.InnerText.Trim(); 

     // If the cell represents an integer number, you are done. 
     // For dates, this code returns the serialized value that 
     // represents the date. The code handles strings and 
     // Booleans individually. For shared strings, the code 
     // looks up the corresponding value in the shared string 
     // table. For Booleans, the code converts the value into 
     // the words TRUE or FALSE. 
     if (cell.DataType == null) 
     { 
      return value; 
     } 
     switch (cell.DataType.Value) 
     { 
      case CellValues.SharedString: 

       // For shared strings, look up the value in the 
       // shared strings table. 
       var stringTable = 
        workbookPart.GetPartsOfType<SharedStringTablePart>() 
         .FirstOrDefault(); 

       // If the shared string table is missing, something 
       // is wrong. Return the index that is in 
       // the cell. Otherwise, look up the correct text in 
       // the table. 
       if (stringTable != null) 
       { 
        value = 
         stringTable.SharedStringTable 
          .ElementAt(int.Parse(value)).InnerText; 
       } 
       break; 

      case CellValues.Boolean: 
       switch (value) 
       { 
        case "0": 
         value = "FALSE"; 
         break; 
        default: 
         value = "TRUE"; 
         break; 
       } 
       break; 
     } 
     return value; 
    } 
Cuestiones relacionadas