pythonopenpyxl

how to get the current row index with Openpyxl


I wrote a Python script to extract some string values from a .json file, store them in some dictionnary and fill them in an .xlsx file using Openpyxl, which I use for the 1st time:

in short, it looks like that :

WORKBOOK = Workbook()
WORKSHEET = WORKBOOK.active
. . .
. . .
for PERSON in TEAM_LIST:
    for ITEM in ITEMS[PERSON]:
       if PERSON in REGULAR_LIST:
          PERSON_ITEMS_ROW = (PERSON,ITEM[0],ITEM[1],ITEM[2],ITEM[3],ITEM[4)]
          SHEET.append(PERSON_ITEMS_ROW)    # Fill each row with some PERSON ITEMS
      else:
        PERSON_ITEMS_ROW = (PERSON,ITEM[0],ITEM[1],ITEM[2],ITEM[5],ITEM[6])
        SHEET.append(PERSON_ITEMS_ROW)      # Fill each row with other PERSON ITEMS

This code works well (although I am not 100% sure it is correct)

I would like to change backgroud and foreground color of rows selected in the "else" part above, and I don't manage to find a way to do it ;

I know how to apply specific color and font to a specific row : I do it for the 1st row used as the header row, but I don't know how to get the current row index so I could apply specific color and font on each row of "else" section

Any idea is welcome

thanks


Solution

  • You are looking for ws._current_row.
    Note: ws._current_row are only valid after inserting new cells.

    You can do it for instance:

        ...
        SHEET.append(PERSON_ITEMS_ROW)
        # For all cells in ws._current_row
        for row_cells in ws.iter_rows(min_row=ws._current_row,  max_row=ws._current_row):
            for cell in row_cells:
                cell.font = Font(color=colors.GREEN, italic=True)
    
        # Only for cell in column A == 1
        ws.cell(row=ws._current_row, column=1).font = Font(color=colors.RED)  
    

    If you don't want to use unsupported ws._current_row.

        # Assume you start in row==2
        for ws_current_row, PERSON in enumerate(TEAM_LIST, 2):
            #...
            #SHEET.append(PERSON_ITEMS_ROW)
    
            # For all cells in ws_current_row
            for row_cells in ws.iter_rows(min_row=ws_current_row, max_row=ws_current_row):
                for cell in row_cells:
                    cell.font = Font(color=colors.GREEN, italic=True)
    
            # Only for cell in column A == 1
            ws.cell(row=ws_current_row, column=1).font = Font(color=colors.RED)
    

    OOP solution, or openpyxl could implemented it.
    For instance:

        from openpyxl.workbook.workbook import Workbook as _Workbook
        from openpyxl.worksheet.worksheet import Worksheet as _Worksheet
    
        class Worksheet(_Worksheet):
            # Overload openpyxl.Worksheet.append
            def append(self, iterable):
                super().append(iterable)
                return self._current_row, \
                       self._cells_by_col(min_col=1, min_row=self._current_row,
                                          max_col=self.max_column, max_row=self._current_row)
    
        class Workbook(_Workbook):
            # Workaround, as openpyxl is not using self.create_sheet(...) in __init__
            def __init__(self, write_only=True):
                super().__init__(write_only)
                self.__write_only = False
                self.create_sheet()
    
            # Not working for self.read_only and self.write_only :
            # Overload openpyxl.Workbook.create_sheet
            def create_sheet(self, title=None, index=None):
                new_ws = Worksheet(parent=self, title=title)
                self._add_sheet(sheet=new_ws, index=index)
                return new_ws
    
        for PERSON in TEAM_LIST:
            # ...
            ws_current_row, iter_col = SHEET.append(PERSON_ITEMS_ROW)
    
            # Iterate all cells from generator iter_col
            for cell in [col_cells[0] for col_cells in iter_col]:
                cell.font = Font(color=colors.RED, italic=True)
    
            # Only for cell in column A == 1
            ws.cell(row=ws_current_row, column=1).font = Font(color=colors.BLUE)
    

    Tested with Python:3.4.2 - openpyxl:2.4.1 - LibreOffice: 4.3.3.2
    OpenPyXL Documentation