XLRD, проверьте, если один лист не существует, проверьте другой - PullRequest
0 голосов
/ 04 марта 2020

Попытка прочитать серию файлов xls. Они не отформатированы одинаково. Иногда листы существуют, иногда нет. Иногда у них одно имя, иногда другое. Это несовершенный мир.

Какой-то код, который я пытался проверить для имени листа:

import xlrd

wb=xlrd.open_workbook(r'C:\sample.xls')

class Workbook_Reading:

    def __init__(self, wb):
        self.wb = wb
        self.history = None

    def purch_hist(self):
        if self.wb.sheet_loaded('Purchase History') is True:
            purchase_history = wb.sheet_by_name('Purchase History')
            self.history = purchase_history
        elif self.wb.sheet_loaded('Previous Purchases') is True:
            purchase_history = wb.sheet_by_name('Previous Purchases')
            self.history = purchase_history
        else:
            pass

Я получаю сообщение об ошибке: xlrd.bffh.XLRDError: No Sheet Named <'Purchase History'>. Я тестирую этот wb, который, как я знаю, не имеет первого условия (лист истории покупок), но имеет другое (предыдущий лист покупок). Что я сделал не так?

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Это может помочь

import xlrd

class Workbook_Reading:

    def __init__(self, wb):
        self.history = None
        self.desiredSheetNames = ['Purchase History', 'Previous Purchases']
        self.availableSheetNames = []
        self.wb = xlrd.open_workbook(r'C:\\sample.xls')
        self.set_available_sheets()

    def set_available_sheets(self):
        for sheetName in self.desiredSheetNames:
            try:
                sheet = self.wb.sheet_by_name(sheetName)
                self.availableSheetNames.append(sheetName)
            except:
                pass

    def purch_hist(self):
        if 'Purchase History' in self.availableSheetNames:
            purchase_history = wb.sheet_by_name('Purchase History')
            self.history = purchase_history
        elif 'Previous Purchases') in self.availableSheetNames:
            purchase_history = wb.sheet_by_name('Previous Purchases')
            self.history = purchase_history
        else:
            pass
0 голосов
/ 04 марта 2020

Как подсказал @Jabb в своем первоначальном комментарии, правильный путь к go - попробовать / исключить. Хотя его пример немного усложнен, например, нет необходимости создавать метод для установки доступных листов, вы можете просто использовать book.sheet_names() все же (чтобы проверить, существует ли лист с данным именем). Но, как я уже сказал, нет необходимости проверять использование блока if / elif / else, просто используйте try / исключением.

import xlrd

file_name = r'some_path\some_file.xls' # replace with your file

class Workbook_Reader:
    def __init__(self, wb, lookup_sheets=('Purchase History', 'Previous Purchases')):
        self.wb = xlrd.open_workbook(wb)
        self.lookup_sheets = lookup_sheets

    @property
    def purchase_history(self): # this property will return the respective sheet or None
        for sheet_name in self.lookup_sheets:
            try:
                return self.wb.sheet_by_name(sheet_name)
            except xlrd.biffh.XLRDError:
                pass

foo = Workbook_Reader(file_name)
for row in foo.purchase_history.get_rows():
    for cl in row:
        print(cl.value)

Обратите внимание, что итерирование по lookup_sheets, first seen wins

...