Ahora creo que dependiendo de la versión que tengas, hay soluciones a lo que pides. Yo hace mucho tiempo me construí una clase, que en su momento me resolvió el problema que tenía. Te paso un ejemplo de uso y la clase. He sacado el código del fuente que tenía y lo he adaptado para que puedas compilarlo (yo tengo FW1610 / BCC / Compilador correspondiente a la versión). El ejemplo es sencillo. Por cierto, la clase tiene un metodo para ocultar columnas del detalle de datos. Espero que te sirva para lo que necesitas.
Code: Select all
#include "fivewin.ch"
#DEFINE EXCEL_FORMAT_FILE_CSV 6
function main()
local oExcel,cNombreEmpresa:="Nombre empresa, S.C.A."
local dDesdeFecha:=CTOD(""),dHastaFecha:=date()
local aProductos:={;
{"001","Descripcion 1",14,3.99,55.86},;
{"002","Descripcion 2",1,2.5,2.5};
}
oExcel:=tExcelExport():New()
oExcel:AddTitle({cNombreEmpresa})
oExcel:AddTitle({"Fecha:" + dtoc(date())})
oExcel:AddBlankLine()
oExcel:AddTitle({"Exportación de Productos a Excel:"})
oExcel:AddTitle({"Desde Fecha:",dtoc(dDesdeFecha),"Hasta Fecha: ",dtoc(dHastaFecha)})
oExcel:AddBlankLine()
oExcel:AddHeadTitle({"Codigo", "Descripción","Udes.","Precio M.","Total"})
oExcel:SetData(aProductos)
//oExcel:SetHideColumns({6})
oExcel:AddColumnsTotals({5}) //Aqui el nº de columnas que tiene que totalizar añades los totales
oExcel:CreateFile()
return
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class tExcelExport
data nRow init 1
data nColumn init 1
data aTitles init {}
data aDatas init {}
data aTitles init {}
data aHidesColumn init {}
data aHeadTitles init {}
data aColumnTotals init {}
data cPosibleColumnWord INIT "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
data cFileName init ""
data oExcel,oSheet,oBook
data lScreenUpdating init .t.
method New() // Constructor de la Clase
method CreateFile(lSave) // Metodo que construye el excel en base a todo lo especificado. Termina abriendolo y mostrando el fichero
method SetData(aDatas) INLINE ::aDatas:=aDatas // Metodo para asignarle un array bidimensional con los datos a mostrar
method SetHideColumns(aHidesColumn) INLINE ::aHidesColumn:=aHidesColumn // Metodo para asignar un array unidimensional con las columnas de los datos que no queremos mostrar
method ReviewExcel()
method SetName(cFileName) INLINE ::cFileName:=cFileName // Establecemos un nombre al fichero de salida
method AddTitle(aValues) INLINE aadd(::aTitles,aValues) // Método para añadir lineas de titulo al documento
method AddBlankLine() INLINE aadd(::aTitles,{""}) // Método simple para añadir una linea en blanco (seria como un salto de línea)
method AddHeadTitle(aHeadTitles) INLINE ::aHeadTitles:=aHeadTitles // Metodo para añadir un array unidimensional con los nombre de las cabeceras de los datos
method AddColumnsTotals(aColumnTotals) INLINE ::aColumnTotals:=aColumnTotals
method SetViewUpdating(lView) INLINE ::lScreenUpdating:=lView
end class
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
method New() class tExcelExport
return self
method CreateFile(lSave) class tExcelExport
local i,x,nTamTitle,nTamTitleElement,nTam,nTamData,nPos,nPosicionComienzoDetalle,nFilasImpresas:=0,cFileName
local lActivaDobleLetraColumna:=.f.
default lSave:=.f.
if !::ReviewExcel()
msgalert("Microsoft Excel NO instalado. La exportación no se va a llevar a cabo","¡Atención!")
return
end if
::oExcel:ScreenUpdating := ::lScreenUpdating
::oBook:=::oExcel:WorkBooks:Add()
::oSheet:=::oExcel:ActiveSheet
nTamTitle:=len(::aTitles)
for i = 1 to nTamTitle
nTamTitleElement:=len(::aTitles[i])
for x = 1 to nTamTitleElement
::oSheet:Cells( ::nRow, ::nColumn):Value:=::aTitles[i,x]
::nColumn++
next x
::nColumn:=1
::nRow++
next i
//Ahora pintamos las cabeceras de las columnas
nTamData:=len(::aHeadTitles)
if nTamData>0
for i = 1 to nTamData
nPos:=ASCAN(::aHidesColumn,i)
if nPos = 0
::oSheet:Cells( ::nRow, ::nColumn):Value:=::aHeadTitles[i]
::nColumn++
end if
next i
//Pintamos una linea de separacion entre lo ultimo impreso y el detalle a imprimir
::oSheet:Range( ::oSheet:Cells( ::nRow, 1 ), ::oSheet:Cells( ::nRow, nTamData-len(::aHidesColumn) ) ):Select()
::oExcel:Selection:Borders(9):LineStyle := 1 // xlContinuous = 1
::oSheet:Rows( ::nRow ):Font:Bold := .T.
::nRow++
::nColumn:=1
end if
//Ahora el detalle
nPosicionComienzoDetalle:=::nRow
nTam:=len(::aDatas)
if nTam>0
nTamData:=len(::aDatas[1])
for i = 1 to nTam
for x = 1 to nTamData
nPos:=ASCAN(::aHidesColumn,x)
if nPos = 0
::oSheet:Cells( ::nRow, ::nColumn):Value:=::aDatas[i,x]
::nColumn++
end if
next x
::nColumn:=1
::nRow++
next i
::oSheet:Range( ::oSheet:Cells( ::nRow-1, 1 ), ::oSheet:Cells( ::nRow-1, nTamData-len(::aHidesColumn) ) ):Select()
if !lSave //Si se va a crear un fichero, no le ponemos los bordes
::oExcel:Selection:Borders(9):LineStyle := 1 // xlContinuous = 1
end if
//Vamos a no ajustar el texto en las columnas que sean caracter
for x = 1 to nTamData
nPos:=ASCAN(::aHidesColumn,x)
if nPos = 0
if valtype(::aDatas[1,x]) = "C"
::oSheet:Range( ::oSheet:Cells( 1, x ), ::oSheet:Cells( ::nRow , x) ):Select()
::oExcel:Selection:WrapText:=.f.
end if
end if
next x
end if
//AHora vamos a añadir los totales si los hubiera
for i = 1 to len(::aColumnTotals)
nPos:=ASCAN(::aHidesColumn,i)
if nPos = 0
if !lActivaDobleLetraColumna
::oSheet:Cells(::nRow,::aColumnTotals[i]):Formula:="=SUMA("+substr(::cPosibleColumnWord,::aColumnTotals[i],1)+alltrim(str(nPosicionComienzoDetalle)) + ":"+substr(::cPosibleColumnWord,::aColumnTotals[i],1)+alltrim(str(::nRow-1))+")" // APLICAR FORMULA A UNA CELDA
if substr(::cPosibleColumnWord,::aColumnTotals[i],1) = "Z"
lActivaDobleLetraColumna:=.t.
end if
else
::oSheet:Cells(::nRow,::aColumnTotals[i]):Formula:="=SUMA(A"+substr(::cPosibleColumnWord,::aColumnTotals[i],1)+alltrim(str(nPosicionComienzoDetalle)) + ":A"+substr(::cPosibleColumnWord,::aColumnTotals[i],1)+alltrim(str(::nRow-1))+")" // APLICAR FORMULA A UNA CELDA
end if
end if
next i
::oSheet:Cells(1,1):Select()
if !lSave
::oExcel:Visible:=.t.
else
if !empty(::cFileName)
cFileName:=alltrim(::cFileName)
else
cFileName:=".\Excel_Export_" + dtos(date()) + strtran(time(),":","") + ".csv"
end if
::oSheet:SaveAs(cFileName,EXCEL_FORMAT_FILE_CSV)
::oBook:Close(.t.)
msginfo("Se ha generado el fichero " + cFileName,"Información")
end if
return
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
method ReviewExcel() class tExcelExport
TRY
::oExcel:= GetActiveObject( "Excel.Application" )
CATCH
TRY
::oExcel:= CreateObject( "Excel.Application" )
CATCH
return .f.
END
END
return .t.