code: def cell_value(sheet, row, col):
      
      cell = sheet.cell(row, col)
      field_type = CELL_TYPES[cell.ctype]
  
      # TODO: this approach will not work if using locale
      value = cell.value
  
      if field_type is None:
          return None
  
      elif field_type is fields.TextField:
          if cell.ctype != xlrd.XL_CELL_BLANK:
              return value
          else:
              return ""
  
      elif field_type is fields.DatetimeField:
          if value == 0.0:
              return None
  
          try:
              time_tuple = xlrd.xldate_as_tuple(value, sheet.book.datemode)
          except xlrd.xldate.XLDateTooLarge:
              return None
          value = field_type.serialize(datetime.datetime(*time_tuple))
          return value.split("T00:00:00")[0]
  
      elif field_type is fields.BoolField:
          if value == 0:
              return False
          elif value == 1:
              return True
  
      elif cell.xf_index is None:
          return value  # TODO: test
  
      else:
          book = sheet.book
          xf = book.xf_list[cell.xf_index]
          fmt = book.format_map[xf.format_key]
  
          if fmt.format_str.endswith("%"):
              # TODO: we may optimize this approach: we're converting to string
              # and the library is detecting the type when we could just say to
              # the library this value is PercentField
  
              if value is not None:
                  try:
                      decimal_places = len(fmt.format_str[:-1].split(".")[-1])
                  except IndexError:
                      decimal_places = 2
                  return "{}%".format(str(round(value * 100, decimal_places)))
              else:
                  return None
  
          elif type(value) == float and int(value) == value:
              return int(value)
  
          else:
              return value
docs: Return the cell value of the table passed by argument, based in row and column.