简体   繁体   中英

Python: Iteratively Writing to Excel Files

Python 2.7. I'm using xlsxwriter.

Let's say I have myDict = {1: 'One', 2: 'Two', 3: 'Three'}

I need to perform some transformation on the value and write the result to a spreadsheet.

So I write a function to create a new file and put some headers in there and do formatting, but don't close it so I can write further with my next function.

Then I write another function for transforming my dict values and writing them to the worksheet.

I'm a noob when it comes to classes so please forgive me if this looks silly.

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()

I get:

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

The docs say this error is due to not closing the workbook, but if I close it then I can't write to it further...

How do I structure this class so that the workbook and worksheet from setup_new_spreadsheet() is able to be written to by write_data() ?

When you do ReadWriteSpreadsheet() you get a new instance of the class you've defined. That new instance doesn't have any knowledge of any workbooks that were set up in a different instance.

It looks like what you want to do is get a single instance, and then issue the methods on that one instance:

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

To address your new concern:

The docs say this error is due to not closing the workbook, but if I close it then I can't write to it further...

Yes, that's true, you can't write to it further. That is one of the fundamental properties of Excel files. At the level we're working with here, there's no such thing as "appending" or "updating" an Excel file. Even the Excel program itself cannot do it. You only have two viable approaches:

  1. Keep all data in memory and only commit to disk at the very end.
  2. Reopen the file, reading the data into memory; modify the in-memory data; and write all the in-memory data back out to a new disk file (which can have the same name as the original if you want to overwrite).

The second approach requires using a package that can read Excel files. The main choices there are xlrd and OpenPyXL . The latter will handle both reading and writing, so if you use that one, you don't need XlsxWriter .

The exception mentioned in your question is triggered when python realises you will not need to use your Workbook any more in the rest of your code and therefore decides to delete it from his memory (garbage collection). When doing so, it will realise you haven't closed your workbook yet and so will not have persisted your excel spreadsheet at all on the disk (only happen on close I assume) and will raise that exception.

If you had another method close on your class that did: self.writeWorkbook.close() and made sure to call it last you would not have that error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM