2016-03-25 5 views
1

Я новичок в ReportLab, страницах шаблонов. Мне нужно создать отчет, в котором у меня есть 2 шаблона страниц. Первая страница использует шаблон страницы заголовка, а на всех других страницах - общий шаблон. Отчет должен разбивать таблицу на несколько страниц. На первой странице таблицы нужно отображать на менее широком кадре, а затем остальную таблицу на более широких кадрах на остальной части страниц.Reportlab Table split

Как изменить ширину столбцов и стиль таблицы, когда таблица разбивается на разные страницы?

EDIT: Здесь я помещаю код, который успешно расколов, но сохраняет таблицу в одинаковой ширины на всех страницах

# ReportLab PDF Generation Library 
from reportlab.pdfgen  import canvas 
from reportlab.lib.units  import inch, cm 
from reportlab.lib.pagesizes import letter, landscape 
from reportlab.lib   import colors 

from reportlab.lib.styles import getSampleStyleSheet 
from reportlab.platypus import BaseDocTemplate, Frame, Paragraph, NextPageTemplate, PageBreak, PageTemplate, Spacer 
from reportlab.platypus.tables import Table, TableStyle 

# Constants 
Font_Leading = 10 
Word_Spacing = 0.0 
Char_Spacing = 0.08 

#global table 
data= [['DATE', 'NAME', 'ITEM', 'AMOUNT', 'BALANCE'], 
    ['01/12/15', 'William', 'ITEM1 RELATED STUFF', '365.00', '43.30'] 
    # CONSIDER MANY MORE ITEMS HERE 
    # NUMBER FO ITMES VARYING IN WAY TO CAUSE 1 OR MORE PAGES 
    # 3RD COLUMN WILL HAVE DESCRIPTIVE ITEM 
    # WHICH WILL REPLACE WITH PARAGARPHS LATER ON 
    ] 
t=Table(data,repeatRows=1, 
    colWidths=[.7*inch, 1*inch, 2.4*inch, .8*inch, .8*inch]) 
#The top left cell is (0, 0) the bottom right is (-1, -1). 
tStyle = TableStyle([ 
    # All Cells 
    ('FONTSIZE', (0,0), (-1,-1), 8), 
    ('TOPPADDING', (0,0), (-1,-1), 0), 
    ('BOTTOMPADDING', (0,0), (-1,-1), 0), 
    ('VALIGN', (0,0), (-1,-1), 'TOP'), 
    ('LEADING', (0,0), (-1,-1), 10), 
    # Top row 
    ('BACKGROUND', (0,0), (-1,0), colors.maroon), 
    ('TEXTCOLOR', (0,0), (-1,0), colors.white), 
    ('ALIGN', (0,0), (-1,0), 'CENTRE'), 
    # 3RD and 4th column, 
    ('ALIGN', (3,0), (4,-1), 'RIGHT'), 
    # Line commands 
    # All 
    ('BOX',(0,0),(-1,-1),.5,colors.black), 
    # top row 
    ('GRID',(0,0),(-1,0),.5,colors.black), 
    # all columns 
    ('LINEBEFORE',(0,0),(-1,-1),.5,colors.black), 
    # last column 
    ('LINEAFTER',(-1,0),(-1,-1),.5,colors.black), 
    # last row 
    ('LINEBELOW',(0,-1),(-1,-1),.5,colors.black)]) 
t.setStyle(tStyle) 

def othPg(c, doc): 
    t.colWidths = [.2*inch, .2*inch,4*inch, .2*inch, .2*inch] 
    tStyle.add('BACKGROUND',(0,0),(-1,-1),colors.lightblue) 
    x=1 

def pgHdr(c, doc): 
    width,height = letter 
    c.saveState() 
    c.translate(.3 * inch, 0 * inch) 

# STUFF RELATED TO 2 INCH STTIC HEADER FOR FIRST PAGE 
    c.restoreState() 


def main(): 
    pdf_file = 'stmt.pdf' 
    Elements = [] 
    doc = BaseDocTemplate(pdf_file, 
         pagesize=letter, 
         leftMargin=.3*inch, 
         rightMargin= .1 * inch, 
         topMargin= .1 * inch, 
         bottomMargin=.3 * inch, 
         showBoundary=1) 
    #normal frame as for SimpleFlowDocument 
    frameT = Frame(doc.leftMargin + 2*inch, doc.bottomMargin, doc.width - 2.01*inch, doc.height - 4.1*inch, id='normal', showBoundary=0) 
    frameB = Frame(doc.leftMargin+2, doc.bottomMargin, 7.5*inch, 10*inch, id='small', showBoundary=1) 



    doc.addPageTemplates([PageTemplate(id='First',frames=frameT,onPage=pgHdr), 
         PageTemplate(id='Later',frames=frameB,onPage=othPg) 
         ]) 
    Elements.append(NextPageTemplate('Later')) 
    Elements.append(t) 
    doc.build(Elements) 

if __name__ == "__main__": 
    sys.exit(main()) 

ответ

1

С нормальной Table кажется, что это не возможно сделать это автоматически (на основе source code). Это делается для того, чтобы сохранить ширину столбца при расщеплении, что имеет смысл, так как изменение макета таблицы после разрыва страницы сделало бы ее довольно запутанной для конечного пользователя.

Вы можете сделать свою собственную версию Table, которая меняет размер столбца, но это потребует перезаписывания довольно сложной функции splitTable. Который будет болью в заднице.

Таким образом, в вашем случае самым простым и, вероятно, самым жизнеспособным решением было бы сделать рамки в обоих шаблонах одинаковой ширины. Тогда вам не нужно менять ширину столбца вообще.

Редактировать: По просьбе OP я рассмотрел варианты, чтобы действительно использовать стиль и ширину столбца для более поздних страниц. На основании этого я создал следующий класс, основанный на Reportlabs Table:

class LaterPagesTable(Table): 
    def __init__(self, data, laterColWidths=None, laterStyle=None, **kwargs): 
     Table.__init__(self, data, **kwargs) 

     self._later_column_widths = laterColWidths 
     self._later_style = laterStyle 


    def split(self, availWidth, availHeight): 
     self._calc(availWidth, availHeight) 
     if self.splitByRow: 
      if not rl_config.allowTableBoundsErrors and self._width>availWidth: return [] 
      tables = self._splitRows(availHeight) 

      if len(tables): 
       self.onLaterPages(tables[1]) 
      return tables 
     else: 
      raise NotImplementedError 


    def onLaterPages(self, T): 
     if self._later_column_widths: 
      T._argW = self._later_column_widths 

     if self._later_style: 
      T.setStyle(self._later_style) 

Этот класс позволяет пользователю указать стиль и ColumnWidth для последующих страниц, используя ключевые аргументы и laterStyle которых синтаксис является точно таким же, как и для нормальных colWidths и style, но будут использоваться только в тех частях таблицы, которые расположены за пределами исходной страницы.

+0

Это не жизнеспособное решение, поскольку таблица слишком велика, и только первая страница имеет меньше места. Можете ли вы предложить, как я могу разделить данные на основе размера кадра, чтобы я мог создать 2 таблицы, сначала для шаблона первой страницы, а второй, которые будут разделены на все оставшиеся страницы. – bvnbhati

+0

Не могли бы вы предоставить нам код, который показывает вашу проблему в этом случае? Это облегчает решение проблемы. – B8vrede

+0

@bvnbhati Я добавил код, который должен быть в состоянии доставить поведение, которое вы ищете. – B8vrede