How do I use openpyxl and still maintain OOP struc

2019-09-18 07:22发布

问题:

I am using python to do some simulations and using openpyxl to generate the reports. Now the simulation is results are to be divided into several sheets of an excel file. By the principles of OOP my structure should have a base simulator class which implements basic operations and several derived classes which implement modifications to simulator. Since functions related to a class should remain with the class I want the report sheets to be generated by the derived classes (with all its styling and formatting etc). Then maybe a driver class or function which takes all these report sheets and puts them in one work book. But as far as I can tell there is no way to copy a worksheet in openpyxl. Now it seems like I have broken the OOP models. Is there a way out of this?

Edit

Here is an example for my code. This is a trimmed fat free version, the real class is not that simple

from openpyxl import Workbook
from openpyxl.styles import Font

class sim1:#this will inherit from another class sim which has basic operations
    def __init__(self):
        #assume function calling and complex math here
        self.x = 1
    def f1OverRide(self):
        #over rides some function in sim to implement custom method for sim1 (several of these)
        return 23
    def get_sheet(self):
        wb = Workbook()
        ws = wb.active
        ws['A1'] = self.x
        #example formatting real formatting is pretty complex
        ws['A1'].font = Font(size=12,name='Calibri')
        return ws

class sim2:#this will inherit from another class sim which has basic operations
    def __init__(self):
        #assume function calling and complex math here
        self.x = 12
    def f1OverRide(self):
        #over rides some function in sim to implement custom method for sim1 (several of these)
        return 42
    def get_sheet(self):
        wb = Workbook()
        ws = wb.active
        ws['A1'] = self.x
        #example formatting, real formatting is pretty complex
        ws['A1'].font = Font(size=14,name='Calibri',color='ff2223')
        return ws


s1 = sim1()
s2 = sim2()
# now I want to get the sheets for sim1 and sim2 and combine in 1 workbook
wb = Workbook()
ws1 = s1.get_sheet()
ws2 = s2.get_sheet()
# dont know what to do now :( openpyxl can not copy sheet into this workbook

回答1:

OOP copy Worksheets between Workbooks, for instance:

from openpyxl import Workbook
from openpyxl.styles import Font
from copy import copy

class sim():
    def __init__(self, n):
        self.n = n

    def get_sheet(self):
        #...
        wb = Workbook()
        ws = wb.active
        ws['A1'] = 'sim'+str(self.n)
        if self.n == 1:
            ws['A1'].font = Font(size=12,name='Calibri')
        else:
            ws['A1'].font = Font(size=14, name='Calibri', color='ff2223')
        return ws

class sim_Workbook(Workbook):
    # overload Workbook.copy_worksheet
    def copy_worksheet(self, from_worksheet):
        # Create new empty sheet and append it to self(Workbook)
        ws = self.create_sheet( title=from_worksheet.title )

        for row, row_data in enumerate(from_worksheet.rows,1):
            for column, from_cell in enumerate(row_data,1):
                cell = ws.cell(row=row, column=column)
                cell.value = from_cell.value
                cell.font = copy(from_cell.font)
s1 = sim(1)
s2 = sim(2)

wb = sim_Workbook()
wb.copy_worksheet( s1.get_sheet() )
wb.copy_worksheet( s2.get_sheet() )
wb.save('../test/test.xlsx')  

#example formatting real formatting is pretty complex

You have to copy your complex formatting, style by style as shown by font in the example. This could lead to huge workload, depending how many cells you have to copy.
Read this to get a hint about this, but you can't do it 1:1 as you copy from workbook to workbook copying-styles-from-a-range-to-another-range

Tested with Python:3.4.2 - openpyxl:2.4.1 - LibreOffice: 4.3.3.2