PyQt:如何对 excel 文件的 QTableView 列进行排序(字符串和数字以及日期类型)

PyQt: How to sort QTableView columns of a excel file(strings and numericals and datetype)

这是以下问题的后续问题:

现在我打算对 excel 个文件进行相同的排序

这是我的代码:

self.Upload = QtGui.QPushButton()
self.Upload.clicked.connect(self.showOpenDialog)
self.Table = QtGui.QPushButton()
self.table.clicked.connect(self.LoadTable)


def showOpenDialog(self):
    fileName = QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home')
    if (".xls" or ".xml" or ".xlsx" or ".xlsm") in fileName:
        with open(fileName, 'rb') as drate:
            self.Datas = pd.read_excel(drate, index_col=0)
        self.Loaded_File.clear()
        self.Loaded_File.append(fileName)
        colll = self.Datas.dtypes.index
        col_names = np.array(colll)


def LoadTable(self):
    tab_table_view = QtGui.QWidget()
    self.Tab.insertTab(0, tab_table_view, self.File_Name)
    self.tableView = QtGui.QTableView(tab_table_view)
    self.tableView.setGeometry(QtCore.QRect(0, 0, 721, 571))
    self.model = QtGui.QStandardItemModel(self)
    file_name_temp = self.File_Name
    self.tableView.setModel(self.model)
    colll = self.Datas.dtypes.index
    col_names = np.array(colll)
    col_names = np.insert(col_names, 0, self.Datas.index.name)
    self.model.setHorizontalHeaderLabels(col_names)
    self.tableView.hideRow(0)
    self.tableView.setSortingEnabled(True)

            if (".xls" or ".xml" or ".xlsx" or ".xlsm") in self.File_Name:
        from itertools import chain
        ii = 1
        book = xlrd.open_workbook(self.File_Name)
        sheet = book.sheet_by_index(0)
        num_col = len(self.Datas.columns)
        num_row = len(self.Datas)
        print(num_col,num_row)
        self.Matrix = [[0 for x in range(num_col+1)] for y in range(num_row)]
        for i in range(num_row):
            self.Matrix[i][0]=self.Datas.index.values[i]
            for j in range(num_col):
                self.Matrix[i][j+1] = self.Datas.iat[i,j]
        print(self.Matrix)
        for i in range(num_row):
            items = []
            for j in range(num_col):
                field = self.Matrix[i][j]
                item = QtGui.QStandardItem(field)
                for numtype in (int, float):
                    try:
                        data = numtype(field)
                        break
                    except (ValueError, OverflowError):
                        pass
                else:
                    print('Not a number: %r' % field)
                    data = field
                item.setData(data, QtCore.Qt.UserRole)
            items.append(item)
            self.model.appendRow(items)

输出将是:

Not a number: 'Government'
Not a number: 'Canada'
Not a number: 'Carretera'
Not a number: 'None'
Traceback (most recent call last):
  File "Main_File.py", line 1535, in loadTable
    item = QtGui.QStandardItem(field)
TypeError: arguments did not match any overloaded call:
  QStandardItem(): too many arguments
  QStandardItem(str): argument 1 has unexpected type 'Timestamp'
  QStandardItem(QIcon, str): argument 1 has unexpected type 'Timestamp'
  QStandardItem(int, int columns=1): argument 1 has unexpected type 'Timestamp'
  QStandardItem(QStandardItem): argument 1 has unexpected type 'Timestamp'

如果文件中的数据类型为 str(最多 "None")并且当第一个 int 或 float 出现时它会生成一些重载调用,这很好。

请有人帮助我。

下面是一个演示脚本,它可以读取 csv 和 excel 文件,并且应该正确地对日期、整数、浮点数和字符串进行排序。

import sys
import pandas as pd, numpy as np
from PyQt4 import QtCore, QtGui

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.model = QtGui.QStandardItemModel(self)
        self.model.setSortRole(QtCore.Qt.UserRole)
        self.tableView = QtGui.QTableView()
        self.tableView.setSortingEnabled(True)
        self.tableView.setModel(self.model)
        self.button = QtGui.QPushButton('Open CSV', self)
        self.button.clicked.connect(self.handleButton)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.tableView)
        layout.addWidget(self.button)

    def handleButton(self):
        filters = (
            'CSV files (*.csv *.txt)',
            'Excel Files (*.xls *.xml *.xlsx *.xlsm)',
            )
        path, filter = QtGui.QFileDialog.getOpenFileNameAndFilter(
            self, 'Open File', '', ';;'.join(filters))
        if path:
            csv = filter.startswith('CSV')
            if csv:
                dataframe = pd.read_csv(path)
            else:
                dataframe = pd.read_excel(path)
            self.model.setRowCount(0)
            dateformat = '%m/%d/%Y'
            rows, columns = dataframe.shape
            for row in range(rows):
                items = []
                for column in range(columns):
                    field = dataframe.iat[row, column]
                    if csv and isinstance(field, str):
                        try:
                            field = pd.to_datetime(field, format=dateformat)
                        except ValueError:
                            pass
                    if isinstance(field, pd.tslib.Timestamp):
                        text = field.strftime(dateformat)
                        data = field.timestamp()
                    else:
                        text = str(field)
                        if isinstance(field, np.number):
                            data = field.item()
                        else:
                            data = text
                    item = QtGui.QStandardItem(text)
                    item.setData(data, QtCore.Qt.UserRole)
                    items.append(item)
                self.model.appendRow(items)

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 150, 600, 400)
    window.show()
    sys.exit(app.exec_())

正如 Ekhumoro 所建议的,Excel 数据的排序最容易用 Pandas 完成。我用openpyxl试过类似的操作,但是太局限了。 Pandas 可以为您节省很多行代码。

一个小例子:

from PyQt4 import QtGui , QtCore
import pandas as pd
import numpy as np
import time
import sys

# open excel file
sales = pd.read_excel ("Sales.xlsx" , parse_dates=['Data'] )
# select columns
purchase_patterns = sales [['Total','Date']]
# choose date index
purchase_patterns = purchase_patterns.set_index("Date")
# regroup / resample by week and get subtotals by sum 
resample = purchase_patterns.resample ('W' , how = sum)

这里有一些不错的链接: