Hi
What would be the easiest approach to set up alternate row colors?
Hi,
Hi
This is for .NET. I am using XlsFile like this:
Private oXlsFile As FlexCel.XlsAdapter.XlsFile = Nothing
oXlsFile = New FlexCel.XlsAdapter.XlsFile(True)
' Number of sheets
oXlsFile.NewFile(nTotalSheet)
' Set the column width
oXlsFile.SetRowHeight(1, loRow("HeaderHeight") * 20)
' Initialization
oXlsFile.ActiveSheet = nActiveSheet
' If we have a sheet name
If lcSheetName.Length > 0 Then
oXlsFile.SheetName = lcSheetName
End If
' For each column
For Each loObject In oColumn
' Initialization
lcName = loObject(1)
loTFlxFormatHeader = loObject(2)
loTFlxFormatData = loObject(4)
lnWidth = loObject(3)
' Initialization
lnCounter = lnCounter + 1
' Set the column header
oXlsFile.SetCellFromString(1, lnCounter, lcName, oXlsFile.AddFormat(loTFlxFormatHeader))
' Set the column width
oXlsFile.SetColWidth(lnCounter, lnWidth)
' Set the column data format range
oXlsFile.SetCellFormat(2, lnCounter, nCount + 1, lnCounter, oXlsFile.AddFormat(loTFlxFormatData))
Next
...
oXlsFile.Save(lcFile)
I did not include all the code but this should give you an idea.
Hi
Thanks for the information
I did try this:
' It is not possible to create an object directly as this is Friend, so we have to get it from Excel
loTFlxFormat = oXlsFile.GetCellVisibleFormatDef(lnCounter + 2, 1)
loTFlxFormat.FillPattern.BgColor = FlexCel.Core.Colors.Blue
' For each record
For lnCounter = 0 To oData.nCount - 1
loRow = oData.oRows(lnCounter)
' Reset the values
lnColumn = 0
' If this is even
If lnCounter Mod 2 = 0 Then
' Initialize the row background color
oXlsFile.SetRowFormat(lnCounter + 2, oXlsFile.AddFormat(loTFlxFormat), False)
End If
I see that it goes in the If lnCounter Mod 2 = 0 at every two records. But, the row is not blue. There must be something wrong in loTFlxFormat in the way I initialize it.
As far the mention about not passing oXlsFile.AddFormat at every cell initialization, what you saw there was only for the header row. And, as each header column could have a different format, this is why I have to do it like this. On the data sections, for all the rows, the "Set the column data format range" line is where I set the format for an entire column. So, if I have 2000 rows in one sheet, this is only one call. I do not know how much simpler I can make it.
Hi,
Hi
I changed as requested but I cannot see any background color:
' It is not possible to create an object directly as this is Friend, so we have to get it from Excel
loTFlxFormat = oXlsFile.GetCellVisibleFormatDef(lnCounter + 2, 1)
loTFlxFormat.FillPattern.FgColor = FlexCel.Core.Colors.Blue
' Save it in memory so to avoid calling AddFormat() every time
lnXF = oXlsFile.AddFormat(loTFlxFormat)
' For each record
For lnCounter = 0 To oData.nCount - 1
loRow = oData.oRows(lnCounter)
' Reset the values
lnColumn = 0
' If this is even
If lnCounter Mod 2 = 0 Then
' Initialize the row background color
oXlsFile.SetRowFormat(lnCounter + 2, lnXF, False)
End If
Are you setting the fill pattern to solid instead of none?
Hi
I am not sure if this is needed but I did change as requested and it still does not show the background:
' It is not possible to create an object directly as this is Friend, so we have to get it from Excel
loTFlxFormat = oXlsFile.GetCellVisibleFormatDef(2, 1)
loTFlxFormat.FillPattern.FgColor = FlexCel.Core.Colors.Blue
loTFlxFormat.FillPattern.Pattern = FlexCel.Core.TFlxPatternStyle.Solid
' Save it in memory so to avoid calling AddFormat() every time
lnXF = oXlsFile.AddFormat(loTFlxFormat)
' For each record
For lnCounter = 0 To oData.nCount - 1
loRow = oData.oRows(lnCounter)
' Reset the values
lnColumn = 0
' If this is even
If lnCounter Mod 2 = 0 Then
' Initialize the row background color
oXlsFile.SetRowFormat(lnCounter + 2, lnXF, False)
End If
Yes, setting the fill style to solid is necessary.
Hi
Thanks, here is the reason why it is not working:
' For each column
For Each loObject In oColumn
' Initialization
lcName = loObject(1)
loTFlxFormatHeader = loObject(2)
loTFlxFormatData = loObject(4)
lnWidth = loObject(3)
' Initialization
lnCounter = lnCounter + 1
' Set the column header
oXlsFile.SetCellValue(1, lnCounter, lcName, oXlsFile.AddFormat(loTFlxFormatHeader))
' Set the column width
oXlsFile.SetColWidth(lnCounter, lnWidth)
' Set the column data format range
'oXlsFile.SetCellFormat(2, lnCounter, oData.nCount + 1, lnCounter, oXlsFile.AddFormat(loTFlxFormatData))
Next
' It is not possible to create an object directly as this is Friend, so we have to get it from Excel
loTFlxFormat = oXlsFile.GetCellVisibleFormatDef(2, 1)
loTFlxFormat.FillPattern.Pattern = FlexCel.Core.TFlxPatternStyle.Solid
loTFlxFormat.FillPattern.FgColor = FlexCel.Core.Colors.LightBlue
' Save it in memory so to avoid calling AddFormat() every time
lnXF = oXlsFile.AddFormat(loTFlxFormat)
' For each record
For lnCounter = 0 To oData.nCount - 1
loRow = oData.oRows(lnCounter)
' Reset the values
lnColumn = 0
' If this is even
If lnCounter Mod 2 = 0 Then
' Initialize the row background color
oXlsFile.SetRowFormat(lnCounter + 2, lnXF, False)
End If
Above, for each column, I define the format range. Once I commented the line, it worked. But, I need to format the column range. How can it be possible to have both?
Hi,
Hi
Thanks for the information
With that approach, it means I have to initialize all cells of a row, even if it is empty, in order to get the background. Presently, my code skip empty values, thus not initializing a cell if it has no value, which saves a lot of time.
I will have to consider the 1, 2, 3 approach instead.
Hi
BTW, I am not sure this priority works. Can you confirm that to me again?
I just tried by moving SetRowFormat() after I have initialized the entire spreadsheet. And, only where the cells have not been initialized that the background color works. It means that where ever I have initialized a cell, the SetCellValue() format remains as is, even if I have SetRowFormat() at the very end of my code.
Skipping empty values is not saving a lot of time, because in the call:
Priority is Cell, row, column. If you set a row format, it will apply only to the empty cells in the row.
Ok, I thought by priority you meant that we could see in that order and the later would work. But, basically, by priority, I think you meant that once a cell is set, even if we set the format at the row level, this will be ignored as we already set something higher in the chain of priority.
I will refactor this and will let you know.
Indeed, this is the priority Excle uses in the xls/x files. You have to consider we are speaking at a very low level here: the way xls and xlsx work.
Ok, this works.
What I do, instead of adding a format for every cell, as I know ahead of processing all records what format applies to which column, I have applied a one time XF conversion in my collection. Then, when I scan the records, I simply assign XF to the data cell.
However, to support alternate row color, in my collection, I have added another format for the cell, thus one format with no color and one format for the alternate row color. Then, as you can see in the code, if I am on an even row number, I will use the format for that one instead.
Here is a short overview on the main code:
' For each record
For lnCounter = 0 To oData.nCount - 1
loRow = oData.oRows(lnCounter)
' Reset the values
lnColumn = 0
' For each column
For Each loObject In oColumn
' Initialization
lnXF = loObject(12)
' If we use alternate row color
If lAlternateRowColor Then
lnXFAlternate = loObject(13)
' If this is even
If lnCounter Mod 2 = 0 Then
lnXF = lnXFAlternate
End If
End If
' Initialization
lnColumn = lnColumn + 1
' Initialize lcValue here, if applicable
...
' If we are initializating directly from the data
If lcValue.Length = 0 Then
' Initialize the value in the cell
oXlsFile.SetCellValue(lnCounter + 2, lnColumn, loRow(lnColumn - 1), lnXF)
Else
' Initialize the value in the cell
oXlsFile.SetCellValue(lnCounter + 2, lnColumn, lcValue, lnXF)
End If
Next
Next
For every 10 minutes of processing, as I am now initializing all the cells, thus also considering the empty cells, it takes about 30 seconds more. Even if you say that it should be faster, based on my initial results of last week, I was able to confirm that skipping cell initialization was ending up to be faster as I do not have to send them to Flexcel.
So, I can process my reports in 9 minutes and 50 seconds instead of 9 minutes and 11 seconds.
...approx.
Skipping cell initialization should be faster, I am not saying the opposite. What I am saying is that you aren't skipping cell initialization, you are actually initializing twice.