Muchas veces ejecutamos nuestras aplicaciones en servidores que no sólo tienen las aplicaciones justas para obtener sus servicios, y en alguna ocasión no tenemos ni siquiera acceso a ellos. Éste era el caso al que nos hemos enfrentado estos días, en el que necesitábamos abrir un archivo Excel desde una aplicación .NET, pero el servidor no tenía instalado Office y, por tanto, no tenía las dlls necesarias para abrir los archivos.
Este era el error que recibíamos:
The 'microsoft.jet.oledb.4.0' provider is not registered on the local machine.
Evidentemente, con registrar la dll con regsvr32 hubiese bastado, pero no podíamos (debíamos J ) tocar el servidor para esas cosas. Camino prohibido…
Investigando encontramos esta forma de abrir un Excel y generar un Dataset, usando la librería "Microsoft.Office.Interop.Excel":
private
DataSet OpenExcelFile(string sPath)
{
try
{
//use this way to open the excel file without office:
Microsoft.Office.Interop.Excel.Application ExcelObj = new Microsoft.Office.Interop.Excel.Application();
DataSet ds = new
DataSet();
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add();
dt.Columns.Add();
dt.Columns.Add();
if (ExcelObj == null)
{
Log("Excel object not found", MessageType.Error);
}
Workbook theWorkbook = ExcelObj.Workbooks.Open(sPath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Sheets sheets = theWorkbook.Worksheets;
Worksheet worksheet = (Worksheet)sheets.get_Item(1);
int index = 0;
object rowIndex = 2;
DataRow row;
while (((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[rowIndex, 1]).Value2 != null)
{
rowIndex = 2 + index;
row = dt.NewRow();
object[] itemArr = { Convert.ToString(((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[rowIndex, 1]).Value2),
Convert.ToString(((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[rowIndex, 2]).Value2),
Convert.ToString(((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[rowIndex, 3]).Value2) };
row.ItemArray = itemArr;
index++;
dt.Rows.Add(row);
}
ds.Tables.Add(dt);
Log("Dataset created properly", MessageType.Success);
return ds;
}
catch (Exception exc)
{
throw
new
Exception(exc.Message);
}
}
La única "pega" (leve) es que con el método convencional (conexión con el provider Microsoft.Jet.OLEDB.4.0) el dataset se creaba automáticamente y los datos podrían estar en cualquier columna del sheet, que él solito cogía los datos correctos. Aquí, como veis, los datos tienen que estar en la fila 1 columna 1. Se podría añadir código para que lo cogiese automáticamente, pero en mi caso no era necesario.