class_docstr: Class for formatting a DataFrame to a list of ExcelCells,
  
  Parameters
  ----------
  df : DataFrame or Styler
  na_rep: na representation
  float_format : string, default None
          Format string for floating point numbers
  cols : sequence, optional
      Columns to write
  header : boolean or list of string, default True
      Write out column names. If a list of string is given it is
      assumed to be aliases for the column names
  index : boolean, default True
      output row names (index)
  index_label : string or sequence, default None
          Column label for index column(s) if desired. If None is given, and
          `header` and `index` are True, then the index names are used. A
          sequence should be given if the DataFrame uses MultiIndex.
  merge_cells : boolean, default False
          Format MultiIndex and Hierarchical Rows as merged cells.
  inf_rep : string, default `'inf'`
      representation for np.inf values (which aren't representable in Excel)
      A `'-'` sign will be added in front of -inf.
  style_converter : callable, optional
      This translates Styler styles (CSS) into ExcelWriter styles.
      Defaults to ``CSSToExcelConverter()``.
      It should have signature css_declarations string -> excel style.
      This is only called for body cells.
code: def _format_hierarchical_rows(self):
      has_aliases = isinstance(
          self.header, (tuple, list, np.ndarray, Index)
      )
      if has_aliases or self.header:
          self.rowcounter += 1
  
      gcolidx = 0
  
      if self.index:
          index_labels = self.df.index.names
          # check for aliases
          if self.index_label and isinstance(
              self.index_label, (list, tuple, np.ndarray, Index)
          ):
              index_labels = self.index_label
  
          # MultiIndex columns require an extra row
          # with index names (blank if None) for
          # unambigous round-trip, unless not merging,
          # in which case the names all go on one row Issue #11328
          if (
              isinstance(self.columns, ABCMultiIndex)
              and self.merge_cells
          ):
              self.rowcounter += 1
  
          # if index labels are not empty go ahead and dump
          if (
              com._any_not_none(*index_labels)
              and self.header is not False
          ):
              for cidx, name in enumerate(index_labels):
                  yield ExcelCell(
                      self.rowcounter - 1, cidx, name, self.header_style
                  )
  
          if self.merge_cells:
              # Format hierarchical rows as merged cells.
              level_strs = self.df.index.format(
                  sparsify=True, adjoin=False, names=False
              )
              level_lengths = get_level_lengths(level_strs)
  
              for spans, levels, level_codes in zip(
                  level_lengths,
                  self.df.index.levels,
                  self.df.index.codes,
              ):
                  values = levels.take(
                      level_codes,
                      allow_fill=levels._can_hold_na,
                      fill_value=True,
                  )
  
                  for i in spans:
                      if spans[i] > 1:
                          yield ExcelCell(
                              self.rowcounter + i,
                              gcolidx,
                              values[i],
                              self.header_style,
                              self.rowcounter + i + spans[i] - 1,
                              gcolidx,
                          )
                      else:
                          yield ExcelCell(
                              self.rowcounter + i,
                              gcolidx,
                              values[i],
                              self.header_style,
                          )
                  gcolidx += 1
  
          else:
              # Format hierarchical rows with non-merged values.
              for indexcolvals in zip(*self.df.index):
                  for idx, indexcolval in enumerate(indexcolvals):
                      yield ExcelCell(
                          self.rowcounter + idx,
                          gcolidx,
                          indexcolval,
                          self.header_style,
                      )
                  gcolidx += 1
  
      for cell in self._generate_body(gcolidx):
          yield cell
  
imports: import itertools
  import re
  import warnings
  import numpy
  from pandas.compat import reduce
  from pandas.core.dtypes import missing
  from pandas.core.dtypes.common import is_float, is_scalar
  from pandas.core.dtypes.generic import ABCMultiIndex, ABCPeriodIndex
  from pandas import Index
  import pandas.core.common
  from pandas.io.formats.css import CSSResolver, CSSWarning
  from pandas.io.formats.format import get_level_lengths
  from pandas.io.formats.printing import pprint_thing
label_desc: Use image node_id 9 for calling the ExcelFormatter obj's underlying member method code with example usage: obj._format_hierarchical_rows() without return types