Como pasar de Excel a SQL con LinQ en Visual Studio y C#

Supongamos que queremos pasar información de un archivo de excel a nuestras tablas de SQL. Supongamos de un ejemplo simple con este archivo simple en excel con datos en «Hoja1»

 

IdFirstNameLastNameAge
1JohnDoe35
2BobSmith42
3CharlieSmith40
4SteveRights29
5BillAbrams24

Ahora digamos que deseas leer todos los empleados de esta hoja en una lista sin tipo y ordenar el resultado según la edad.

Comenzamos en nuestro programa haciendo los siguientes metodos o agregando una clase como esta:

using System.Data;
using System.Data.OleDb;

namespace LinqToExcel
{
    /// <summary>
    /// Provides linq querying functionality towards Excel (xls) files
    /// </summary>
    public class LinqToExcelProvider
    {
        /// <summary>
        /// Gets or sets the Excel filename
        /// </summary>
        private string FileName { get; set; }

        /// <summary>
        /// Template connectionstring for Excel connections
        /// </summary>
        private const string ConnectionStringTemplate = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=Excel 8.0;";

        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="fileName">The Excel file to process</param>
        public LinqToExcelProvider(string fileName)
        {
            FileName = fileName;
        }

        /// <summary>
        /// Returns a worksheet as a linq-queryable enumeration
        /// </summary>
        /// <param name="sheetName">The name of the worksheet</param>
        /// <returns>An enumerable collection of the worksheet</returns>
        public EnumerableRowCollection<DataRow> GetWorkSheet(string sheetName)
        {
            // Build the connectionstring
            string connectionString = string.Format(ConnectionStringTemplate, FileName);

            // Query the specified worksheet
            OleDbDataAdapter dataAdapter = new OleDbDataAdapter(string.Format("SELECT * FROM [{0}$]", sheetName), connectionString);

            // Fill the dataset from the data adapter
            DataSet myDataSet = new DataSet();
            dataAdapter.Fill(myDataSet, "ExcelInfo");

            // Initialize a data table which we can use to enumerate the contents based on the dataset
            DataTable dataTable = myDataSet.Tables["ExcelInfo"];

            // Return the data table contents as a queryable enumeration
            return dataTable.AsEnumerable();
        }
    }
}

despues podemos usar estos métodos como en el siguiente ejemplo de una aplicación de consola que los trae desde el excel y los muestra en pantalla ordenados por id.

using System;
using System.Data;

namespace LinqToExcel
{
    class Program
    {
        static void Main(string[] args)
        {
            // Initialize the linq to excel provider
            LinqToExcelProvider provider = new LinqToExcelProvider(@"c:\Employees.xls");

            // Query the worksheet
            var query = from p in provider.GetWorkSheet("Hoja1")
                        select new
                        {
                            Id = Convert.ToInt32(p.Field<object>("Id")),
                            FirstName = Convert.ToString(p.Field<object>("FirstName")),
                            LastName = Convert.ToString(p.Field<object>("LastName")),
                            Age = Convert.ToInt32(p.Field<object>("Age"))
                        };

            // Display the query result ordered by age
            foreach (var row in query.OrderBy(p => p.Age))
            {
                Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", row.Id, row.FirstName, row.LastName, row.Age));
            }

            // Pause
            Console.ReadKey();
        }
    }
}

con eso fácilmente podemos tomar los elementos del excel y almacenarlos a nuestro antojo en variables, objetos de clases o lo que gusten para despues insertarlos a nuestras bases de datos de  SQL como estén acostumbrados.

tomen en cuenta que la siguiente cadena de conexión me funcionó tanto para excel 97-2003 como para los nuevos 2007-2010. Pero la que está en el código es solo para 97-2003. Aunque para la siguiente quisá tengan que instalar algo si no les funciona. En mi caso no, quiza por tener VS 2010 ultimate. Recuerden también respetar las comillas dobles y todo.

private const string ConnectionStringTemplate = «Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\»Excel 8.0;HDR=Yes;IMEX=1\»»

También te podría gustar...

6 Respuestas

  1. Mirna dice:

    Hola … MUCHAS GRACIAS por compartirlo, es justo lo que estaba buscando, apenas estoy haciendo mis pininos en Visual Studio C#, fíjate que me marca error en Field en el query, me dice — ‘System.Data.DataRow’ no contiene una definición de ‘Field’ ni se encontró ningún método de extensión ‘Field’ que acepte un primer argumento del tipo ‘System.Data.DataRow’ (¿falta una directiva de uso o una referencia de ensamblado?) — qué puedo hacer?? GRACIAS!

    • Anónimo dice:

      a mi me pasó y fue porque estaba utilizando una librería que no era compatible con el netframework o puede ser también que te falte agregar la referencia al proyecto.

      Saludos

  2. Mirna dice:

    Ya lo resolví, LO SIENTO, fue una omisión mía .. Gracias!!!

  3. Mirna dice:

    Ups, nadie contestó a mi primer pregunta, espero tener suerte esta ocasión, cómo le puedo hacer para leer el archivo de excel a partir de una fila específica?, ya encontré como hacerle cuando no tiene encabezados pero no he encontrado lo que pregunto, GRACIAS!!

Escribeme un comentario

Tu dirección de correo electrónico no será publicada.