将 QTableWidget 内容写入 .csv 或 .xls 文件

3

能否将QTableWidget中的内容写入csv文件?我找到了一个关于使用xlwt将数据写入.xls文件的问题,但是似乎无法通过我的代码实现。

def saveFile(self):
    filename = unicode(QtGui.QFileDialog.getSaveFileName(self, 'Save File', '', ".xls(*.xls)"))    
    wbk = xlwt.Workbook()
    self.sheet = wbk.add_sheet("sheet")
    self.write()
    wbk.save(filename)    


def write(self):
    for col in range (self.coordinates.columnCount()):
        for row in range(self.coordinates.rowCount()):
            text=str(self.coordinates.item(row,col).text())
            self.sheet.write(row,col,text)

I get the following error:

  File "C:\Users\Tory\Desktop\DIDSON.py", line 186, in saveFile
    self.write()
  File "C:\Users\Tory\Desktop\DIDSON.py", line 192, in write
    text=str(self.coordinates.item(row,col).text())
AttributeError: 'NoneType' object has no attribute 'text'

为什么会这样?self.coordinates是一个QTableWidget。我已经成功把表格里的项目保存到了工作表中,尽管我还想以.csv文件的格式进行保存...


为什么要设置并递增 rowcol?你可以直接使用 ix,或者我有什么遗漏吗?如果您不使用 try/except 而是让跟踪打印并将其发布在问题中,那么这对调试很有用。 - BrtH
而且,你为什么要从QTableWidget中获取数据呢?如果你有数据要放在表格中,为什么不将这些原始数据写入csv/xls文件呢? - BrtH
第一条评论 - 实际上不太确定,将进行修订。第二个问题,表“records”鼠标单击图像坐标,因此我希望用户能够看到坐标,然后保存完成的版本。 - Victoria Price
1个回答

13
回答有关AttributeError的问题:可能是因为表格中存在一些空行或列。
一个空单元格没有分配QTableWidgetItem,所以table.item()将返回None(显然没有'text'属性)。
要将表格保存为csv文件,请尝试下面的示例代码(还可以打开csv文件,并希望处理任何潜在的Unicode问题)。
import sys, csv
from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self, rows, columns):
        QtGui.QWidget.__init__(self)
        self.table = QtGui.QTableWidget(rows, columns, self)
        for column in range(columns - 1):
            for row in range(rows - 1):
                item = QtGui.QTableWidgetItem('Text%d' % row)
                self.table.setItem(row, column, item)
        self.buttonOpen = QtGui.QPushButton('Open', self)
        self.buttonSave = QtGui.QPushButton('Save', self)
        self.buttonOpen.clicked.connect(self.handleOpen)
        self.buttonSave.clicked.connect(self.handleSave)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.table)
        layout.addWidget(self.buttonOpen)
        layout.addWidget(self.buttonSave)

    def handleSave(self):
        path = QtGui.QFileDialog.getSaveFileName(
                self, 'Save File', '', 'CSV(*.csv)')
        if not path.isEmpty():
            with open(unicode(path), 'wb') as stream:
                writer = csv.writer(stream)
                for row in range(self.table.rowCount()):
                    rowdata = []
                    for column in range(self.table.columnCount()):
                        item = self.table.item(row, column)
                        if item is not None:
                            rowdata.append(
                                unicode(item.text()).encode('utf8'))
                        else:
                            rowdata.append('')
                    writer.writerow(rowdata)

    def handleOpen(self):
        path = QtGui.QFileDialog.getOpenFileName(
                self, 'Open File', '', 'CSV(*.csv)')
        if not path.isEmpty():
            with open(unicode(path), 'rb') as stream:
                self.table.setRowCount(0)
                self.table.setColumnCount(0)
                for rowdata in csv.reader(stream):
                    row = self.table.rowCount()
                    self.table.insertRow(row)
                    self.table.setColumnCount(len(rowdata))
                    for column, data in enumerate(rowdata):
                        item = QtGui.QTableWidgetItem(data.decode('utf8'))
                        self.table.setItem(row, column, item)

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    window = Window(10, 5)
    window.resize(640, 480)
    window.show()
    sys.exit(app.exec_())

“open” 可以接受 Unicode 文件名并正确处理。您可以省略 .encode(sys.getfilesystemencoding()) 部分。 - Avaris
@Avaris。根据使用的平台和Python的特定版本/构建,它可能会执行正确的操作-但不能保证。然而,我同意它在Windows上总是可以被删除(我认为OP正在使用Windows)。 - ekhumoro
这不是保证吗?文档说使用Unicode文件名至少与显式编码sys.getfilesystemencoding()相同。 - Avaris
@Avaris。抱歉,我错过了你特别提到的“open”。我的意思是,通常情况下不能依赖自动转换Unicode路径。但无论如何,在我的示例中唯一出现的原因是由于从某些现有代码中复制和粘贴 - 所以我将其删除以避免进一步混淆... - ekhumoro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接