How do I apply a style to the whole row using XLWT

2019-08-01 11:06发布

问题:

I'm trying to apply a style that will highlight the whole row if one of the columns contains the value "Assets". The code below will highlight only the column with "Assets" in it, instead of the entire row. Is there a way to apply the style to the whole row?

for row in csv_input:
     #Iterate through each column
      for col in range(len(row)):
           #Apply different styles depending on row
           if row_count == 0:
               sheet.write(row_count,col,row[col],headerStyle)
           elif row_count == 3:
               sheet.write(row_count,col,row[col],subheadStyle)
           elif "Assets" in row[col]:
               sheet.write(row_count,col,row[col],highlightStyle)             
           else:
               if (is_number(row[col]) == True):
                   sheet.write(row_count,col,float(row[col]),rowStyle)
               else:
                   sheet.write(row_count,col,row[col],rowStyle)

As you can see, depending on the row I am applying different styles. How can I make it so that any row that contains the keyword "Assets" will be highlighted? Thanks!

回答1:

Your main problem is that your code is checking for "Assets" after it has written some cells in the row. You need to do your "what style to use for the whole row" tests before you write any cells in the row. Setting a style on the xlwt Row object doesn't work; that's a default style for use with cells that don't have any formatting applied otherwise.

Other problems:

contains the value "Assets". The code below will highlight only the column with "Assets" in it

This is ambiguous. Suppose a cell value is exactly equal to "Equity Assets"; what do you want to do? Note: your code will highlight such a cell and those to its right. Also it's not apparent whether the "Assets"-bearing cell should be the first (example in your comment on another answer) or any cell (as per your code).

Some of your choices for variable names make your code very hard to read e.g. row is a list of cell values but col is a column index. Use enumerate() where possible.

Try something like this:

for row_index, cell_values in enumerate(csv_input):
    # Determine what style to use for the whole row
    if row_index == 0:
        common_style = headerStyle
    elif row_index == 3:
        common_style = subheadStyle
    elif "Assets" in cell_values:
        # perhaps elif any("Assets" in cell_value for cell_value in cell_values):
        # perhaps elif cell_values and cell_values[0] == "Assets":
        # perhaps elif cell_values and "Assets" in cell_values[0]:
        common_style = highlightStyle
    else:
        common_style = rowStyle
    # Iterate over the columns
    for col_index, cell_value in enumerate(cell_values):
        if common_style == rowStyle and is_number(cell_value):
            cell_value = float(cell_value)
        sheet.write(row_index, col_index, cell_value, common_style)

I'm curious about the is_number function ... I'd use this:

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

which automatically leads to:

        if common_style == rowStyle:
            try:
                cell_value = float(cell_value)
            except ValueError:
                pass

and also raises the question of whether you should perhaps have different styles for numbers and text.