code: def excel2json(filename, non_empty_col=-1, file_contents=None):
      
  
      if file_contents:
          workbook = xlrd.open_workbook(file_contents=file_contents)
      else:
          workbook = xlrd.open_workbook(filename)
  
      start_row = 0
      ret = collections.defaultdict(list)
      fields = {}
      for name in workbook.sheet_names():
          sh = workbook.sheet_by_name(name)
          headers = []
          for col in range(len(sh.row(start_row))):
              headers.append(sh.cell(start_row, col).value)
  
          logging.info(u"sheet={} rows={} cols={}".format(
              name, sh.nrows, len(headers)))
          logging.info(json.dumps(headers, ensure_ascii=False))
  
          fields[name] = headers
  
          for row in range(start_row + 1, sh.nrows):
              item = {}
              rowdata = sh.row(row)
              if len(rowdata) < len(headers):
                  msg = "skip mismatched row {}".format(
                      json.dumps(rowdata, ensure_ascii=False))
                  logging.warning(msg)
                  continue
  
              for col in range(len(headers)):
                  value = sh.cell(row, col).value
                  if type(value) in [unicode, basestring]:
                      value = value.strip()
                  item[headers[col]] = value
  
              if non_empty_col >= 0 and not item[headers[non_empty_col]]:
                  logging.debug("skip empty cell")
                  continue
  
              ret[name].append(item)
          # stat
          logging.info(u"loaded {} {} (non_empty_col={})".format(
              filename, len(ret[name]), non_empty_col))
      return {'data': ret, 'fields': fields}
docs: http://www.lexicon.net/sjmachin/xlrd.html
          non_empty_col is -1 to load all rows, when set to a none-empty value,
          this function will skip rows having empty cell on that col.