2016-06-10 8 views
4

Я только начал работать с XlsxWriter, и я хотел написать свои собственные методы, чтобы упростить запись excels, так как данные, которые у меня есть, имеют один и тот же формат более или менее.Наследование XlsxWriter и Python

Я хотел сделать это полностью прозрачным, написав модуль, который наследует XlsxWriter, и для тех, кому не нужны мои методы с помощью моего модуля, это то же самое, что напрямую использовать XlsxWriter, а если в какой-то момент нужен один из моих методов он может быть использован без каких-либо изменений кода или добавления большего количества объектов, работающих в одном файле/объекте.

Так что я начал писать модуль:

import xlsxwriter 

class XlsxMaster(xlsxwriter.Workbook): 

    def __init__(self, filename): 
     super(XlsxMaster, self).__init__(filename) 

    def write_results(self): 
     print "write results" 

Тогда я могу использовать:

from xlsx_Master import XlsxMaster 

workbook = XlsxMaster('./Expenses01.xlsx') 
worksheet = workbook.add_worksheet() 
worksheet.write_results() 

Проблема заключается в том, что это не работает, как объект рабочего листа происходит от xlsxwriter.worksheet, а не из мой модуль, его можно правильно назвать workbook.write_results(), но это не то, что я хочу. Как я могу добавить методы к xlsxwriter.worksheet таким образом? Я не знаю, как это решить. Может быть, есть способ, или, может быть, я ошибся с самого начала.

ответ

2

write_results является метод листа, поэтому вам придется создать класс, унаследованный от Worksheet тоже. Там вы сможете написать свой write_results. И вам необходимо переопределить метод, в котором создается рабочий лист . Рассматривая код _add_sheet

Не изящный, я боюсь, но это то, о чем вы просите.

+0

Я думаю, что это решение, но это займет много работы, так как это первое препятствие. Я уверен, что найду много других, когда буду использовать диаграммы, форматы и т. Д. ... Я все еще надеюсь, что есть другое решение вместо создания других классов и переопределения существующих методов только для добавления новых методов, может быть, мне придется столкнуться с суровой истиной, что нет другого способа. –

3

Я принял несколько иной подход, и он работал достаточно хорошо, чтобы произвести вывод xls в веб-приложении.

Вместо того, чтобы переопределять материал xlswriter, я только что разработал объект Facade, который был сопоставлен с тем, что я пытался сделать, а затем просто позвонил в базовые активы xlswriter, чтобы выполнить эту работу.

import xlsxwriter 

class ExcelWriter(object): 

    def getColFormatInfo(self, fieldname): 
     #some app-specific stuff... 
     f = FieldFormat.factory(self.rdb, fieldname) 
     # width = 30 
     label = f.SHORTNAME 
     width = max(f.LENGTH, len(label)) 
     return width, label 

    def __init__(self, rdb, title): 
     self.rdb = rdb 
     self.fnp = "/tmp/%s.xlsx" % (title) 
     wb = self.workbook = xlsxwriter.Workbook(self.fnp) 

     #http://xlsxwriter.readthedocs.org/en/latest/format.html#set_bg_color 
     self.fmt_title = wb.add_format(dict(bold=True)) 
     self.fmt_title.set_bg_color("#F5F5F5") 
     self.fmt_title.set_border(1) 

     self.fmt_colheader = wb.add_format(dict(bold=True)) 
     self.fmt_colheader.set_bottom(2) 


     self.fmt_link = wb.add_format({'color': 'blue', 'underline': 1}) 

    def add_worksheet(self, wsname): 
     return self.workbook.add_worksheet(wsname) 

    def write_title(self, ws, row, col, s): 
     ws.write(row, col, s, self.fmt_title) 

    def write_colheader(self, ws, row, col, s): 
     ws.write(row, col, s, self.fmt_colheader) 

    def write(self, ws, row, col, s): 
     ws.write(row, col, s) 

    def write_url(self, ws, row, col, url, s): 
     ws.write_url(row, col, url, self.fmt_link, s) 

Как вы можете видеть, что я делаю, чтобы предварительно вычислить некоторые форматы XLS и использовать их в таких вещах, как write_colheader.

Но вы могли бы обобщить этот подход для создания более простых в использовании простых функций для выполнения сложных действий xlswriter за кулисами.

Я не могу найти код, который я использовал для взаимодействия с ним, но он работал достаточно хорошо. Единственное, что было много руководства положить xyz в 1,13 тип кода, который я писал. Нормальная, html, сторона моего веб-приложения использовала django-tables2, чтобы генерировать html, и это было намного меньше кода.

Итак, мой план состоит в том, чтобы вернуться и переписать отчетность, чтобы быть более декларативно-основанным, с передним интерфейсом отчетности, который затем позаботится обо всех командах, которые будут переданы в ExcelWriter, - я все еще ожидаю ExcelWriter однако, иметь примерно такой же API.

О, и в стороне от декларативных изменений одна вещь, которую я сразу же изменил бы в новой реализации, заключалась бы в том, чтобы сохранить константы форматирования, такие как цвет фона # F5F5F5 в Json-файле, и передать это в ExcelWriter при инициализации :

Что-то вроде:

self.fmt_title.set_bg_color(
    self.j_config.get("fmt_title",{}).get("bg_color", "F5F5F5") 
    ) 

в отношении ФОС комментарий о том, чтобы передать переменные, вот некоторые обновленные функции DEFS в качестве возможного решения проблемы.

def add_worksheet(self, wsname): 
    ws = self.current_ws = self.workbook.add_worksheet(wsname) 
    return ws 

#you'd also need to have a set_current_ws function 

def write_url(self, row, col, url, s, ws=None, fmt=None): 
    ws = ws or self.current_ws 
    fmt = fmt or self.fmt_link 

    ws.write_url(row, col, url, fmt, s) 
+0

Это, безусловно, еще один успешный способ ее реализации, но идет немного далеко от того, что я хотел. Что касается каждого метода, я должен передать рабочий лист для работы. Ничего драматичного для меня, но как someonelse будет использовать мой сценарий, даже если он просто будет видеть это «нечто большее». Я рассмотрю эту идею, даже если в данный момент я по-прежнему предпочитаю @pacholik, даже если это сложнее реализовать. –

+0

Отмечено. Я добавил некоторые возможные изменения. В конце концов, это вопрос предпочтения - я склонен быть несколько предвзятым против наследования в качестве решения большинства проблем ООП. В этом случае, на мой взгляд, я считаю, что использование Facade позволяет мне сосредоточиться на проблемах с доменом, то есть писать конкретные типы содержимого Excel. Вместо того, чтобы беспокоиться о внутренних классах XlsWriter, которые вам нужно отслеживать, если вы используете наследование. Как всегда, ваш пробег может отличаться. –