如何获取 pdf 的页码并分配给 ReportLab 中的表格,Python

问题描述 投票:0回答:2

我正在使用 Python 中的 ReportLab 编写 PDF 生成脚本。该脚本生成一个包含客户端表和一些附加信息的 PDF。我已经实现了一个自定义 PageNumCanvas 类来处理页码。(PageNumCanvas 来自 https://www.blog.pythonlibrary.org/2013/08/12/reportlab-how-to-add-page-numbers/

这是PageNumCanvas。我覆盖(在保存方法中)第一页以将页面号添加到固定位置。

但是我需要在客户端表中动态加载 page_count。

class PageNumCanvas(canvas.Canvas):
    """
    http://code.activestate.com/recipes/546511-page-x-of-y-with-reportlab/
    http://code.activestate.com/recipes/576832/

    This below code is taken from the 
    https://www.blog.pythonlibrary.org/2013/08/12/reportlab-how-to-add-page-numbers/
    """
    #----------------------------------------------------------------------
    def __init__(self, *args, **kwargs):
        """Constructor"""
        canvas.Canvas.__init__(self, *args, **kwargs)
        self.pages = []
        
    #----------------------------------------------------------------------
    def showPage(self):
        """
        On a page break, add information to the list
        """
        self.pages.append(dict(self.__dict__))
        self._startPage()
        
    #----------------------------------------------------------------------
    def save(self):
        """
        Add the page number to each page (page x of y)
        """
        page_count = len(self.pages)
        self.__dict__.update(self.pages[0])
        self.setFont("Helvetica", 9)
        self.drawRightString(270, 679, str(page_count))
        for page in self.pages:
            self.__dict__.update(page)
            self.draw_page_number(page_count)
            canvas.Canvas.showPage(self)
            
        canvas.Canvas.save(self)
        
    #----------------------------------------------------------------------
    def draw_page_number(self, page_count):
        """
        Add the page number
        """
        page = "Page %s of %s" % (self._pageNumber, page_count)
        self.setFont("Helvetica", 9)
        self.drawRightString(200*mm, 20*mm, page)

class YourPdfClass:
    def __init__(self):
        pass
    def header(self, canvas, doc):
           pass
    def write_pdf_lines(self, columns_fields, file_path):

        pdf_filename = file_path
        pdf_document = SimpleDocTemplate(pdf_filename, pagesize=letter
                                         )

        # Calculate the available width within the margins
        available_width = pdf_document.width
        styless = getSampleStyleSheet()
        client_data=client_data = [
                [
                    Paragraph(f"Client: <b>{x}</b>", styless['Normal']),
                    Paragraph(f"Downloaded By: <b>{y}</b>", styless['Normal']),
                    Paragraph(f"Date and Time: <b>{05-Jan-2024, 03:20 pm}</b>", styless['Normal'])
                ],
                [
                    Paragraph(f"Records: <b>{z}</b>", styless['Normal']),
                    Paragraph("Pages:{}", styless['Normal']),
                    ""
                ]
]

        client_table=Table(client_data,
                        #    colWidths=[available_width / 3] * 3,
                           spaceBefore=10)
        # Build the PDF document
        print("we started making pdf")
        pdf_document.build([client_table],canvasmaker=PageNumCanvas)

    def save(self):
        """
        Add the page number to each page (page x of y)
        """
        page_count = len(self.pages)
        self.__dict__.update(self.pages[0])
        self.setFont("Helvetica", 9)
        self.drawRightString(270, 679, str(page_count))
        for page in self.pages:
            self.__dict__.update(page)
            self.draw_page_number(page_count)
            canvas.Canvas.showPage(self)
            
        canvas.Canvas.save(self)

这会将数据加载到固定位置。但是如果其他字段的动态值很大的话,它就会变大,所以看起来会像错位了。

任何关于为什么会发生这种情况的见解以及修复它的建议将不胜感激。谢谢!

python django pdf-generation reportlab
2个回答
0
投票

早上好,Rishikumar 希望你一切都好,伙计。

这会将数据加载到固定位置。但是如果其他字段的动态值很大的话,它就会变大,所以看起来会像错位了。

您可以调整表格大小或使用文本换行吗?

我最近使用 ReportLab 为我的一个项目设置 PDF 样式,似乎面临着无穷无尽的问题。我只看一页和样式。该项目已在我的 github 上结束,仍处于开发阶段,但 PDF 样式很好。


0
投票

好的,抱歉,让我们再试一次。

我们渲染文档但不保存它并使用 PageNumCanvas 来计算页数怎么样?此时我们知道页数,我们可以更新具有页数的单元格重新渲染文档。

使用了 {{TOTAL_PAGES}}

因此更改 client_data:

client_data = [
# ... (other rows)
[
    Paragraph(f"Records: <b>{z}</b>", styless['Normal']),
    Paragraph("Pages: <b>{{TOTAL_PAGES}}</b>", styless['Normal']),  
    ""
]

]

和:

def write_pdf_lines(self, columns_fields, file_path):
     (your existing code to set up the document and table)

# First Pass: Render the document to count pages
pdf_document.build([client_table], canvasmaker=PageNumCanvas)

# Get the total pages from your PageNumCanvas instance
page_count = len(self.pages)

# Update the placeholder in the client_data
for row in client_data:
    for i, cell in enumerate(row):
        if isinstance(cell, Paragraph):
            text = cell.text
            # Replace placeholder with actual page count
            if "{{TOTAL_PAGES}}" in text:
                row[i] = Paragraph(text.replace("{{TOTAL_PAGES}}", 
                  str(page_count)), styless['Normal'])

# Second Pass: Re-render the document with the updated page count
pdf_document.build([client_table], canvasmaker=PageNumCanvas)

让我知道你过得怎么样。很抱歉回复晚了,我经常外出工作。祝你好运:)

© www.soinside.com 2019 - 2024. All rights reserved.