Проверьте рабочую книгу на лист и добавьте, если отсутствует - PullRequest
2 голосов
/ 30 апреля 2019

Я пытаюсь просто проверить, существует ли лист в файле .xlsx, и если нет, я хочу добавить его.

book = load_workbook('test.xlsx')
writer = pd.ExcelWriter('test.xlsx', engine = 'openpyxl')
writer.book = book

if 'testSheet' in book.sheetnames:
    pass
else:
    book.add_sheet(book['testSheet'])

Есть идеи, почему это не работает?

Ответы [ 5 ]

8 голосов
/ 05 мая 2019

Если вы работаете только с файлами Excel с расширением *.xlsx, то openpyxl имеет полезные функции, которые позволяют создавать, получать доступ, переименовывать, добавлять / удалять данные в / из рабочих таблиц Excel.Хотя доступ к рабочему листу рабочей книги с помощью openpyxl может показаться довольно простым, использование обработки исключений в Python может помочь отловить ошибки, когда рабочий лист не существует в первую очередь.Рассмотрим приведенный ниже пример, где KeyError вызывается, если для рабочей книги «test.xlsx» не существует листа с именем invalidSheet.Задача блока try / Кроме того, чтобы вызвать исключение, если лист не существует.Цель этого простого примера - определить только тип исключения, которое вызывает openpyxl.

In [1]: import openpyxl

In [2]: book = openpyxl.load_workbook("test.xlsx")

In [3]: try:
   ...:     ws = book["invalidSheet"]  #try to access a non-existent worksheet
   ...: except:
   ...:     raise
   ...:
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-3-4f4ac71a4f19> in <module>
      1 try:
----> 2     ws = book["invalidSheet"]
      3 except:
      4     raise
      5

~\Anaconda3\lib\site-packages\openpyxl\workbook\workbook.py in __getitem__(self, key)
    275             if sheet.title == key:
    276                 return sheet
--> 277         raise KeyError("Worksheet {0} does not exist.".format(key))
    278
    279     def __delitem__(self, key):

KeyError: 'Worksheet invalidSheet does not exist.'

Это помогает нам сформировать более явный блок try / Кроме того, чтобы ловить несуществующие листы.Вскоре мы улучшим этот пример, но сначала давайте выясним имена листов в этой электронной таблице Excel.Мы используем атрибут sheetnames объекта Workbook book, который мы создали ранее:

In [15]: book.sheetnames
Out[15]: ['testSheet1', 'testSheet2']

In [16]: type(book.sheetnames)
Out[16]: list

Возвращает список имен листов.Мы будем использовать эту информацию для проверки имен листов позже.Возвращаясь к приведенному выше примеру, следующая улучшенная версия перехватывает KeyError для несуществующих листов и создает новый лист, если он не существует.Однако листы не появятся в реальной электронной таблице Excel, если мы не save() ее.Имена листов с другой стороны все еще будут обновляться для объекта.Вы можете проверить это после выполнения фрагмента:

In [20]: try:
    ...:     filename = "test.xlsx"
    ...:     sheet_name = "invalidSheet"
    ...:     ws = book[sheet_name]
    ...: except KeyError:
    ...:     print("The worksheet '{}' does not exist for workbook '{}'. Creating one...".format(
    ...:                                                                                         sheet_name,
    ...:                                                                                         filename))
    ...:     book.create_sheet(sheet_name)
    ...:     print("Worksheet '{}' created successfully for workbook '{}'.".format(sheet_name, filename))
    ...:
The worksheet 'invalidSheet' does not exist for workbook 'test.xlsx'. Creating one...
Worksheet 'invalidSheet' created successfully for workbook 'test.xlsx'.

In [21]: book.sheetnames
Out[21]: ['testSheet1', 'testSheet2', 'invalidSheet']

Итак, теперь, когда у нас добавлен лист «invalidSheet», давайте добавим некоторые данные и сохраним их под более осмысленным именем.Openpyxl также обеспечивает поддержку Pandas dataframe .Сначала мы создадим фрейм данных, а затем добавим каждую строку в фрейме данных (включая заголовок) на лист, используя метод dataframe_to_rows(), затем переименуем лист и, наконец, сохраним его.

In [23]: import pandas as pd

In [24]: df = pd.DataFrame({"Name": ["John", "Val", "Katie"], 
                           "Favorite Pet":["dog", "cat", "guinea pig"]})   #create dataframe

In [25]: df
Out[25]:
    Name Favorite Pet
0   John          dog
1    Val          cat
2  Katie   guinea pig

In [26]: from openpyxl.utils.dataframe import dataframe_to_rows #import method

In [27]: ws = book["invalidSheet"] #create a worksheet object for the existing sheet "invalidSheet"

In [29]: for r in dataframe_to_rows(df, index=False, header=True):
    ...:     ws.append(r)    #append each df row to the worksheet
    ...:                                    
In [31]: ws['A2'].value    #verify value at cell 'A2'. Remember, the first row will be the header
Out[31]: 'John'

In [32]: ws.title = "favPetSheet" #rename the worksheet

In [33]: book.sheetnames  #verify whether the sheet was added & renamed
Out[33]: ['testSheet1', 'testSheet2', 'favPetSheet']

In [35]: book.save("test.xlsx")  #save the workbook

В идеалеВ этом случае одна функция должна выполнять все эти задачи для определенной рабочей книги и рабочего листа рабочей книги и кадра данных.

In [45]: def check_sheet_add_data(filename, sheetname, df):
    ...:     """Check if sheet exists for an xlsx spreadsheet and add data from dataframe to the sheet
    ...:        :param: filename - The filename of the xlsx spreadsheet
    ...:        :param: sheetname - Name of the worksheet to search for
    ...:        :param: df - A Pandas dataframe object"""
    ...:
    ...:     wb = openpyxl.load_workbook(filename)
    ...:     try:
    ...:         ws = wb[sheetname]
    ...:         print("Sheet '{}' found in workbook '{}'".format(sheetname, filename))
    ...:     except KeyError:
    ...:         print("Worksheet '{}' not found for workbook '{}'.Adding...".format(sheetname, filename))
    ...:         wb.create_sheet(sheetname)
    ...:         ws = wb[sheetname]
    ...:         print()
    ...:         print("Current sheetnames: {}".format(wb.sheetnames))
    ...:         print()
    ...:         print("Worksheet '{}' added successfully for workbook '{}'".format(sheetname, filename))
    ...:     finally:
    ...:         print()
    ...:         print("Adding data to worksheet '{}'...".format(sheetname))
    ...:         print()
    ...:         for r in dataframe_to_rows(df, index=False, header=True):
    ...:             ws.append(r)
    ...:         wb.save(filename)
    ...:         print("Workbook '{}' saved successfully.".format(filename))
    ...:         print()
    ...:         print("***End***")

Когда эта функция готова, давайте протестируем все условия.Сначала давайте добавим некоторые новые данные, скажем, «Любимые альбомы» для наших старых друзей Джона, Вэл и Кэти.

In [39]: df2 = pd.DataFrame({"Name":["John", "Val", "Katie"], 
                         "Favorite Album": ["Thriller", "Stairway to Heaven", "Abbey Road"]})

In [40]: df2
Out[40]:
    Name      Favorite Album
0   John            Thriller
1    Val  Stairway to Heaven
2  Katie          Abbey Road

Наша рабочая книга будет называться «test.xlsx», а наша новая рабочая таблица будет называться «favAlbumSheet».Тестирование на всех условиях для существующих и несуществующих рабочих листов:

#Condition 1: Worksheet does not exist
In [44]: check_sheet_add_data(filename="test.xlsx", sheetname="favAlbumSheet", df=df2)
Worksheet 'favAlbumSheet' not found for workbook 'test.xlsx'.Adding...

Current sheetnames: ['testSheet1', 'testSheet2', 'favPetSheet', 'favAlbumSheet']

Worksheet 'favAlbumSheet' added successfully for workbook 'test.xlsx'

Adding data to worksheet 'favAlbumSheet'...

Workbook 'test.xlsx' saved successfully.

***End***

#Condition 2: Worksheet exists
In [46]: check_sheet_add_data(filename="test.xlsx", sheetname="favAlbumSheet", df=df2)
Sheet 'favAlbumSheet' found in workbook 'test.xlsx'

Adding data to worksheet 'favAlbumSheet'...

Workbook 'test.xlsx' saved successfully.

***End***

Мы использовали простые в использовании функции Openpyxl для доступа к рабочим листам в действующей рабочей книге Excel и добавления данных из информационных фреймов в рабочие листы.Благодаря обработке исключений в Python мы смогли четко определить наличие рабочего листа (для действительной рабочей книги) и добавить его при необходимости.Эта функция может быть расширена для обнаружения других ошибок, таких как недопустимое имя файла (FileNotFoundError), недопустимый объект фрейма данных и т. Д. Если вы не хотите добавлять данные каждый раз и проверять только наличие листа, сделайте df anнеобязательный аргумент: df=None и сохраняйте книгу только без добавления каких-либо данных на лист в блоке finally.

5 голосов
/ 02 мая 2019

Добавление рабочего листа может быть выполнено только с помощью команд openpyxl (т. Е. Не нужно также включать команды pandas):

import openpyxl

# Load existing excel file into a openpyxl Workbook object
book = openpyxl.load_workbook('test.xlsx')

# If sheet 'testSheet' does not exist yet, then add it in the openpyxl Workbook object
if not 'testSheet' in book.sheetnames:
    book.create_sheet('testSheet')

# Save the openpyxl Workbook object to file
book.save('test.xlsx')
2 голосов
/ 07 мая 2019

Для двигателя openpyxl используйте book.create_sheet("testSheet")

Источник: https://openpyxl.readthedocs.io/en/stable/tutorial.html

0 голосов
/ 09 мая 2019

Я использовал функцию, которая, очевидно, выполняет ту работу, которая вам также необходима.Я использую xlwings , я не знаю openpyxl.Он может иметь дело с 3 критическими случаями:

  • Нет открытых книг
  • Желаемый лист не найден (создайте новый без поднятия исключения)
  • Попытка найти листошибка (используется для поиска листа и невидима для пользователя)

Функция возвращает (в случае успеха) объект xlwings.Sheet (который является эквивалентом xlwings объекта Excel Sheet).Помните, что вы можете вернуться к собственному объекту COM «Sheet», используя свойство xlwings.sheet.api

import xlwings as xw

def load_xlsh(SheetName):
    foundBK = False
    iBK = 0
    try:
        while (not foundBK) and iBK < len(xw.books):
            srcBK = xw.books[iBK]
            try:
                srcSH = srcBK.sheets[SheetName]
                foundBK = True
            except:
                iBK += 1
        if foundBK == False:
            srcBK.sheets.add(SheetName)
        else:
            return srcSH
    except AttributeError:
        print('No Workbooks open')
0 голосов
/ 08 мая 2019
  1. установить openpyxl
  2. импортировать openpyxl как pxl
  3. my_excel_wb = pxl.load_workbook ("excel.xlsx")
  4. , если не «имя листа» в my_excel_wb.Имена листов: my_excel_wb.create_sheet ('имя листа')
  5. в конце сохраните книгу.
...