как сохранить данные qtablewidget в файл excel с помощью openpyxl

У меня есть qtablewidet с данными, и когда пользователь нажимает кнопку экспорта, появляется диалоговое окно с запросом имени файла для сохранения в формате excel, как мне это сделать с помощью openpyxl?

вот мой код

self.exportbtn.clicked.connect(self.export)

    def export(self):
        try:
            filename = QtWidgets.QFileDialog.getSaveFileName(self, 'Save file', '','Excel files(*.xlsx)')
            wb = Workbook()
            sheet = wb.active
            for column in range(self.tableWidget.columnCount()):
                for row in range(self.tableWidget.rowCount()):
                    try:
                        text = str(self.tableWidget.item(row, column).text())
                        sheet.write(row, column, text)
                        wb.save(filename)
                    except Exception as e:
                        print("Error Writing file.")
        except Exception as e:
            print("Error Saving file.")

когда я пытаюсь нажать «Сохранить» в диалоговом окне, прямо сейчас выводится это

введите здесь описание изображения

как сохранить все данные, включая заголовки из qtablewidget, в файл excel с помощью openpyxl?

обновление: я отредактировал свой код сейчас, и я могу создать файл, но данные из qtablewidget все еще не записываются в файл excel

def export(self):
        filename, filter = QtWidgets.QFileDialog.getSaveFileName(self, 'Save file', '','Excel files (*.xlsx)')
        wb = Workbook()
        sheet = wb.active
        if not filename:
            for column in range(self.tableWidget.columnCount()):
                for row in range(self.tableWidget.rowCount()):
                    try:
                        text = str(self.tableWidget.item(row, column).text())
                        sheet.write(row, column, text)                    
                    except AttributeError:
                        pass
        wb.save(filename)

я попытался распечатать данные из qtablewidget, и они отображаются, они просто не сохраняются в файле excel, чего-то еще не хватает?


person uaena    schedule 18.12.2020    source источник
comment
изменить на print("Error Writing file.", e)   -  person eyllanesc    schedule 18.12.2020


Ответы (2)


Таким образом, ваша строка wb.save(filename) находится внутри вашего цикла for, поэтому одно и то же имя файла сохраняется в каждом цикле.

Переместите эту строку наружу и после цикла for во внешнем отступе и, следовательно, сохраните ее только один раз.

Кроме того, убедитесь, что имя файла еще не существует, иначе вы можете получить всплывающее диалоговое окно. Вы уверены? и тогда вам нужно принудительно сохранить его.

person Rob Py    schedule 18.12.2020
comment
но когда я выдвигаю его наружу, он говорит AttributeError: 'tuple' object has no attribute 'write' - person uaena; 19.12.2020
comment
Я ожидаю, что вам придется проверить, какие значения вы получаете от qtablewidget. - person Rob Py; 21.12.2020
comment
Я ожидаю, что вам придется проверить, какие значения вы получаете от qtablewidget, чтобы убедиться, что вы не получаете недопустимое (нулевое) значение. Используйте печать, чтобы убедиться, что значения действительны. Кроме того, следующие строки можно использовать для сохранения значений в Excel, и большинство из них уже есть в вашем коде. from openpyxl import Workbook wb = Workbook() sheet = wb.active # в циклах for получите ссылку на ячейку и присвойте значение данных cellref = sheet.cell(row=4,column=5) cellref.value = 'ваши данные для ячейки' #после цикла for wb.save('samplefile.xlsx') - person Rob Py; 21.12.2020
comment
теперь я могу создать файл .xlsx, но данные из qtable не записываются в файл, я попытался распечатать значения в qtablewidget, и он показывает, он просто не сохраняется в файл excel, извините, я не совсем понял получить ссылку на часть ячейки? - person uaena; 21.12.2020
comment
Ваша проблема может быть не в сохранении в Excel, а просто в том, чтобы быть уверенным. Начните с простого тестирования того, что вы можете сохранить простую строку в Excel, используя свой код, чтобы просто ввести значение в ячейку, например так.# получить ссылку на ячейку cellref = sheet.cell(row=4,column=5) # присвоить ячейке значение cellref.value = 'test hello world' #после цикла for wb.save('samplefile.xlsx') - person Rob Py; 21.12.2020
comment
я отредактировал свой вопрос и поместил свой последний код сейчас, я также сделал простой тест, и он сработал, может быть, сейчас чего-то не хватает в моем коде???? - person uaena; 21.12.2020
comment
sheet.cell(3,3).value = 'hello world' это позволит получить ссылку на ячейку и ввести строку 'hello world' в ячейку excel C3 - person Rob Py; 21.12.2020
comment
измените строку: sheet.write(row, column, text) и сделайте ее sheet.cell(row,column).value = text - person Rob Py; 21.12.2020
comment
это не сработало... - person uaena; 21.12.2020
comment
ваш первый индекс из цикла for равен 0. Однако в Excel таблица начинается с 1. Поэтому вам нужно изменить строку ввода ячейки на это: sheet.cell(row+1,column+1).value = text # К сожалению, если вы не распечатаете сообщение об ошибке, вам будет сложно выявить проблемы. У вас не должно быть Pass в части исключения вашего кода, так как вам лучше знать, когда возникает проблема. Лучше распечатать сообщение об ошибке и попытаться решить оттуда. - person Rob Py; 21.12.2020
comment
у вас есть строка кода, которую вы добавили в свое обновление редактирования, которая не нужна: если не имя файла: - person Rob Py; 21.12.2020
comment
аааа, я вижу ... я добавил, если не имя файла ранее, потому что он не создает файл, но я удалил сейчас и заменил лист.ячейка (строка + 1, столбец + 1). значение = текст, теперь это работает, я просто нужно добавить заголовки столбцов, большое спасибо за терпение: D - person uaena; 21.12.2020

Почти все статические методы QFileDialog (кроме getExistingDirectory() и getExistingDirectoryUrl()) возвращают кортеж в виде (file(s), filter).

Для getOpenFileNames() (обратите внимание на множественное число) первый объект представляет собой список строк, указывающих выбранные файлы, в остальных случаях это путь к файлу в виде строки или URL-адреса.

Обратите внимание, что если диалоговое окно закрыто, строка файла (или список) пуста, поэтому вы должны проверить это, прежде чем продолжить запись файла:

    filename, filter = QtWidgets.QFileDialog.getSaveFileName(
        self, 'Save file', '','Excel files(*.xlsx)')
    if not filename:
        return
    # ...

Также не следует пытаться сохранять файл при каждом цикле цикла for.

Хотя 99% функций в Qt ведут себя так же, как и в PyQt, это не всегда так, особенно в ситуациях, когда C++ использует переменные, на которые ссылаются. Всякий раз, когда вы не уверены в функции или получаете неожиданное поведение от нее, вы можете проверить документация PyQt (возвращаемые типы указываются в конце определения функции после символа →) или просто вызовите help(class.function) в консоли python. Еще более простое решение — просто print возвращаемого значения, и вы сами в этом убедитесь.

person musicamante    schedule 18.12.2020
comment
Теперь я могу создать файл xlsx, и он сохраняется, но когда я его открываю, данные не сохраняются и пусты, чего-то не хватает в цикле for или что-то в этом роде? я также переместил wb.save наружу - person uaena; 19.12.2020