This is my function to save an array to XLS. I'm using blocks of 500 rows to obtain better speed.
Code: Select all
function exportXLS(aColTitles, aData, cHeader, cSubHeader, cType, lMsg, lAuto, cFile, oExcel, oBook, oSheet)
**********************************************************************************************************************
local i, j, nRows:=len(aData), cMsg:="", lExcelDestroy:=iif(!empty(oExcel), .F., .T.), lExcelVisible:=iif(lAuto, .F., .T.)
local nCols:=len(aData[1]), cRange:="", cColumns:="", aRow:={}, nBlokken:=0, aDataBlock:={}, nTotBreedte:=0, aOwners:={}
local nColOWNER:=0, nRowStart:=5
local xlEdgeBottom:=9, xlPortrait:=1, xlLandscape:=2, xlExcel8:=56
default cType:="X", lMsg:=.T., lAuto:=.F., cFile:=""
default oExcel:=iif(!empty(oExcel), oExcel, nil)
default oBook:=iif(!empty(oBook), oBook, nil)
default oSheet:=iif(!empty(oSheet), oSheet, nil)
if empty(oExcel)
oExcel:=CreateObject("Excel.Application")
endif
if empty(oExcel)
cMsg:="Excel not installed!"
iif(lAuto .or. !lMsg, logitem(cMsg), msgbox(cMsg))
RETURN .F.
endif
if empty(oBook) .and. !empty(oExcel)
oBook:=oExcel:Workbooks:Add()
endif
if empty(oSheet) .and. !empty(oBook)
oSheet:=oBook:ActiveSheet
endif
if !empty(nRows)
if !lAuto
DC_HourGlassOn()
endif
aSize(aRow, nCols)
for i = 1 to nCols
oSheet:cells(3,i):value := aColTitles[i]
oSheet:cells(3,i):font:bold := .T.
nTotBreedte += aColTitles[i][2]
next
if nTotBreedte < 80
oSheet:PageSetup:Orientation := xlPortrait
else
oSheet:PageSetup:Orientation := xlLandscape
endif
oSheet:PageSetup:TopMargin:=iif(!empty(cSubHeader), 45, 30)// 10 is gelijk aan 35 mm.
oSheet:PageSetup:CenterHeader:= "&B&10 " + cHeader//TODOhardcoded
if !empty(cSubHeader)
oSheet:PageSetup:CenterHeader+=chr(13)+cSubHeader
endif
oSheet:PageSetup:LeftFooter:="&B&6 "+dtoc(amain(4,1))// + dtoc(date())
oSheet:PageSetup:CenterFooter:="&B&6 &P/&N"
oSheet:PageSetup:RightFooter:="&B&6 " + amain(3,2)//TODO
for i = 1 To nRows
aRow := aData[i]
aadd(aDataBlock,aClone(aRow))
if len(aDataBlock) == 500
cColumns := Get_Excel_Column_ID(nCols)
cRange := 'A'+ alltrim(str(nRowStart+nBlokken*500,6,0))+':' + cColumns + Ltrim(Str(len(aDataBlock)+nRowStart-1+nBlokken*500))
oSheet:Range(cRange):Value := aDataBlock
asize(aDataBlock,0)
nBlokken++
endif
next
if len(aDataBlock)>0
cColumns := Get_Excel_Column_ID(nCols)
cRange := 'A'+ alltrim(str(nRowStart+nBlokken*500,6,0))+':' + cColumns + Ltrim(Str(len(aDataBlock)+nRowStart-1+nBlokken*500))
oSheet:Range(cRange):Value:=aDataBlock
endif
if !lAuto
DC_HourGlassOff()
endif
if nTotBreedte > 120
cRange:=chr(65)+alltrim(str(3))+":"+ cColumns + Ltrim(Str(len(aDataBlock)+nRowStart-1+nBlokken*500))
oSheet:Range(cRange):Borders(xlEdgeBottom):LineStyle:=1 // xlContinuous
oSheet:Range(cRange):Borders(xlEdgeBottom):Weight:=1 //xlHairline
oSheet:Range(cRange):font:size := 8
endif
for i = 1 to nCols
oSheet:Columns(i):AutoFit()
next
oExcel:ActiveWindow:SplitRow := 3
oExcel:Windows(1):FreezePanes:=.T.
do case
case cType == "P" // export to PDF
if empty(cFile)
cFile:=amain(5,2)+"\list\report"+alltrim(cHeader)+".pdf"
endif
oSheet:ExportAsFixedFormat(0, cFile)
if !lAuto
DllCall('Shell32.dll', 32,'ShellExecuteA', 0, Chr(0), amain(5,2)+'\list\report'+alltrim(cHeader)+'.pdf', Chr(0), Chr(0), 3)
oBook:Close(.F.)
endif
case !empty(cFile) // export as XLS
oSheet:SaveAs(cFile) //oSheet:SaveAs(cFile, xlExcel8)
if !lAuto
oBook:Close(.F.)
endif
otherwise
oExcel:Visible:=lExcelVisible
endcase
endif//if !empty(nRows)
if lExcelDestroy
oBook:close(.F.)
iif(valtype(oSheet) == "O", oSheet:Destroy(), nil)
iif(valtype(oBook) == "O", oBook:Destroy(), nil)
iif(valtype(oExcel) == "O", oExcel:Destroy(), nil)
oSheet := nil
oBook := nil
oExcel := nil
endif
return nil