Как в python сохранить данные из "tableView" в dbf файл?
Рабочий вариант сохранения в dbf файл
При нажатии на "pushButton", открывается диалоговое окно для выбора dbf файла, он загружается в "tableView", выполняются различные подсчёты, и нужно итоговую таблицу из "tableView" сохранить в dbf файл. Как из "tableView" сохранить в dbf файл?
import sys
from PyQt5 import QtWidgets, uic
from PyQt5.QtWidgets import QTableView, QPushButton, QVBoxLayout, QWidget, QFileDialog, QMessageBox
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from dbfread import DBF
import pandas as pd
import os
import dbf
class ExcelViewer(QtWidgets.QMainWindow):
def __init__(self):
super(ExcelViewer, self).__init__()
uic.loadUi('main.ui', self)
self.model = QStandardItemModel(self)
self.table_view = self.findChild(QTableView, 'tableView')
self.table_view.setModel(self.model)
self.button = self.findChild(QPushButton, 'pushButton')
self.button.clicked.connect(self.load_dbf_data)
self.skip_rows = 0
def load_dbf_data(self):
options = QFileDialog.Options()
filenames, _ = QFileDialog.getOpenFileNames(self, "Выберите файлы", "", "Dbf Files (*.dbf)", options=options)
if filenames:
self.model.clear()
total_sum = 0
for i, filename in enumerate(filenames):
dbf = DBF(filename)
df = pd.DataFrame(iter(dbf))
if i != 0:
df = df.iloc[self.skip_rows:, :]
if i == 0:
df = df.iloc[:-1, :]
else:
df = df.iloc[6:-1, :]
self.skip_rows = 6
for _, row in df.iterrows():
items = [
QStandardItem(str(row[col]))
for col in df.columns
]
self.model.appendRow(items)
if len(row) > 5:
value = pd.to_numeric(row[5], errors='coerce')
if not pd.isnull(value):
total_sum += value
for i in range(6, self.model.rowCount()):
self.model.setItem(i, 0, QStandardItem(str(i-5)))
total_sum = round(total_sum, 2)
self.model.appendRow([
QStandardItem(''),
QStandardItem('ИТОГО ЗАЧИСЛЕНИЙ: ' + str(self.model.rowCount() - 1)),
QStandardItem('ИТОГО СУММА: '),
QStandardItem(''),
QStandardItem(''),
QStandardItem('' + format(total_sum, ',').replace(",", " "))
])
self.save_dbf_data()
def save_dbf_data(self):
options = QFileDialog.Options()
save_filename, _ = QFileDialog.getSaveFileName(self, "Сохранить как", "Новый_файл.dbf", "Dbf Files (*.dbf)", options=options)
if save_filename:
if self.model.rowCount() == 0:
QMessageBox.warning(self, "Внимание", "Нет данных для сохранения.")
return
try:
# Определение полей таблицы dbf
field_specs = '; '.join([f'{chr(97 + i)} C({max([len(self.model.item(row, i).text()) for row in range(self.model.rowCount()) if self.model.item(row, i) is not None])})' for i in range(self.model.columnCount())])
with dbf.Table(save_filename, field_specs=field_specs, codepage='cp866') as db:
db.open(mode=dbf.READ_WRITE)
for row in range(self.model.rowCount()):
db.append(tuple([self.model.item(row, col).text() for col in range(self.model.columnCount()) if self.model.item(row, col) is not None]))
QMessageBox.information(self, "Сохранение", "Данные успешно сохранены в файл " + save_filename)
except Exception as e:
QMessageBox.critical(self, "Ошибка", "Не удалось сохранить данные: " + str(e))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
viewer = ExcelViewer()
viewer.show()
sys.exit(app.exec_())
Ответы (1 шт):
Ну, для начала вам нужно эти самые данные достать из tableView
, а потом засунуть в DBF
. Можно заимпортить библиотеку dbf
и реализовать функцию вот так:
import dbf
def save_dbf_data(self):
save_filename, _ = QFileDialog.getSaveFileName(self, "Сохранить как", "", "Dbf Files (*.dbf)")
if save_filename:
try:
with dbf.Table(save_filename, 'w') as db:
for row in range(self.model.rowCount()):
db.insert([self.model.item(row, col).text() for col in range(self.model.columnCount())])
QMessageBox.information(self, "Сохранение", "Данные успешно сохранены в файл ")
except Exception as e:
QMessageBox.critical(self, "Ошибка", "Не удалось сохранить данные: " + str(e))
Можно еще добавить проверку на наличие данных, чтобы случайно пустой файл не сохранить и добавить использование переменной options
.
import dbf
def save_dbf_data(self):
options = QFileDialog.Options()
save_filename, _ = QFileDialog.getSaveFileName(self, "Сохранить как", "", "Dbf Files (*.dbf)", options=options)
if save_filename:
if self.model.rowCount() == 0:
QMessageBox.warning(self, "Внимание", "Нет данных для сохранения.")
return
# остальная часть функции
UPD 1
В качестве решения новых проблем, можем организовать функцию след. образом:
import dbf
from PyQt5.QtWidgets import QFileDialog, QMessageBox
def save_dbf_data(self):
save_filename, _ = QFileDialog.getSaveFileName(self, "Сохранить как", "", "Dbf Files (*.dbf)")
if save_filename:
try:
# Определение полей таблицы dbf
field_names = [self.model.horizontalHeaderItem(i).text() for i in range(self.model.columnCount())]
field_types = 'C' * self.model.columnCount() # Все поля будут строковыми
with dbf.Table(save_filename, field_specs=field_types) as db:
db.open(mode=dbf.READ_WRITE)
for row in range(self.model.rowCount()):
db.append([self.model.item(row, col).text() for col in range(self.model.columnCount())])
QMessageBox.information(self, "Сохранение", "Данные успешно сохранены в файл " + save_filename)
except Exception as e:
QMessageBox.critical(self, "Ошибка", "Не удалось сохранить данные: " + str(e))
Ну и плюсом можно добавить проверку на наличие данных и использование переменной options
, как я описывал до этого.
UPD 2
проверка на наличие элемента и значения текста элемента в каждой ячейке:
import dbf
from PyQt5.QtWidgets import QFileDialog, QMessageBox
def save_dbf_data(self):
save_filename, _ = QFileDialog.getSaveFileName(self, "Сохранить как", "", "Dbf Files (*.dbf)")
if save_filename:
try:
# Определение полей таблицы dbf
field_names = [self.model.horizontalHeaderItem(i).text() for i in range(self.model.columnCount())]
field_types = 'C' * self.model.columnCount() # Все поля будут строковыми
with dbf.Table(save_filename, zip(field_names, field_types)) as db:
db.open(mode=dbf.READ_WRITE)
for row in range(self.model.rowCount()):
row_data = []
for col in range(self.model.columnCount()):
item = self.model.item(row, col)
if item is None or item.text() is None:
row_data.append('')
else:
row_data.append(item.text())
db.append(row_data)
QMessageBox.information(self, "Сохранение", "Данные успешно сохранены в файл " + save_filename)
except Exception as e:
QMessageBox.critical(self, "Ошибка", "Не удалось сохранить данные: " + str(e))