gpt4 book ai didi

python-3.x - Reportlab:将自定义参数传递给 Canvas

转载 作者:行者123 更新时间:2023-12-02 17:10:48 26 4
gpt4 key购买 nike

我正在使用 Python 开发报告生成器。到目前为止一切顺利,除了一个细节:我需要向报告添加自定义页脚。由于我还添加了更多元素,我需要使用自定义 Canvas 对象来构建报告,我认为应该可以将此自定义页脚添加到 Canvas 类中......但到目前为止我没有成功.

这是我一直在写的代码:

导入:

from reportlab.pdfgen import canvas
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.pagesizes import letter
from reportlab.lib.enums import TA_JUSTIFY

自定义 Canvas 类:

class CustomCanvas(canvas.Canvas):
"""
Adapted from http://code.activestate.com/recipes/576832/
"""
def __init__(self, *args, **kwargs):
canvas.Canvas.__init__(self, *args, **kwargs)
self._saved_page_states = []
# I'd like to pass the custom footer text to the constructor
# to draw it at the footer for each page. This is a fragment of
# text that will be read from a database
if 'customFooterText' in kwargs:
self.customFooter = kwargs['customFooterText']
else:
self.customFooter = 'Missing custom footer text :('

def showPage(self):
self._saved_page_states.append(dict(self.__dict__))
self._startPage()

def drawPageNumber(self, page_count):
self.setFont('Helvetica', 8)
self.drawRightString(21 * cm, 1 * cm,
'%s / %s' % (self._pageNumber, page_count))

def drawCustomFooter(self):
"""
Here is where I'd like to draw the custom footer.
"""
self.setFont('Helvetica', 8)
self.drawString(1 * cm, 1 * cm, self.customFooter)

def save(self):
num_pages = len(self._saved_page_states)
for state in self._saved_page_states:
self.__dict__.update(state)
self.drawPageNumber(num_pages)
self.drawCustomFooter()
canvas.Canvas.showPage(self)
canvas.Canvas.save(self)

我的报告生成器:

class MyReport:
def __init__(self):
self.filename = 'test.pdf'
self.doc = SimpleDocTemplate(self.filename, pagesize=letter,
topMargin = 1 * cm, bottomMargin = 2 * cm,
leftMargin = 1 * cm, rightMargin = 1 * cm)
self.Story = []

def generateReport(self):
self.reportContent()
self.doc.build(self.Story, canvasmaker=CustomCanvas)
# Here is the issue: How to pass the kwarg to the CustomCanvas
# class so it can be drawn in each page?

def reportContent(self):
# In the "real life", this content will be generated with data from
# a database.
styles = getSampleStyleSheet()
styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
justify = styles['Justify']
txt = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas tristique cursus enim at luctus. Proin tincidunt,
arcu vitae mattis pretium, lorem eros semper lectus,
venenatis luctus orci odio rhoncus nunc. Nam nulla arcu,
hendrerit at lacinia eget, gravida aliquam quam. Mauris
finibus ipsum at leo ullamcorper, ut faucibus est eleifend.
Maecenas vehicula malesuada tempor. Nulla et augue a purus
luctus tincidunt. Nam consectetur ut diam sit amet efficitur.
Morbi a volutpat orci. Donec id ipsum ut quam hendrerit gravida.
Nulla gravida, ante non euismod fermentum, metus nulla ullamcorper
sem, ut feugiat ipsum felis sit amet lectus.
"""
for i in range(15):
self.Story.append(Paragraph(txt, justify))

测试

report = MyReport()
report.generateReport()

创建报告时,第一页如下所示:

enter image description here

因此,问题是:如何使用 CustomCanvas 类中的 kwarg 将该字符串添加到每个页面?

最佳答案

我找到了一种方法来做我需要的...我单独留下自定义 Canvas 并使用 onFirstPageonLaterPages 参数来包含我的自定义页脚(我不我不在乎在哪里指定了自定义页脚字符串,只要我可以在运行时指定它即可)。

我的解决方案:

导入:

from reportlab.pdfgen import canvas
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.pagesizes import letter
from reportlab.lib.enums import TA_JUSTIFY

自定义 Canvas 类:

我单独留下了 Custom Canvas 类。它做它需要做的事情:

class CustomCanvas(canvas.Canvas):
"""
Adapted from http://code.activestate.com/recipes/576832/
"""
def __init__(self, *args, **kwargs):
canvas.Canvas.__init__(self, *args, **kwargs)
self._saved_page_states = []

def showPage(self):
self._saved_page_states.append(dict(self.__dict__))
self._startPage()

def drawPageNumber(self, page_count):
self.setFont('Helvetica', 8)
self.drawRightString(21 * cm, 1 * cm,
'%s / %s' % (self._pageNumber, page_count))
def save(self):
num_pages = len(self._saved_page_states)
for state in self._saved_page_states:
self.__dict__.update(state)
self.drawPageNumber(num_pages)
canvas.Canvas.showPage(self)
canvas.Canvas.save(self)

我的报告生成器:

我在这里添加了我的 **kwargs 参数,这样我就可以传递带有页脚文本的自定义参数:

class MyReport:
def __init__(self, *args, **kwargs):
self.filename = 'test.pdf'
self.doc = SimpleDocTemplate(self.filename, pagesize=letter,
topMargin = 1 * cm, bottomMargin = 2 * cm,
leftMargin = 1 * cm, rightMargin = 1 * cm)
if 'left_footer' in kwargs:
self.left_footer = kwargs['left_footer']
else:
self.left_footer = None
self.Story = []

def onMyFirstPage(self, canvas, doc):
# If the left_footer attribute is not None, then add it to the page
canvas.saveState()
if self.left_footer is not None:
canvas.setFont('Helvetica', 8)
canvas.drawString(1 * cm, 1 * cm, self.left_footer)
canvas.restoreState()

def onMyLaterPages(self, canvas, doc):
# If the left_footer attribute is not None, then add it to the page
canvas.saveState()
if self.left_footer is not None:
canvas.setFont('Helvetica', 8)
canvas.drawString(1 * cm, 1 * cm, self.left_footer)
canvas.restoreState()

def generateReport(self):
self.reportContent()
self.doc.build(self.Story, canvasmaker=CustomCanvas,
onFirstPage=self.onMyFirstPage,
onLaterPages=self.onMyLaterPages)

def reportContent(self):
styles = getSampleStyleSheet()
styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
justify = styles['Justify']
txt = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas tristique cursus enim at luctus. Proin tincidunt,
arcu vitae mattis pretium, lorem eros semper lectus,
venenatis luctus orci odio rhoncus nunc. Nam nulla arcu,
hendrerit at lacinia eget, gravida aliquam quam. Mauris
finibus ipsum at leo ullamcorper, ut faucibus est eleifend.
Maecenas vehicula malesuada tempor. Nulla et augue a purus
luctus tincidunt. Nam consectetur ut diam sit amet efficitur.
Morbi a volutpat orci. Donec id ipsum ut quam hendrerit gravida.
Nulla gravida, ante non euismod fermentum, metus nulla ullamcorper
sem, ut feugiat ipsum felis sit amet lectus.
"""
for i in range(15):
self.Story.append(Paragraph(txt, justify))

测试

report = MyReport(left_footer='A custom test footer for my pages')
# I can now specify my custom footer in runtime!
report.generateReport()

现在我发现它是如此简单,我觉得有点傻。
但我将此留给后代,以防有人需要做类似的事情。

无论如何,如果其他人有更好的解决方案,请添加您的答案。

关于python-3.x - Reportlab:将自定义参数传递给 Canvas,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49344094/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com