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»
Id | FirstName | LastName | Age |
1 | John | Doe | 35 |
2 | Bob | Smith | 42 |
3 | Charlie | Smith | 40 |
4 | Steve | Rights | 29 |
5 | Bill | Abrams | 24 |
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\»»
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!
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
Ya lo resolví, LO SIENTO, fue una omisión mía .. Gracias!!!
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!!
Gracias por tus comentarios!!
eso del excel te lo debo jeje