[reportlab-users] Spreadsheet Table

Tomasz Świderski contact at tomaszswiderski.com
Fri Feb 26 12:57:37 EST 2010




>

> I would prefer a complete separation of issues here. We already handle

> various alignment issues for string values. I suspect that whatever

> the abstract value of a special type like Formula represents it can

> also provide a __str__ method that results in its correct formatting.

> At present it is assumed that non-flowable cellvalues are strs (and

> indeed Formula.__call__ seems to assume that); It's difficult to see

> why cell style etc etc are being used in the call function. It's clear

> that these formulas require some extra information to evaluate

> themselves, but that information seems to come from the table

> instance. I know that activerows0 is not currently on the table, but

> it probably ought to be. I think it should be possible to push the

> logic for creating a string value from a formula into drawCell. There

> logically Formula should be treated as a str and the conversion should

> look like

>

> cellval = cellval(self, colNo, rowNo)

>

> self is the table on which everything required by the formula should

> be present.

>

I used __call__ with some many arguments because I did not want to
violate Table encapsulation. Note, that most of required informations to
evaluate Formula are Table's private properties. Cell style is used to
check if evaluated value will fit into cell. You can't evaluate Formula
inside drawCell because you don't have all needed information to call it
(colNo and rowNo missing). That's why I'm evaluating it in draw method
just before calling drawCell.


> Currently there is a bit of a conundrum present in the

> spreadsheettable code in that it appears as though width and height

> are obtained prior to drawing the formula cells. In my view this

> cannot in general be true unless these are fixed externally. That

> means effectively automatic widths are probably not going to happen in

> this model.

In current implementation Formula cell dimensions are calculated on
longest_possible_value. This longest possible value is provided by user.
Only user can make educated guess about it. For example when I generate
my tax records, I know that sum of my income will never exceed
999999.99 (I wish it would :P ) so I can provide this value as longest
possible value. Automatic width calculation without user hints is
impossible because width calculation would depend on Formula's value and
Formula's value would depend on split points (which depends on col
widths :P).

>

> I don't think it's sufficient to put out an overflow indicator; in a

> spreadsheet that's acceptable, because I can adjust the column width

> manually. If my gas bill total ends up as ***** it's useless. The

> formatted cell value should not care how wide the cell is unless it's

> able to do something useful with it. Currently we just draw the

> generic strings whatever and let them overflow. Other actions are

> possible ie truncate, raise an error, shrink to fit etc etc.

>

Formula overflow indicator '###' is just one of possible outcomes.
Current Formula class also supports raising Exceptions on overflow -
other actions can be added if needed.

>

> both of these could be added as formatting methods to a particular

> formula type.

>

> Using the FORMAT approach is useful, but it should apply to all cells.

> That would mean that data could be ints/floats/strings or other types

> and the Formula __call__ would need to return the right thing for its

> conversion. If that's the case then there is little distinction

> between simple and non-simple cell values; the formatting would need

> to be done early so that we could establish widths etc etc etc.

>


I agree that FORMAT should apply to all cells and be independent of
Formulas. Frankly, current Table already have one formatter in place -
normalizeData which replaces Nones with empty strings and encodes
unicode strings. So far Table do very great job to separate data from
data representation (styles). FORMAT would be next step in this
direction. For example:

I have all floats in my data. I want to represent it with 2 decimal
places precision. So I have to do this:
for row_num, row in enumerate(data):
for col_num, value in enumerate(row):
data[row_num][col_num] = '%.2f' % value
table = Table(data)

Now if I want to change display decimal precision I have to CHANGE data
and create new Table.

Better solution with FORMAT command:

table = Table(data)
table_style = [
('FORMAT', (0,0), (-1,-1), DecimalPrecision(2)),
]
table.setStyle(table_style)

Now when I want to change decimal precision I need only to override
Table style.

table_style = [
('FORMAT', (0,0), (-1,-1), DecimalPrecision(4)),
]
table.setStyle(table_style)


FORMAT command would allow greater control over data representation - I
believe things like decimal precision of displayed data counts as
representation.

Tomasz Świderski


More information about the reportlab-users mailing list