【发布时间】:2014-04-03 05:49:17
【问题描述】:
我正在尝试将“全角”表格拆分为 2 页甚至更多页。我使用 ReportLab 的 Platypus 库和 BaseDocTemplate 类。
我有一个“全宽”元素表,它应该被绘制到第一页的框架中,如果表有足够的行它应该在第二页继续。我的问题是第一页的框架与其他框架的高度和位置不同,因为在第一页的顶部我需要显示更多信息(是的......我在谈论发票或订单)。
经过数千次尝试,我得到的只是一个 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)
提前谢谢你!!
【问题讨论】:
标签: python django pdf-generation reportlab