Files
comun/utile/excel/excelxml.vc2

1290 lines
49 KiB
Plaintext

*--------------------------------------------------------------------------------------------------------------------------------------------------------
* (EN) AUTOGENERATED - ATTENTION!! - NOT INTENDED FOR EXECUTION!! USE ONLY FOR MERGING CHANGES AND STORING WITH SCM TOOLS!!
*--------------------------------------------------------------------------------------------------------------------------------------------------------
*< FOXBIN2PRG: Version="1.21" SourceFile="excelxml.vcx" CPID="1252" /> (Solo para binarios VFP 9 / Only for VFP 9 binaries)
*
*
DEFINE CLASS excelxml AS custom
*< CLASSDATA: Baseclass="custom" Timestamp="" Scale="Pixels" Uniqueid="" />
*<DefinedPropArrayMethod>
*m: about && About ExcelXML class
*m: addnewstyle && Cria o estilo para o excel caso ainda não exista um igual e retorna o a string xml do estilo criado.
*m: buildcolumnsstyles && Cria os estilos para uso das colunas e linhas. Ou seja, cada celula do grid é analizada para compor o seu estilo.
*m: buildcolumnswidth && Cria propriedades com as definições de cada coluna
*m: buildheadersstyles && Cria os estilos para uso do cabeçalho
*m: buildrows && Prepara o conteudo da tabela baseado nos estilos encontrados.
*m: colortostrhexa && Converto a cor do vfp para hexadecimal
*m: getcolumn && Retorna o objeto da coluna conforme sua ordem de apresentação no grid
*m: getcolumnalign && Retorna o alinhamento de um objeto para ser usado na linha/coluna (célula) do Excel
*m: getcolumnheader && Retorna o nome do header da coluna indicada
*m: getcurrentcontrolobject && Retorna o objeto corrente dentro da linha/coluna
*m: hascolumnvisible && Retorna o numero de colunas visiveis no grid
*m: progress && Method used to show the percentage processed.
*m: save && Creates the Excel XML file.
*m: seekstyle && Busco o estilo que será usado na Coluna/Linha (célula)
*p: alias && Name of the table/cursor defined in the Grid or name of current table/cursor opened.
*p: columncount && Returns the number of columns included in the Excel file.
*p: crlf
*p: dateformat && Specifies the date format.
*p: file && Inform the name of Excel file. If you don't inform the name with the extension, the XML extension will be included. The default file name is "Book1"
*p: gridobject && Inform the grid control object to convert a grid control in an Excel XML file.
*p: hasfilter && .T. Includes the option Filter in all columns in the generated file.
*p: lockheader && .T. locks the header in the generated file. This option in Excel is called by Freeze Top Row.
*p: openaftersaving && .T. to open the file after saving it.
*p: rowcount && Returns the number of rows included in the Excel file.
*p: setstyles && Defines if the Excel file will have all the grid graphical attributes transported.
*p: sheetname && Excel sheet name. The default name is "Sheet1"
*p: stylecodenumber
*p: version && Object that contain the information about this class.
*p: xmlencoding && XML encoding type used to set the code that defines special characters. Default code is "iso-8859-1".
*a: afields[1,18] && Array with information about the structure of the table in a specified work area, specified by a table alias, or in the currently selected work area in an array and returns the number of fields in the table.
*p: _memberdata && XML Metadata for customizable properties
*</DefinedPropArrayMethod>
HIDDEN afields,crlf,dateformat,stylecodenumber
PROTECTED alias
*<PropValue>
alias =
columncount = 0
crlf =
dateformat =
file =
gridobject =
hasfilter = .F.
Height = 16
lockheader = .F.
Name = "excelxml"
openaftersaving = .F.
rowcount = 0
setstyles = .T.
sheetname = Sheet1
stylecodenumber = 0
version =
Width = 70
xmlencoding = iso-8859-1
_memberdata = <VFPData>
<memberdata name="hasfilter" display="HasFilter" type="property"/>
<memberdata name="file" display="File" type="property"/>
<memberdata name="sheetname" display="SheetName" type="property"/>
<memberdata name="gridobject" display="GridObject" type="property"/>
<memberdata name="lockheader" display="LockHeader" type="property"/>
<memberdata name="columncount" display="ColumnCount" type="property"/>
<memberdata name="rowcount" display="RowCount" type="property"/>
<memberdata name="version" display="Version" type="property"/>
<memberdata name="setstyles" display="SetStyles" type="property"/>
<memberdata name="xmlencoding" display="xmlEncoding" type="property"/>
<memberdata name="openaftersaving" display="OpenAfterSaving" type="property"/>
<memberdata name="righttoleft" display="RightToLeft" type="property"/>
<memberdata name="save" display="Save" type="method"/>
<memberdata name="about" display="About" type="method"/>
<memberdata name="progress" display="Progress" type="method"/>
</VFPData>
*</PropValue>
PROCEDURE about && About ExcelXML class
messagebox("ExcelXML " + this.version.number + " " + this.version.datetime + this.CRLF +;
"Converts a Grid control into a Microsoft Excel XML file" + this.CRLF +;
"" + this.CRLF +;
"Created by "+ this.version.author + this.CRLF +;
this.version.CountryAndCity + this.CRLF +;
this.version.url + this.CRLF +;
this.version.email, 64, "About ExcelXML")
ENDPROC
PROTECTED PROCEDURE addnewstyle && Cria o estilo para o excel caso ainda não exista um igual e retorna o a string xml do estilo criado.
lparameters plcType, plnRow, plnCol ,;
plcAlignH, plcAlignV, plcFontName, plcFontFamily ,;
plcFontSize, plcForeColor, plcFontBold, plcFontItalic ,;
plcFontUnderline, plcFontStrikeThru, plcBackColor, plcPattern ,;
plcFormat
local lcStyleCode, lcXmlStyle
lcXmlStyle = ""
*- Definição de bordas entre as linhas/colunas (células)
lcXmlBorderStyle = ""
lcTop = "0"
lcBottom = "0"
if this.GridObject.GridLines >= 1 and this.Setstyles
lcGridLineWidth = iif(plcType="c", alltrim(str(iif(this.GridObject.GridLineWidth>=4, 3, this.GridObject.GridLineWidth))), "1")
lcGridLineColor = iif(plcType="c", this.ColorToStrHexa(this.GridObject.GridLineColor), this.ColorToStrHexa(rgb(100,100,100)))
lcXmlBorderStyle = [ <Borders>] + this.CRLF
*- Linhas na horizontal
if inlist(this.GridObject.GridLines, 1, 3)
lcXmlBorderStyle = lcXmlBorderStyle + [ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="]+lcGridLineWidth+[" ss:Color="]+lcGridLineColor+["/>] + this.CRLF
lcXmlBorderStyle = lcXmlBorderStyle + [ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="]+lcGridLineWidth+[" ss:Color="]+lcGridLineColor+["/>] + this.CRLF
endif
*- Linhas na vertical
if inlist(this.GridObject.GridLines, 2, 3)
if this.GridObject.GridLines = 2
if plnRow = 1 &&- Se for a primeira linha
lcTop = "1"
lcXmlBorderStyle = lcXmlBorderStyle + [ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="]+lcGridLineWidth+[" ss:Color="]+lcGridLineColor+["/>] + this.CRLF
else
if plnRow = (this.RowCount-1) &&- Se for a ultima linha
lcBottom = "1"
lcXmlBorderStyle = lcXmlBorderStyle + [ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="]+lcGridLineWidth+[" ss:Color="]+lcGridLineColor+["/>] + this.CRLF
endif
endif
endif
lcXmlBorderStyle = lcXmlBorderStyle + [ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="]+lcGridLineWidth+[" ss:Color="]+lcGridLineColor+["/>] + this.CRLF
lcXmlBorderStyle = lcXmlBorderStyle + [ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="]+lcGridLineWidth+[" ss:Color="]+lcGridLineColor+["/>] + this.CRLF
endif
lcXmlBorderStyle = lcXmlBorderStyle + [ </Borders>] + this.CRLF
else
lcXmlBorderStyle = [ <Borders></Borders>] + this.CRLF
endif
*- Adiciono no cursor caso não ache um registro com os mesmos dados
if not seek(plcAlignH + plcAlignV + plcFontName + plcFontFamily + ;
plcFontSize + plcForeColor + plcFontBold + plcFontItalic + ;
plcFontUnderline + plcFontStrikeThru + plcBackColor + plcPattern +;
plcFormat + lcTop + lcBottom ,;
"xxxStylesProperties","idxStyle")
this.StyleCodeNumber = this.StyleCodeNumber + 1
lcStyleCode = alltrim(lower(plcType))+transform(this.StyleCodeNumber, "@L 99999")
*- xml de estilo da celula
lcXmlStyle = [ <Style ss:ID="]+lcStyleCode+[">] + this.CRLF +;
[ <Alignment ss:Horizontal="]+alltrim(plcAlignH)+[" ss:Vertical="]+alltrim(plcAlignV)+["/>] + this.CRLF +;
[ <Font ss:FontName="]+alltrim(plcFontName)+[" x:Family="]+alltrim(plcFontFamily)+[" ss:Size="]+alltrim(str(val(plcFontSize)))+[" ss:Color="]+alltrim(plcForeColor)+["] + this.CRLF +;
[ ss:Bold="]+plcFontBold+[" ss:Italic="]+plcFontItalic+["]+iif(!empty(plcFontUnderline),[ ss:Underline="]+alltrim(plcFontUnderline)+["],"")+[ ss:StrikeThrough="]+alltrim(plcFontStrikeThru)+["/>] + this.CRLF +;
iif(this.SetStyles, [ <Interior ss:Color="]+alltrim(plcBackColor)+[" ss:Pattern="]+alltrim(plcPattern)+["/>], [ <Interior/>] ) + this.CRLF +;
iif(!empty(plcFormat), [ <NumberFormat ss:Format="]+alltrim(plcFormat)+["/>] + this.CRLF, "") +;
lcXmlBorderStyle +;
[ </Style>]
insert into xxxStylesProperties ;
values ( lcStyleCode ,;
plcAlignH ,;
plcAlignV ,;
plcFontName ,;
plcFontFamily ,;
plcFontSize ,;
plcForeColor ,;
plcFontBold ,;
plcFontItalic ,;
plcFontUnderline ,;
plcFontStrikeThru ,;
plcBackColor ,;
plcPattern ,;
plcFormat ,;
lcTop ,;
lcBottom ,;
lcXmlStyle )
endif
insert into xxxStylesRowCol ;
values ( transform(plnRow, "@L 999999") ,;
transform(plnCol, "@L 999") ,;
xxxStylesProperties.ssCode )
return lcXmlStyle
ENDPROC
PROTECTED PROCEDURE buildcolumnsstyles && Cria os estilos para uso das colunas e linhas. Ou seja, cada celula do grid é analizada para compor o seu estilo.
*!* 12.10.2016
*!* marius.mutu
*!* try catch endtry for dynamic properties (ex: this.readonly - error)
local lcAlignH, lcAlignV, lcFontName, lcFontFamily, ;
lcFontSize, lcForeColor, lcFontBold, lcFontItalic, ;
lcFontUnderline, lcFontStrikeThru, lcBackColor, lcPattern, ;
lcFormat, lcXmlBorderStyle, lcXmlStyles, lnRow, lnCol, lnRowFound
this.StyleCodeNumber = 0
lnRow = 0
lnCol = 0
lcXmlStyles = ""
*- Verifico os estilos de todas as linhas/colunas do grid
select (this.Alias)
go top
scan
lnRow = lnRow + 1
if not this.SetStyles and lnRow >= 2 &&- Não aplica os estilos ao grid.
exit
endif
for lnCol = 1 to this.GridObject.ColumnCount
loColumn = this.GetColumn(lnCol)
if not loColumn.Visible &&-Considero somente as colunas visiveis
loop
endif
*- Formato dos dados da linha/coluna (célula)
lcDataColumn = evaluate(loColumn.ControlSource)
loCurrentControl = this.GetCurrentControlObject(loColumn)
lcFormat = ""
if not isnull(loCurrentControl)
do case
case inlist(vartype(lcDataColumn),"N","Y")
if lower(loCurrentControl.BaseClass) $ "textbox//spinner"
if not empty(loColumn.InputMask)
lcInputMask = loColumn.InputMask
if occurs(".",lcInputMask) > 0
lcFormat = "#,##0." + replicate("0", len(subs(lcInputMask, rat(".",lcInputMask)+1)))
else
lcFormat = "#,##0"
endif
else
lnRowFound = ascan(this.AFields, iif("."$loColumn.ControlSource, substr(loColumn.ControlSource, at(".",loColumn.ControlSource)+1), loColumn.ControlSource), -1,-1, 1, 15)
if lnRowFound > 0 and this.AFields[lnRowFound,4] > 0
lcFormat = "#,##0." + replicate("0", this.AFields[lnRowFound,4])
else
lcFormat = ""
endif
endif
endif
if lower(loCurrentControl.BaseClass) $ "checkbox//optiongroup"
lcFormat = ""
endif
case vartype(lcDataColumn) = "D"
lcFormat = this.DateFormat + ";@"
case vartype(lcDataColumn) = "T"
if lower(loCurrentControl.BaseClass) = "textbox"
lnHasSeconds = loCurrentControl.Seconds
else
lnHasSeconds = 2
endif
if lnHasSeconds = 0
*- Data e hora sem segundos
lcFormat = this.DateFormat+"\ h:mm" + iif(set("hours")=12," AM/PM","")
else
*- Data e hora com segundos
lcFormat = this.DateFormat+"\ h:mm:ss" + iif(set("hours")=12," AM/PM","")
endif
case vartype(lcDataColumn) = "L"
lcFormat = "True/False"
otherwise
lcFormat = ""
endcase
endif
lcFormat = padr(lcFormat, len(xxxStylesProperties.ssFormat))
*- Requisitos fixos para o estilo
lcFontFamily = padr("Swiss", len(xxxStylesProperties.ssFontFamily))
lcPattern = padr("Solid", len(xxxStylesProperties.ssPattern))
*- Alinhamento Horizontal do texto da coluna/linha
if not isnull(loCurrentControl) and lower(loCurrentControl.BaseClass) = "combobox"
lcAlignH = this.GetColumnAlign("H", loCurrentControl.Alignment, vartype(lcDataColumn))
lcAlignV = this.GetColumnAlign("V", loCurrentControl.Alignment, vartype(lcDataColumn))
else
lcAlignH = this.GetColumnAlign("H", loColumn.Alignment, vartype(lcDataColumn))
lcAlignV = this.GetColumnAlign("V", loColumn.Alignment, vartype(lcDataColumn))
endif
*- cor de fundo da coluna/linha
if not empty(loColumn.DynamicBackColor)
TRY
lcBackColor = this.ColorToStrHexa( evaluate(loColumn.DynamicBackColor) )
CATCH
lcBackColor = this.ColorToStrHexa( loColumn.BackColor )
ENDTRY
else
lcBackColor = this.ColorToStrHexa( loColumn.BackColor )
endif
*- cor da fonte da coluna/linha
if not empty(loColumn.DynamicForeColor)
TRY
lcForeColor = this.ColorToStrHexa( evaluate(loColumn.DynamicForeColor) )
CATCH
lcForeColor = this.ColorToStrHexa( loColumn.ForeColor )
ENDTRY
else
lcForeColor = this.ColorToStrHexa( loColumn.ForeColor )
endif
*- fonte usada na coluna/linha
if not empty(loColumn.DynamicFontName)
TRY
lcFontName = evaluate(loColumn.DynamicFontName)
CATCH
lcFontName = loColumn.FontName
ENDTRY
else
lcFontName = loColumn.FontName
endif
lcFontName = padr(lcFontName, len(xxxStylesProperties.ssFontName))
*- tamanho da fonte da coluna/linha
if not empty(loColumn.DynamicFontSize)
TRY
lcFontSize = transform(evaluate(loColumn.DynamicFontSize), "@L 999")
CATCH
lcFontSize = transform(loColumn.FontSize, "@L 999")
ENDTRY
else
lcFontSize = transform(loColumn.FontSize, "@L 999")
endif
*- Fonte Italica da coluna/linha
if not empty(loColumn.DynamicFontItalic)
TRY
lcFontItalic = iif(evaluate(loColumn.DynamicFontItalic), "1", "0")
CATCH
lcFontItalic = iif(loColumn.FontItalic, "1", "0")
ENDTRY
else
lcFontItalic = iif(loColumn.FontItalic, "1", "0")
endif
*- Fonte Negrito da coluna/linha
if not empty(loColumn.DynamicFontBold)
TRY
lcFontBold = iif(evaluate(loColumn.DynamicFontBold), "1", "0")
CATCH
lcFontBold = iif(loColumn.FontBold, "1", "0")
ENDTRY
else
lcFontBold = iif(loColumn.FontBold, "1", "0")
endif
*- Fonte Underline da coluna/linha
if not empty(loColumn.DynamicFontUnderline)
TRY
lcFontUnderline = iif(evaluate(loColumn.DynamicFontUnderline), "Single", "")
CATCH
lcFontUnderline = iif(loColumn.FontUnderline, "Single", "")
ENDTRY
else
lcFontUnderline = iif(loColumn.FontUnderline, "Single", "")
endif
lcFontUnderline = padr(lcFontUnderline, len(xxxStylesProperties.ssFontUnderline))
*- Fonte Underline da coluna/linha
if not empty(loColumn.DynamicFontStrikeThru)
TRY
lcFontStrikeThru = iif(evaluate(loColumn.DynamicFontStrikeThru), "1", "0")
CATCH
lcFontStrikeThru = iif(loColumn.FontStrikeThru, "1", "0")
ENDTRY
else
lcFontStrikeThru = iif(loColumn.FontStrikeThru, "1", "0")
endif
lcFontStrikeThru = padr(lcFontStrikeThru, len(xxxStylesProperties.ssFontStrikeThru))
*- se o estilo já existir "lcXmlStyle" retorna ""
lcXmlStyle = this.AddNewStyle( "c", lnRow, lnCol, ;
lcAlignH, lcAlignV, lcFontName, lcFontFamily, ;
lcFontSize, lcForeColor, lcFontBold, lcFontItalic, ;
lcFontUnderline, lcFontStrikeThru, lcBackColor, lcPattern, ;
lcFormat )
if not empty(lcXmlStyle)
lcXmlStyles = lcXmlStyles + this.CRLF + lcXmlStyle
endif
endfor
endscan
return lcXmlStyles
ENDPROC
PROTECTED PROCEDURE buildcolumnswidth && Cria propriedades com as definições de cada coluna
local lcXmlColumnsWidth, lnCol, lnColumnWidth
lcXmlColumnsWidth = this.CRLF
for lnCol = 1 to this.GridObject.ColumnCount
loColumn = this.GetColumn(lnCol)
if loColumn.Visible = .T.
lnColumnWidth = iif(loColumn.width>700,700,loColumn.width) &&- Avoiding error in Excel
lcXmlColumnsWidth = lcXmlColumnsWidth + [ <Column ss:AutoFitWidth="0" ss:Width="]+alltrim(str(lnColumnWidth))+["/>] + this.CRLF
endif
endfor
return lcXmlColumnsWidth
ENDPROC
PROTECTED PROCEDURE buildheadersstyles && Cria os estilos para uso do cabeçalho
local loColumn, loColumnHeader, lnCol, lcXmlStyles, lcXmlStyle, ;
lcBackColor, lcForeColor, lcFontName, lcFontSize, lcFontItalic, ;
lcFontBold, lcFontUnderline, lcFontStrikeThru, lcFormat, ;
lcFontFamily, lcPattern, lcAlignH, lcAlignV, lcCollate
lcXmlStyle = ""
lcXmlStyles = ""
this.StyleCodeNumber = 0
lcCollate = set("Collate")
set collate to "MACHINE"
*- Crio cursor para armazenar todos os estilos encontrados
create cursor xxxStylesProperties ( ssCode c(6) ,;
ssAlignH c(6) ,;
ssAlignV c(6) ,;
ssFontName c(40) ,;
ssFontFamily c(5) ,;
ssFontSize c(3) ,;
ssFontColor c(7) ,;
ssFontBold c(1) ,;
ssFontItalic c(1) ,;
ssFontUnderline c(6) ,;
ssFontStrikeThru c(1) ,;
ssBackColor c(7) ,;
ssPattern c(5),;
ssFormat c(40) ,;
ssTop c(1) ,;
ssBottom c(1) ,;
ssStyle m )
select xxxStylesProperties
index on ssAlignH + ssAlignV + ssFontName + ;
ssFontFamily + ssFontSize + ssFontColor + ;
ssFontBold + ssFontItalic + ssFontUnderline + ssFontStrikeThru + ;
ssBackColor + ssPattern + ssFormat + ssTop + ssBottom tag idxStyle
index on ssCode tag idxCode
*- Crio cursor para gravar o estilo que sera usado pela linha/coluna (célula)
create cursor xxxStylesRowCol ( ssRow c(6) ,;
ssCol c(3) ,;
ssCode c(6) )
select xxxStylesRowCol
index on ssRow + ssCol tag idxRowCol
set collate to lcCollate
*- Verifico os estilos dos headers de cada coluna
if this.GridObject.HeaderHeight > 0
for lnCol = 1 to this.GridObject.ColumnCount
loColumn = this.GetColumn(lnCol)
loColumnHeader = this.GetColumnHeader(loColumn)
lcBackColor = this.ColorToStrHexa( iif(this.SetStyles, loColumnHeader.BackColor, rgb(255,255,255)) )
lcForeColor = this.ColorToStrHexa( iif(this.SetStyles, loColumnHeader.ForeColor, rgb(0,0,0)) )
lcFontName = padr(loColumnHeader.FontName, len(xxxStylesProperties.ssFontName))
lcFontSize = transform(loColumnHeader.FontSize, "@L 999")
lcFontItalic = iif(loColumnHeader.FontItalic, "1", "0")
lcFontBold = iif(loColumnHeader.FontBold or this.SetStyles=.f., "1", "0")
lcFontUnderline = padr(iif(loColumnHeader.FontUnderline or this.SetStyles=.f., "Single", ""), len(xxxStylesProperties.ssFontUnderline))
lcFontStrikeThru = iif(loColumnHeader.FontStrikeThru, "1", "0")
lcFormat = padr("", len(xxxStylesProperties.ssFormat))
lcFontFamily = padr("Swiss", len(xxxStylesProperties.ssFontFamily))
lcPattern = padr("Solid", len(xxxStylesProperties.ssPattern))
lcAlignH = iif(this.SetStyles, this.GetColumnAlign("H", loColumnHeader.Alignment), "Left")
lcAlignV = iif(this.SetStyles, this.GetColumnAlign("V", loColumnHeader.Alignment), "Center")
*- se o estilo já existir "lcXmlStyle" retorna ""
lcXmlStyle = this.AddNewStyle( "h", 0, lnCol, ;
lcAlignH, lcAlignV, lcFontName, lcFontFamily, ;
lcFontSize, lcForeColor, lcFontBold, lcFontItalic, ;
lcFontUnderline, lcFontStrikeThru, lcBackColor, lcPattern, ;
lcFormat )
if not empty(lcXmlStyle)
lcXmlStyles = lcXmlStyles + this.CRLF + lcXmlStyle
endif
endfor
endif
return lcXmlStyles
ENDPROC
PROTECTED PROCEDURE buildrows && Prepara o conteudo da tabela baseado nos estilos encontrados.
local lcXmlRows, lcDataType, lcDataColumn, lcAuxDataColumn, lnRow, lnCol, loColumn, loColumnHeader, loCurrentControl, ;
lnPercent, lnCountRowSource, lcCountOption, laArrayTmp, lcComboOption, lcToolTipText, lnBytes, llHasDecimals, ;
lnSetDecimals, lnRowFound, lnYear
lcXmlRows = this.CRLF
lnRow = 0
lnCol = 0
lnBytes = 0
lnSetDecimals = set("Decimals")
*- Adiciono a linha do Header no arquivo excel
if this.GridObject.HeaderHeight > 0
lcXmlRows = lcXmlRows + [ <Row ss:AutoFitHeight="0" ss:Height="]+alltrim(str(this.GridObject.HeaderHeight))+[">] + this.CRLF
for lnCol = 1 to this.GridObject.ColumnCount
loColumn = this.GetColumn(lnCol)
loColumnHeader = this.GetColumnHeader(loColumn)
if loColumn.Visible = .T.
*- caso tenha tooltiptext
lcToolTipText = ""
if not empty(loColumnHeader.ToolTipText)
lcToolTipText = [<Comment ss:Author="Rodrigo_Bruscain">]+;
[<ss:Data xmlns="http://www.w3.org/TR/REC-html40">]+;
[<Font html:Face="Tahoma" x:Family="Swiss" html:Color="#000000">]+alltrim(loColumnHeader.ToolTipText)+[</Font>]+;
[</ss:Data>]+;
[</Comment>]
endif
*- linha do header
lcXmlRows = lcXmlRows + [ <Cell ss:StyleID="]+this.SeekStyle("000000",transform(lnCol,"@L 999"))+["><Data ss:Type="String">]+loColumnHeader.caption+[</Data>]+lcToolTipText+[</Cell>] + this.CRLF
endif
endfor
lcXmlRows = lcXmlRows + [ </Row>] + this.CRLF
endif
lcXmlRows = lcXmlRows + this.CRLF
*- Adiciono a linha do Registro no arquivo excel
select (this.Alias)
go top
scan
lnRow = lnRow + 1
lcXmlRows = lcXmlRows + [ <Row ss:AutoFitHeight="0">] + this.CRLF
*- percentual processado
lnPercent = int((lnRow / (this.RowCount - (iif(this.GridObject.HeaderHeight > 0, 1, 0))) ) * 100)
this.Progress(lnPercent)
*- faço a varredura em todas as colunas
for lnCol = 1 to this.GridObject.ColumnCount
loColumn = this.GetColumn(lnCol)
if not loColumn.Visible
loop
endif
*- Verifico o tipo de dado da coluna
lcDataColumn = evaluate(loColumn.ControlSource)
loCurrentControl = this.GetCurrentControlObject(loColumn)
*- se não tem objeto de controle na linha da coluna não levo a informação da tabela ao excel
if isnull(loCurrentControl)
lcDataType = "String"
lcDataColumn = ""
else
do case
case vartype(lcDataColumn) $ "N//Y"
lcDataType = "Number"
*- Se o currentcontrol da coluna for um combobox mostro o seu conteudo ao inves da posição numerica
if lower(loCurrentControl.BaseClass) = "combobox"
try
do case
*- Mostro o texto do value
case loCurrentControl.RowSourceType = 1
lcDataType = "String"
if not empty(loCurrentControl.RowSource)
lcAuxDataColumn = alltrim(loCurrentControl.RowSource)
lcAuxDataColumn = strtran(strtran(strtran(lcAuxDataColumn," ,",","), ", ",","), " , ", ",")
lcCountOption = occurs(",",lcAuxDataColumn)+1
dimension laArrayTmp[lcCountOption]
for lnCountRowSource = 1 to lcCountOption
lcComboOption = substr(lcAuxDataColumn, 1, iif(lnCountRowSource < lcCountOption, at(",",lcAuxDataColumn)-1, len(lcAuxDataColumn)) )
lcAuxDataColumn = strtran(lcAuxDataColumn, lcComboOption + iif(lcCountOption>=2,",",""), "")
laArrayTmp[lnCountRowSource] = lcComboOption
endfor
lcDataColumn = evaluate("laArrayTmp["+alltrim(str(lcDataColumn))+"]")
endif
*- Mostro o texto do array do combo
case loCurrentControl.RowSourceType = 5
lcDataType = "String"
*- Se for um array objeto ex: thisform.ArrayName ou MyObj.ArrayName
if occurs(".", loCurrentControl.RowSource) > 0
lcObjArrayName = substr(loCurrentControl.RowSource, 1, rat(".",loCurrentControl.RowSource)-1)
*- Se for um array objeto publico
if type(lcObjArrayName) = "O"
lcAuxDataColumn = loCurrentControl.RowSource+"["+alltrim(str(lcDataColumn))+"]"
else
lcArrayName = substr(loCurrentControl.RowSource, rat(".",loCurrentControl.RowSource)+1)
lnCountObjectHierarchy = occurs(".", sys(1272, this.GridObject))
lcAuxDataColumn = "this.GridObject"+replicate(".Parent",lnCountObjectHierarchy)+"."+lcArrayName+"["+alltrim(str(lcDataColumn))+"]"
endif
*- Array comum
else
lcAuxDataColumn = loCurrentControl.RowSource+"["+alltrim(str(lcDataColumn))+"]"
endif
lcDataColumn = evaluate(lcAuxDataColumn)
*- Qualquer outro mostro o conteudo do campo e não o conteudo do array
otherwise
lcDataColumn = lcDataColumn
endcase
catch to loError
endtry
if vartype(loError) = "O"
messagebox( "Combo array '"+loCurrentControl.RowSource+"' in column '"+loColumn.name+"' not is valid", 48)
select (this.Alias)
go top
return .f.
endif
else
lnRowFound = ascan(this.AFields, iif("."$loColumn.ControlSource, substr(loColumn.ControlSource, at(".",loColumn.ControlSource)+1), loColumn.ControlSource), -1,-1, 1, 15)
if lnRowFound > 0 and this.AFields[lnRowFound,4] > 0
llHasDecimals = .t.
set decimals to this.AFields[lnRowFound,4]
else
llHasDecimals = .f.
endif
endif
case vartype(lcDataColumn) = "D"
lcDataType = "DateTime"
if not empty(nvl(lcDataColumn,""))
lnYear = iif(year(lcDataColumn)<1900,1900,year(lcDataColumn))
lcAuxDataColumn = str(lnYear,4)+"-"+transform(month(lcDataColumn),"@L 99")+"-"+transform(day(lcDataColumn),"@L 99")+"T00:00:00.000"
lcDataColumn = lcAuxDataColumn
else
lcDataType = "String"
lcDataColumn = ""
endif
case vartype(lcDataColumn) = "T"
lcDataType = "DateTime"
if not empty(nvl(lcDataColumn,""))
lnYear = iif(year(lcDataColumn)<1900,1900,year(lcDataColumn))
lcAuxDataColumn = str(lnYear,4)+"-"+transform(month(lcDataColumn),"@L 99")+"-"+transform(day(lcDataColumn),"@L 99")+;
"T"+transform(hour(lcDataColumn),"@L 99")+":"+transform(minute(lcDataColumn),"@L 99")+":"+transform(sec(lcDataColumn),"@L 99")+".000"
lcDataColumn = lcAuxDataColumn
else
lcDataType = "String"
lcDataColumn = ""
endif
case vartype(lcDataColumn) = "L"
lcDataType = "Number"
lcDataColumn = iif(lcDataColumn, 1, 0)
otherwise
lcDataType = "String"
if isnull(lcDataColumn)
lcDataColumn = ""
endif
endcase
endif
*- removing invalid characters
if lcDataType = "String" and ("<" $ lcDataColumn or ">" $ lcDataColumn)
lcDataColumn = strtran(strtran(lcDataColumn, "<", "["), ">", "]")
endif
*- incluo a linha de dados
lcXmlRows = lcXmlRows + [ <Cell ss:StyleID="]+this.SeekStyle(transform(lnRow,"@L 999999"),transform(lnCol,"@L 999"))+["><Data ss:Type="]+lcDataType+[">]+alltrim(transform(lcDataColumn, ""))+[</Data></Cell>] + this.CRLF
*- devolvo o atributo original
if llHasDecimals
set decimals to lnSetDecimals
endif
endfor
lcXmlRows = lcXmlRows + [ </Row>] + this.CRLF
lnBytes = lnBytes + strtofile( lcXmlRows + this.CRLF, this.File, 1)
lcXmlRows = ""
endscan
return lnBytes
ENDPROC
PROTECTED PROCEDURE colortostrhexa && Converto a cor do vfp para hexadecimal
lparameters plnColor
local lnDecimalColor
lnDecimalColor = substr(transform(plnColor, '@0'),5)
return "#"+right(lnDecimalColor,2) + substr(lnDecimalColor,3,2) + left(lnDecimalColor,2)
ENDPROC
PROTECTED PROCEDURE getcolumn && Retorna o objeto da coluna conforme sua ordem de apresentação no grid
lparameters plcColumnNumber
local lnCol
for lnCol = 1 to this.GridObject.ColumnCount
if this.GridObject.Columns(lnCol).ColumnOrder = plcColumnNumber
return this.GridObject.Columns(lnCol)
endif
endfor
ENDPROC
PROTECTED PROCEDURE getcolumnalign && Retorna o alinhamento de um objeto para ser usado na linha/coluna (célula) do Excel
lparameters plcWhat, plnAlignment, plcVartype
local lcAlignment, lcAlignH, lcAlignV
plcVartype = evl(plcVartype,"")
lcAlignment = alltrim(str(plnAlignment))
*- Alinhamento Horizontal do texto da coluna/linha
if plcWhat = "H"
do case
case lcAlignment $ "0//4//7"
lcAlignH = "Left"
case lcAlignment $ "1//5//8"
lcAlignH = "Right"
case lcAlignment $ "2//6//9"
lcAlignH = "Center"
otherwise
lcAlignH = iif(plcVartype $ "N//Y", "Right", "Left")
endcase
lcAlignH = padr(lcAlignH, len(xxxStylesProperties.ssAlignH))
return lcAlignH
endif
*- Alinhamento vertical do texto da coluna/linha
if plcWhat = "V"
do case
case lcAlignment $ "4//5//6"
lcAlignV = "Top"
case lcAlignment $ "7//8//9"
lcAlignV = "Bottom"
case lcAlignment $ "0//1//2"
lcAlignV = "Center"
otherwise
lcAlignV = "Center"
endcase
lcAlignV = padr(lcAlignV, len(xxxStylesProperties.ssAlignV))
return lcAlignV
endif
ENDPROC
PROTECTED PROCEDURE getcolumnheader && Retorna o nome do header da coluna indicada
lparameters ploColumn
local loReturn, lnx
loReturn = ""
if ploColumn.ControlCount > 0
for lnx = 1 to ploColumn.ControlCount
if lower(ploColumn.Controls(lnx).BaseClass) = "header"
loReturn = ploColumn.Controls(lnx)
exit
endif
endfor
endif
return loReturn
ENDPROC
PROTECTED PROCEDURE getcurrentcontrolobject && Retorna o objeto corrente dentro da linha/coluna
lparameters ploGridColumn
local lcCurrentControl
if not empty(ploGridColumn.DynamicCurrentControl)
lcCurrentControl = evaluate(ploGridColumn.DynamicCurrentControl)
else
lcCurrentControl = ploGridColumn.CurrentControl
endif
if not empty(lcCurrentControl)
return evaluate("ploGridColumn."+lcCurrentControl)
else
return null
endif
ENDPROC
PROTECTED PROCEDURE hascolumnvisible && Retorna o numero de colunas visiveis no grid
local lnCol, llReturn
llReturn = .f.
for lnCol = 1 to this.GridObject.ColumnCount
if this.GridObject.Columns(lnCol).Visible
llReturn = .t.
exit
endif
endfor
return llReturn
ENDPROC
PROCEDURE Init
*/---------------------------------------------------------------------------------------------------/*
*/ Descripton..: - Classe para converter o grid do vfp em um arquivo xml para o Excel. /*
*/ - A grande vantagem na utilização é que NÃO NECESSITA DO EXCEL INSTALADO /*
*/ pois em nenhum momento o Excel é instanciado para automação. /*
*/ Apesar de ser um arquivo xml, se encontra no padrão Microsoft onde é reconhecido /*
*/ pelo Excel como "Planilha XML 2003 (*.xml)". Dessa forma fica restrito o uso /*
*/ para Excel 2003 ou superior. /*
*/ /*
*/ - Se o Excel estiver instalado o icone do arquivo gerado será reconhecido /*
*/ pelo Excel e abrindo o arquivo será reconhecido como se fosse um XLS ou XLSX, /*
*/ ou seja, tudo será transparente para o Excel. /*
*/ /*
*/ - Praticamente todos os recursos visuais do grid, headers, colunas e linhas /*
*/ são tratados na exportação. Segue abaixo as propriedades reconhecidas: /*
*/ /*
*/ Header Properties /*
*/ --------------------------------- /*
*/ ToolTipText / HeaderHeight / Alignment / FontBold / FontItalic / FontUnderline / /*
*/ FontStrikeThru / FontName / FontSize / ForeColor / BackColor / Caption / /*
*/ /*
*/ Columns Properties /*
*/ --------------------------------- /*
*/ ControlSource / BaseClass / InputMask / Seconds / RowHeight / Alignment / /*
*/ FontBold / FontItalic / FontUnderline / FontStrikeThru / FontName / FontSize / /*
*/ ForeColor / FontBackColor / CurrentControl / DynamicFontBold / DynamicFontItalic /*
*/ DynamicFontUnderline / DynamicFontStrikeThru / DynamicCurrentControl / /*
*/ DynamicFontName / DynamicFontSize / DynamicForeColor / DynamicBackColor / /*
*/ ColumnCount / ColumnOrder / Width / Visible / Combobox.Alignment / /*
*/ Combobox.RowSource / Combobox.RowSourceType /*
*/ /*
*/ Environment /*
*/ --------------------------------- /*
*/ set date / set century / set hours /*
*/ /*
*/
*/ Goals
*/ ------
*/ a) Possibilidade de gerar planilhas com mais de 65,535 linhas superando
*/ a limitaçao nativa do VFP
*/ b) Converte um grid em planilha Excel assumindo 99% do visual do grid
*/ c) Easy to implement and it is not necessary to change your code
*/ d) Compativel com Excel 2003 ou superior
*/ e) Pode ser aberto pelo OpenOffice reduzindo erros de conversão
*/ f) Ao abrir o arquivo pelo Excel é possivel salvar em outros formatos
*/ g) Nao precisa ter o Excel instalado
*/
*/ /*
*/ Author......: Rodrigo Bruscain /*
*/ Date........: 25/05/2013 /*
*/ Country.....: Brazil - São Paulo - SP /*
*/ Version.....: 1.08 /*
*/---------------------------------------------------------------------------------------------------/*
this.CRLF = chr(13) + chr(10)
local lcDateFormat, lcCentury
lcDateFormat = set("Date")
lcCentury = iif(set("century")="ON","yyyy","yy")
do case
case inlist(lcDateFormat, "AMERICAN", "MDY") && month/day/year
this.DateFormat = "mm/dd/"+lcCentury
case lcDateFormat = "ANSI" && year.month.day
this.DateFormat = lcCentury+".mm.dd"
case inlist(lcDateFormat, "BRITISH", "DMY", "FRENCH") && day/month/year
this.DateFormat = "dd/mm/"+lcCentury
case lcDateFormat = "GERMAN" && day.month.year
this.DateFormat = "dd.mm."+lcCentury
case lcDateFormat = "ITALIAN" && day-month-year
this.DateFormat = "dd-mm-"+lcCentury
case inlist(lcDateFormat, "JAPAN", "YMD") && year/month/day
this.DateFormat = lcCentury+"/mm/dd"
case lcDateFormat = "USA" && month-day-year
this.DateFormat = "mm-dd-"+lcCentury
otherwise
this.DateFormat = "dd/mm/"+lcCentury
endcase
*- version object
this.version = createobject("empty")
addproperty(this.version, "Number", "Beta 1.08")
addproperty(this.version, "DateTime", "Feb.21.2014 3:59:41 AM")
addproperty(this.version, "Author", "Rodrigo Duarte Bruscain")
addproperty(this.version, "CountryAndCity", "kitchener ON - Canada")
addproperty(this.version, "Url", "http://vfpx.codeplex.com/wikipage?title=ExcelXML")
addproperty(this.version, "Email", "bruscain@hotmail.com")
ENDPROC
PROCEDURE progress && Method used to show the percentage processed.
lparameters plnPercent
ENDPROC
PROCEDURE save && Creates the Excel XML file.
lparameters plcFile
local lcCreatedDate, lnCol, lcSetPoint, loForm, lcAlias, lnRecno, ;
lcXmlStart, lcXmlDocumentProperties, lcXmlExcelWorkbook, lcStringStyles, ;
lcXmlAllStyles, lcXmlFreezePanes, lcStringFilter, lcStringColumnWidth, ;
lcXmlWorksheet_part1, lcXmlWorksheet_part2, lnBytes, loError
plcFile = iif(empty(plcFile),"Book1",plcFile)
this.File = iif(empty(this.File),plcFile,this.File)
this.File = this.File + iif(empty(justext(this.File)),".XML","")
if empty(alias())
messagebox("No table is open in the current work area. ", 48)
return .f.
endif
*- crio um grid virtual caso a nao exista um grid para conversao,
*- ou seja, estou convertendo somente a tabela
if vartype(this.GridObject) <> "O"
loForm = createobject("form")
loForm.AddObject("grid1","grid")
loForm.Grid1.RecordSource = alias()
loForm.Grid1.visible = .t.
loForm.refresh()
this.GridObject = loForm.Grid1
this.SetStyles = .f.
endif
*- environment
if this.GridObject.RecordSourceType = 1
this.Alias = this.GridObject.RecordSource
else
this.Alias = alias()
endif
lnRecno = recno()
afields(this.afields,this.Alias)
*- Data da criação do arquivo excel
lcCreatedDate = str(year(date()),4)+"-"+transform(month(date()),"@L 99")+"-"+transform(day(date()),"@L 99")+"T"+time()+"Z"
*- Numero de colunas válidas para o excel
this.ColumnCount = 0
for lnCol = 1 to this.GridObject.ColumnCount
if this.GridObject.Columns(lnCol).Visible = .T.
this.ColumnCount = this.ColumnCount + 1
endif
endfor
*- Numero de linhas disponíveis para o excel
this.RowCount = 0
select (this.Alias)
count to this.RowCount
go top
if this.GridObject.HeaderHeight > 0
this.RowCount = this.RowCount + 1
endif
*- verifico se tudo esta ok para prosseguir
if isnull(this.GridObject) or this.GridObject.ColumnCount <= 0 and this.HasColumnVisible()
return .f.
endif
*- No Excel casas decimais obrigatóriamente trabalham com ponto "."
lcSetPoint = set("Point")
set point to "."
*- Inicio tratamento dos dados
text to lcXmlStart textmerge pretext 2 noshow
<?xml version="1.0" encoding="<<this.xmlEncoding>>"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
endtext
text to lcXmlDocumentProperties textmerge pretext 2 noshow
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
<Author><<iif(!empty(getenv("USERNAME")), getenv("USERNAME"), iif(!empty(getenv("COMPUTERNAME")), getenv("COMPUTERNAME"), "RODRIGO_BRUSCAIN"))>></Author>
<LastAuthor><<iif(!empty(getenv("USERNAME")), getenv("USERNAME"), iif(!empty(getenv("COMPUTERNAME")), getenv("COMPUTERNAME"), "RODRIGO_BRUSCAIN"))>></LastAuthor>
<Created><<lcCreatedDate>></Created>
<LastSaved><<lcCreatedDate>></LastSaved>
<Version>12.00</Version>
</DocumentProperties>
endtext
text to lcXmlExcelWorkbook textmerge pretext 2 noshow
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>8130</WindowHeight>
<WindowWidth>15135</WindowWidth>
<WindowTopX>120</WindowTopX>
<WindowTopY>45</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
endtext
*- Crio os estilos de cores/fontes/formato/etc das colunas
*- Depois junto com o estilo padrão todos os estilos encontrados
*- Estilos são todas as formatões da células combinadas onde um estilo pode ser usado
*- por várias céluas ou por uma única célula.
lcStringStyles = ""
lcStringStyles = this.BuildHeadersStyles() &&- Estilos do header
lcStringStyles = lcStringStyles + this.BuildColumnsStyles() &&- Estilos das linhas/colunas
text to lcXmlAllStyles textmerge pretext 2 noshow
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Center"/>
<Borders/>
<Font ss:FontName="Arial" x:Family="Swiss" ss:Size="9" ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<<lcStringStyles>>
</Styles>
endtext
*- Congelando paineis na horizontal e vertical
do case
*- Congelo a linha do header
case this.GridObject.LockColumns = 0 and (this.GridObject.HeaderHeight > 0 and this.LockHeader)
text to lcXmlFreezePanes textmerge pretext 2 noshow
<FreezePanes/>
<FrozenNoSplit/>
<SplitHorizontal>1</SplitHorizontal>
<TopRowBottomPane>1</TopRowBottomPane>
<ActivePane>2</ActivePane>
<Panes>
<Pane>
<Number>3</Number>
</Pane>
<Pane>
<Number>2</Number>
</Pane>
</Panes>
endtext
*- congelo a linha do header e a coluna definida
case this.GridObject.LockColumns > 0 and (this.GridObject.HeaderHeight > 0 and this.LockHeader)
text to lcXmlFreezePanes textmerge pretext 2 noshow
<FreezePanes/>
<FrozenNoSplit/>
<SplitHorizontal>1</SplitHorizontal>
<TopRowBottomPane>1</TopRowBottomPane>
<SplitVertical><<alltrim(str(this.GridObject.LockColumns))>></SplitVertical>
<LeftColumnRightPane><<alltrim(str(this.GridObject.LockColumns))>></LeftColumnRightPane>
<ActivePane>0</ActivePane>
<Panes>
<Pane>
<Number>3</Number>
</Pane>
<Pane>
<Number>1</Number>
</Pane>
<Pane>
<Number>2</Number>
</Pane>
<Pane>
<Number>0</Number>
</Pane>
</Panes>
endtext
*- congelo somente a coluna definida
case this.GridObject.LockColumns > 0 and (this.GridObject.HeaderHeight = 0 or not this.LockHeader)
text to lcXmlFreezePanes textmerge pretext 2 noshow
<FreezePanes/>
<FrozenNoSplit/>
<SplitVertical>2</SplitVertical>
<LeftColumnRightPane>2</LeftColumnRightPane>
<ActivePane>1</ActivePane>
<Panes>
<Pane>
<Number>3</Number>
</Pane>
<Pane>
<Number>1</Number>
</Pane>
</Panes>
endtext
otherwise
lcXmlFreezePanes = ""
endcase
*- filtros na colunas
lcStringFilter = ""
if this.HasFilter and this.GridObject.HeaderHeight > 0
text to lcStringFilter textmerge pretext 2 noshow
<AutoFilter x:Range="R1C1:R<<alltrim(str(this.RowCount))>>C<<alltrim(str(this.ColumnCount))>>"
xmlns="urn:schemas-microsoft-com:office:excel">
</AutoFilter>
endtext
endif
*- tratamento do nome da planilha
this.SheetName = chrtran(alltrim(substr(this.SheetName,1,31)), ':?][*/\','')
this.SheetName = iif(empty(this.SheetName),"Sheet1", this.SheetName)
*- Monto a tabela
lcStringColumnWidth = this.BuildColumnsWidth()
text to lcXmlWorksheet_part1 textmerge pretext 2 noshow
<Worksheet ss:Name="<<this.SheetName>>">
<Table ss:ExpandedColumnCount="<<this.ColumnCount>>" ss:ExpandedRowCount="<<this.RowCount>>" x:FullColumns="1"
x:FullRows="1" ss:DefaultRowHeight="<<alltrim(str(this.GridObject.RowHeight-3))>>">
<<lcStringColumnWidth>>
endtext
text to lcXmlWorksheet_part2 textmerge pretext 2 noshow
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.31496062000000002"/>
<Footer x:Margin="0.31496062000000002"/>
<PageMargins x:Bottom="0.78740157499999996" x:Left="0.511811024"
x:Right="0.511811024" x:Top="0.78740157499999996"/>
</PageSetup>
<Unsynced/>
<Print>
<ValidPrinterInfo/>
<PaperSizeIndex>9</PaperSizeIndex>
<HorizontalResolution>300</HorizontalResolution>
<VerticalResolution>300</VerticalResolution>
</Print>
<Selected/>
<<lcXmlFreezePanes>>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
<<lcStringFilter>>
</Worksheet>
</Workbook>
endtext
try
lnBytes = 0
lnBytes = lnBytes + strtofile("", this.File, 0)
lnBytes = lnBytes + strtofile( lcXmlStart + this.CRLF, this.File, 1)
lnBytes = lnBytes + strtofile( lcXmlDocumentProperties + this.CRLF, this.File, 1)
lnBytes = lnBytes + strtofile( lcXmlExcelWorkbook + this.CRLF, this.File, 1)
lnBytes = lnBytes + strtofile( lcXmlAllStyles + this.CRLF, this.File, 1)
lnBytes = lnBytes + strtofile( lcXmlWorksheet_part1 + this.CRLF, this.File, 1)
lnBytes = lnBytes + this.BuildRows()
lnBytes = lnBytes + strtofile( lcXmlWorksheet_part2 + this.CRLF, this.File, 1)
llReturn = iif(lnBytes > 0, .T., .F.)
catch to loError
if file(this.File)
erase (this.File)
endif
messagebox("An error occurred during the data exporting. "+chr(13)+"Error: "+loError.message,16,"Exporting")
llReturn = .F.
endtry
*select xxxStylesRowCol
*browse normal
*select xxxStylesProperties
*browse normal
set point to &lcSetPoint
if used("xxxStylesProperties")
use in xxxStylesProperties
endif
if used("xxxStylesRowCol")
use in xxxStylesRowCol
endif
if used(this.Alias)
TRY
go lnRecno
CATCH
ENDTRY
endif
if vartype(this.GridObject) <> "O"
loForm.Release()
endif
this.GridObject = .null.
if used(this.Alias)
select (this.Alias)
endif
*- abre o arquivo apos salva-lo
if llReturn and this.OpenAfterSaving
declare integer ShellExecute in SHELL32.dll as WinAPI_OpenAfterSavingExcelXML;
integer HndWin, string cAction, string cFileName,;
string cParams, string cDir, integer nShowWin
WinAPI_OpenAfterSavingExcelXML(0,"OPEN",this.file,"","",1)
clear dlls "WinAPI_OpenAfterSavingExcelXML"
endif
return llReturn
ENDPROC
PROTECTED PROCEDURE seekstyle && Busco o estilo que será usado na Coluna/Linha (célula)
lparameters plcRow, plcCol
local lcReturn
lcReturn = ""
*- se nao aplica estilos
if not this.SetStyles and plcRow > "000001"
plcRow = "000001"
endif
*- Procuro um estilo para a celula, caso nao encontre aplico o padrão.
*- Teoricamente todas as celulas deve ter um estilo e não o padrão.
if seek(plcRow + plcCol, "xxxStylesRowCol", "idxRowCol")
lcReturn = xxxStylesRowCol.ssCode
else
lcReturn = "Default"
endif
return lcReturn
ENDPROC
ENDDEFINE