2014-03-02 28 views
0

中拆分超过1页的表我试图在2页或更多页面上拆分“全角”表。我使用ReportLab和BaseDocTemplate类的Platypus库。在Reportlab

我有一个“全宽”元素表,如果表中有足够的行,这应该被绘制到第一页的框架中。应该在第二页继续。我的问题是,第一页的框架的高度和位置与其他页面不同,因为在第一页的顶部,我需要显示更多信息(是的...我正在讨论发票或订单)。

经过数千次尝试后,我所得到的只是一个带有唯一页面的pdf,只有8个项目/行,这正是他们在第一页需要的空间,但是如果该表有多于8行,然后我得到只有1页,没有表(这意味着一个空框架,虽然我看到日志中的所有数据)的PDF。

我已经使用了方法split()和wrap(),但可能以错误的方式,因为我是新的ReportLab。我向你展示我的代码的最后一个版本:

from django.http import HttpResponse 
from reportlab.pdfgen import canvas 
from reportlab.lib.units import mm 
from reportlab.lib import colors 
from reportlab.lib.pagesizes import A4 
from reportlab.platypus import BaseDocTemplate, PageTemplate, Table, Spacer, Frame, TableStyle,\ 
           NextPageTemplate, PageBreak, FrameBreak 

PAGE_WIDTH = A4[0] 
PAGE_HEIGHT = A4[1] 
MARGIN = 10*mm 

class ThingPDF(BaseDocTemplate): 
    def header(self, canvas, subheader=True): 
     # print 'header()' 
     data = [('AAAA', 'Thing %s' % (self.thing.name)), ] 

     s = [] 
     t = Table(data, colWidths=[95 * mm, 95 * mm], rowHeights=None, style=None, splitByRow=1, 
        repeatRows=0, repeatCols=0) 
     t.setStyle(TableStyle([ 
        ('BACKGROUND', (0, 0), (0, 0), colors.red), 
        ('BACKGROUND', (1, 0), (1, 0), colors.blue), 
        ('ALIGN', (1, 0), (1, 0), 'RIGHT'), 
     ])) 
     s.append(t) 

     # if subheader: 
     #  print 'subheader' 

     self.head.addFromList(s, canvas) 


    def data_table(self, canvas, items): 
     # print 'data_table()' 
     d = [[u'col0', u'col1', u'col2', u'col3', u'col4', ],] 

     for item in items: 
      d.append([item.col0, item.col1, item.col2, item.col3, item.col4]) 

     s = [] 
     t = Table(d, colWidths=[20*mm, 100*mm, 20*mm, 20*mm, 30*mm], rowHeights=20*mm, style=None,\ 
        splitByRow=1, repeatRows=0, repeatCols=0) 

     t.setStyle([('BACKGROUND', (0,0), (-1,0), ('#eeeeee'))]) 


     h=187*mm #TODO 
     w=A4[0] - (2*MARGIN) 

     splitter = t.split(w, h) 
     # print '\n\nresult of splitting: ', len(splitter) 

     for i in splitter: 
      print 'i: ', i 
      self.dataframeX.addFromList(s, canvas) 

     s.append(t) 
     self.dataframe0.addFromList(s, canvas) 

    def on_first_page(self, canvas, doc): 
     canvas.saveState() 
     self.header(canvas) 
     self.data_table(canvas, self.items) 
     canvas.restoreState() 

    def on_next_pages(self, canvas, doc): 
     canvas.saveState() 
     self.header(canvas, subheader=False) 
     canvas.restoreState() 

    def build_pdf(self, thing=None, items=None, user=None): 
     self.thing = thing 
     self.items = items 

     self.doc = BaseDocTemplate('%s.pdf' % (thing.name), 
           pagesize=A4, 
           pageTemplates=[self.first_page, self.next_pages,], 
           showBoundary=1, 
           rightMargin=MARGIN, 
           leftMargin=MARGIN, 
           bottomMargin=MARGIN, 
           topMargin=MARGIN, 
           allowSplitting=1, 
           title='%s' % 'title') 

     self.story.append(Spacer(0*mm, 2*mm)) 
     self.doc.build(self.story) 

     response = HttpResponse(mimetype='application/pdf') 
     response['Content-Disposition'] = 'attachment; filename=%s.pdf' % (reference) 

     return response 

    def __init__(self): 
     self.thing = None 
     self.items = None 
     self.story = [] 

     #========== FRAMES ========== 
     self.head = Frame(x1=MARGIN, y1=A4[1] - (2*MARGIN), width=A4[0] - (2*MARGIN), height=10*mm, 
         leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0, id='header', 
         showBoundary=1)#, overlapAttachedSpace=None, _debug=None) 
     self.dataframe0 = Frame(x1=MARGIN, y1=10*mm, width=A4[0] - (2*MARGIN), height=187*mm, 
           leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0, 
           id='body', showBoundary=1) 
     self.dataframeX = Frame(x1=MARGIN, y1=MARGIN, width=A4[0] - (2*MARGIN), height=257*mm, 
           leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0, 
           id='body', showBoundary=1) 

     #========== PAGES ========== 
     self.first_page = PageTemplate(id='firstpage', frames=[self.head, self.dataframe0], onPage=self.on_first_page) 
     self.next_pages = PageTemplate(id='nextpages', frames=[self.head, self.dataframeX], onPage=self.on_next_pages) 

预先感谢您!

回答

0

您发布的代码缺少一些数据,本身不能运行,所以我无法确定我的答案是否正确。如果这不起作用,请延长您的代码!

首先,您根本不必使用wrapsplit方法!当doc.build消耗故事时,表格将自行分裂。此外,拆分不会拆分表内联,但只返回表的列表。所以在你的情况下,splitter是你迭代的表的列表,然后在框架中附加一个空的列表。我建议你跳过那部分。您正在为各个框架添加不同的元素。因此,您可以将拆分表添加到dataframeX,但dataframeX可能永远不会使用,因为您从未使用next_pagesPageTemplate。为此,您必须在完成第一页后添加NextPageTemplate()到故事中。我会让platypus为你做这些事情:让你的方法返回带有生成元素的列表并连接它们,然后将它们传递给doc.build()

+0

非常感谢您的回答!现在我可以看到我的方式是错误的,而且你说得对,现在我可以看到,如你所说,我在框架中添加了一个空列表。明天我会尝试优化这段代码。 非常感谢! –