PDA

Ver la Versión Completa : exportar a excel un string grid


davidgaldo
22-06-2005, 16:21:39
Hola , como puedo exportar a excel un stringgrid, me podeir ayudar??

roman
22-06-2005, 16:29:00
Puedes utilizar ADO para conectarte a Excel y ver una hoja como si fuera una tabla de una base de datos. Con esto no tienes más que copiar una a una las líneas.

// Saludos

davidgaldo
22-06-2005, 16:29:58
puedes ponerme un ejemplo, es que no controlo mucho.

ContraVeneno
22-06-2005, 17:21:08
Si realizas una búsqueda en los foros sobre excel o exportar a excel encontrarás mucha información respecto al tema.

roman
22-06-2005, 19:51:01
Hola

Tuve que repensar esta pregunta porque cuando te iba a poner el enlace a un ejemplo me di cuenta de un pequeño detalle.

Vamos a resumir un poco.

Hay dos métodos favoritos para acceder a una hoja de Excel:


OLE
ADO


El primero viene a ser el que te proporcionan las componentes de la paleta Servers y el segundo es usando las componentes de la paleta ADO.

La razón por la que yo siempre recomiendo ADO en lugar de OLE es porque es mucho más rápido cuando se trata de una gran cantidad de registros.

El detalle es que siempre había usado ADO para leer datos de una hoja de Excel más que para escribir. Y en este segundo caso, el problema es que si el archivo no existe hay primero que crearlo y llenar la fila de encabezados para que la conexión con ADO sea posible.

Quizá con el mismo ADO pueda crearse el archivo pero en tal caso desconozco como.

Así que vamos a dividir el problema en dos partes


Crear el archivo
Vaciar los datos


Para crear el archivo usaremos OLE, aunque directamente, sin recurrir a las componentes de la paleta Server.


const
xlWBATWorksheet = -4167;

var
Excel, WorkBook, WorkSheet: Variant;

begin
// crear instancia de la aplicación Excel (requieres la unidad ComObj)
//
Excel := CreateOleObject('Excel.Application');

// evitar que nos pregunte si deseamos sobreescribir el archivo
// (esto para el caso de que ya exista y quieras sobreescribirlo)
//
Excel.DisplayAlerts := false;

// agregar libro de trabajo
// (el parámetro indica que deseamos un libro con una sóla hoja)
//
Workbook := Excel.Workbooks.Add(xlWBATWorksheet);

// tomar una referencia a la hoja creada
//
WorkSheet := WorkBook.WorkSheets[1];

// dar nombre a la hoja
//
WorkSheet.Name := 'nombre de la hoja';

(*
Llenamos celdas
*)

// guardar el archivo
//
WorkBook.SaveAs('c:\ruta al archivo\archivo.xls');

// Terminamos la instancia de Excel
//
Excel.Quit;
end;


Para llenar las celdas lo hacemos mediante WorkSheet.Cells que es similar a StringGrid.Cells, es decir, un arreglo de dos dimensiones.

Pero hay que observar dos cosas respecto a los índices del arreglo:


En StringGrid.Cells los índices comienzan en cero mientras que en WorkSheet.Cells comienzan en 1.

En StringGrid.Cells el primer índice es de la columna y el segundo de la fila mientras que en WorkSheet.Cells es alrevés.


Así, por ejemplo, para llenar los títulos (nombres de 'campos') a partir de la primera fila del StringGrid haríamos:



for J := 0 to StringGrid.ColCount - 1 do
WorkSheet.Cells[1, J + 1] := StringGrid.Cells[J, 0];


Una vez llenados los encabezados puedes cerrar el archivo y comenzar con ADO o bien seguir llenando celdas con WorkSheet usando un doble ciclo:



for I := 1 to StringGrid1.RowCount - 1 do
for J := 0 to StringGrid1.ColCount - 1 do
WorkSheet.Cells[I + 1, J + 1] := StringGrid1.Cells[J, I];


Pero como mencioné antes, cuando se trata de muchos registros, la diferencia entre ADO y OLE puede ser enorme.

Para usar ADO necesitas una componente TAdoConnection y una componente TAdoTable.



const
AdoConn = 'Provider=%s;Data Source=%s;Extended Properties=%s';

begin
// establecer la cadena de conexión con Excel
// (esto me ha funcionado para Excel 2000 aunque para otras versiones
// quizá haya que cambiar Excel 8.0 por la versión correcta)
//
AdoConnection.ConnectionString :=
Format(AdoConn, ['Microsoft.Jet.OLEDB.4.0', FileName, 'Excel 8.0']);

AdoTable.Connection := AdoConnection;

// estas propiedades hacen la diferencia. sin ellas la velocidad de
// transferencia es aún más lenta que con OLE
//
AdoTable.CursorLocation := clUseServer;
AdoTable.CursorType := ctOpenForwardOnly;

// nombre de la 'tabla'
// debe ser el nombre que le hayamos dado a la hoja terminado por
// el caracter $
//
AdoTable.TableName := 'nombrehoja$';

AdoTable.Open;

(*
Llenamos celdas
*)

AdoTable.Close;
end;


El llenado de las celdas se hace también con un doble ciclo:



for I := 1 to StringGrid1.RowCount - 1 do
begin
AdoTable1.Append;

for J := 0 to StringGrid1.ColCount - 1 do
AdoTable1.Fields[J].Value := StringGrid1.Cells[J, I];

AdoTable1.Post;
end;


Prueba ambos métodos para el llenado de celdas y dependiendo de los resultados y la cantidad de filas escoge el más adecuado.

// Saludos