【问题标题】:Python: Iteratively Writing to Excel FilesPython:迭代写入 Excel 文件
【发布时间】:2015-05-11 18:36:12
【问题描述】:

Python 2.7。我正在使用 xlsxwriter。

假设我有myDict = {1: 'One', 2: 'Two', 3: 'Three'}

我需要对值执行一些转换并将结果写入电子表格。

所以我编写了一个函数来创建一个新文件并在其中放置一些标题并进行格式化,但不要关闭它,以便我可以在下一个函数中进一步编写。

然后我编写另一个函数来转换我的 dict 值并将它们写入工作表。

在上课方面我是个菜鸟,所以如果这看起来很愚蠢,请原谅我。

import xlsxwriter

class ReadWriteSpreadsheet(object):
    def __init__(self, outputFile=None, writeWorkbook=None,     writeWorksheet=None):
        self.outputFile = outputFile
        self.writeWorksheet = writeWorksheet
        self.writeWorkbook = writeWorkbook

    # This function works fine
    def setup_new_spreadsheet(self):
        self.writeWorkbook = xlsxwriter.Workbook(self.outputFile)
        self.writeWorksheet = self.writeWorkbook.add_worksheet('My Worksheet')
        self.writeWorksheet.write('A1', 'TEST') 

    # This one does not
    def write_data(self):
        # Forget iterating through the dict for now
        self.writeWorksheet.write('A5', myDict[1])

x = ReadWriteSpreadsheet(outputFile='test.xlsx')
x.setup_new_spreadsheet()
x.write_data()

我明白了:

Exception Exception: Exception('Exception caught in workbook destructor. Explicit close() may be required for workbook.',) in <bound method Workbook.__del__ of <xlsxwriter.workbook.Workbook object at 0x00000000023FDF28>> ignored

文档说这个错误是由于没有关闭工作簿,但如果我关闭它,我就不能再写了……

我如何构造这个类,以便setup_new_spreadsheet() 中的工作簿和工作表能够被write_data() 写入?

【问题讨论】:

  • 你是什么意思“不[工作]”?错误信息?意外的输出?你确保setup_new_spreadsheetwrite_data 之前被调用了吗?
  • @jonrsharpe 抱歉,我添加了有关类型错误的详细信息。是的,我正在按顺序调用函数。
  • 显然self.writeWorkbook.add_worksheet 没有返回任何内容。也许你应该看看图书馆的文档?
  • 这么短的代码中有很多误解。我建议在尝试编写 Excel 文件之前先处理一些 OOP 和 Python 基础知识。
  • @AutomaticStatic:不,着名的garkin 是对的。您发布的代码中有许多问题。如果您认为写入 Excel 并不难(这是一个公平的评估,当然对于任何精通 XlsxWriter 的人来说),那么您应该考虑根本不使用类,而只使用函数和全局变量。一些学术类型不会喜欢它,但它会更容易理解并且更容易为新手做好准备。

标签: python excel


【解决方案1】:

当python意识到您将不再需要在其余代码中使用您的工作簿并因此决定将其从他的内存中删除(垃圾收集)时,就会触发您的问题中提到的异常。这样做时,它会意识到您尚未关闭工作簿,因此根本不会将您的 excel 电子表格保存在磁盘上(我假设只会在关闭时发生)并且会引发该异常。

如果你在你的类上有另一个方法 close:self.writeWorkbook.close() 并确保最后调用它,你就不会出现这个错误。

【讨论】:

    【解决方案2】:

    当您执行ReadWriteSpreadsheet() 时,您将获得您定义的类的新实例。该新实例不了解在其他实例中设置的任何工作簿。

    看起来您想要做的是获取单个实例,然后在该实例上发出方法:

    x = ReadWriteSpreadsheet(outputFile='test.xlsx')
    x.setup_new_spreadsheet()
    x.write_data()
    

    解决您的新问题:

    文档说这个错误是由于没有关闭工作簿,但如果我关闭它,我就不能再写了......

    是的,这是真的,你不能再写了。这是 Excel 文件的基本属性之一。在我们在这里使用的级别上,没有“附加”或“更新”Excel 文件这样的事情。甚至 Excel 程序本身也做不到。您只有两种可行的方法:

    1. 将所有数据保存在内存中,最后只提交到磁盘。
    2. 重新打开文件,将数据读入内存;修改内存数据;并将所有内存中的数据写回一个新的磁盘文件(如果你想覆盖,它可以与原始文件同名)。

    第二种方法需要使用可以读取 Excel 文件的包。主要的选择有xlrdOpenPyXL。后者将同时处理读写,所以如果你使用那个,你不需要XlsxWriter

    【讨论】:

    • 这是有道理的,但是当我尝试它时,我得到TypeError: 'Worksheet' object is not callable Exception Exception: Exception('Exception caught in workbook destructor. Explicit close() may be required for workbook.',) in &lt;bound method Workbook.__del__ of &lt;xlsxwriter.workbook.Workbook object at 0x00000000023ADF60&gt;&gt; ignored 文档说当你不关闭工作簿时会出现这个错误,但是一旦我关闭它,我就不能写更进一步。
    • 好吧,你说的函数 (setup_new_spreadsheet) 不应该像你的问题中写的那样工作,因为确实,Worksheet 对象是不可调用的,但你正在尝试调用它。您可能指的是self.writeWorksheet.write('A1', 'TEST'),而不是self.writeWorksheet('A1', 'TEST')。您的__init__ 中也有明显的缩进错误。因此,如果您想要任何有意义的答案,您需要做的第一件事就是清理您的问题,以便它真正反映您正在使用的代码。
    • 对不起。这只是我的 OP 中的一个错字。
    • 好吧,我很抱歉我草率的 OP,它现在与我的代码和错误消息完全匹配。
    • @AutomaticStatic:您最近的编辑尝试使用我的答案,但您仍然弄错了。注意最后一行中的双倍句点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多