简体   繁体   English

如何使用 pyfpdf 生成目录?

[英]How to generate table of contents using pyfpdf?

I hope you'r doing fine.我希望你一切都好。

I want to generate a PDF using pyfpdf.我想使用 pyfpdf 生成 PDF。

I need to generate a table of contents on the first page.我需要在第一页上生成一个目录。

As you know, new pages are created at the end of the PDF.如您所知,在 PDF 的末尾会创建新页面。 So, my table of content is generated at the end of the PDF.所以,我的目录是在 PDF 的末尾生成的。

I can't generate the table of contents at the start of the process because it contains links to go the pages.我无法在流程开始时生成目录,因为它包含指向 go 页面的链接。 To do that i need to know what are the pages number so i need to generate all other page before the table of contents.为此,我需要知道页码是多少,因此我需要在目录之前生成所有其他页面。

To do that, I tried to create a blank page at the beginning and then create other pages and finally return to the first page to add the table of contents.为此,我尝试在开始时创建一个空白页面,然后创建其他页面,最后返回第一页添加目录。 But the first page is still blank...但是第一页还是空白……

from fpdf import FPDF
from datetime import date

today = date.today()
today = today.strftime("%Y/%m/%d")

hardwareModel = ["hardwareModel1", "hardwareModel2", "hardwareModel3"]
snapshotNumber = ["N13100","N13101","N13102"]
firmwareVersion = ["1.8.0","1.8.1","1.8.2"]
websiteVersion = ["2.4.0","2.4.0","2.4.0"]
unifiedPackage = ["#38-20220624","#39-20220701","#40-20220829"]
stageDatabaseVersion = ["4.3.12","4.3.13","4.3.13"]
dateArray = ["2022/06/24","2022/07/01",today]

tableOfContents = []

class PDF(FPDF):
    def __init__(self):
        super().__init__()
        self.currentIndex = -1
        
    def titlePage(self, redScale, greenScale, blueScale, string):
        pdf.set_text_color(redScale, greenScale, blueScale)
        #Title
        self.cell(0, 10, txt = string , align = "L")
        self.drawLine(128, 196, 28, 1, 10, 50, 200, 50)

    def drawLine(self, redScale, greenScale, blueScale, lineWidth, x1, y1, x2, y2):
        pdf.set_draw_color(redScale, greenScale, blueScale)
        pdf.set_line_width(lineWidth)
        pdf.line(x1, y1, x2, y2)
    
    def tableOfContentsGenerator(self):
        self.page = 1
        print(self.page_no())
        self.set_y(0)
        self.set_text_color(0, 0, 0)
        print(self.get_y())
        self.ln(50)
        print(self.get_y())
        for elem in tableOfContents:
            newLink = self.add_link()
            self.set_link(newLink,y=0.0,page=elem[0])
            self.cell(0,10,elem[1],link=newLink)
            self.ln(5)
        
    def header(self):
        if self.currentIndex > -1 and self.currentIndex <= len(snapshotNumber)-1:
            tableOfContents.append((pdf.page_no(), hardwareModel[self.currentIndex] + "_" + snapshotNumber[self.currentIndex] + " (" + dateArray[self.currentIndex] + ")"))
            self.image('image.jpg', 0 , 0 , 210)
            pdf.set_font("helvetica", size = 20)
            self.ln(30)
            self.titlePage(0, 84, 136, hardwareModel[self.currentIndex] + "_" + str(snapshotNumber[self.currentIndex]) + " (" + today + ")")
            if self.currentIndex == len(snapshotNumber)-1:
                self.tableOfContentsGenerator()
        elif self.currentIndex == -1:
            pass
            
        self.currentIndex += 1

pdf = PDF()

pdf.set_title("titleTest")

pdf.add_page()
for elem in snapshotNumber:
    pdf.add_page()

pdf.output("test.pdf")

Any help would be much appreciated.任何帮助将非常感激。

Best regards此致

This can easily be done with fpdf2 :这可以通过fpdf2轻松完成:

from fpdf import FPDF, TitleStyle


def p(pdf, text, **kwargs):
    "Inserts a paragraph"
    pdf.multi_cell(
        w=pdf.epw,
        h=pdf.font_size,
        txt=text,
        new_x="LMARGIN",
        new_y="NEXT",
        **kwargs,
    )

def render_toc(pdf, outline):
    pdf.y += 50
    pdf.set_font("Helvetica", size=16)
    pdf.underline = True
    p(pdf, "Table of contents:")
    pdf.underline = False
    pdf.y += 20
    pdf.set_font("Courier", size=12)
    for section in outline:
        link = pdf.add_link()
        pdf.set_link(link, page=section.page_number)
        p(pdf, f'{" " * section.level * 2} {section.name} {"." * (60 - section.level*2 - len(section.name))} {section.page_number}', align="C", link=link)

pdf = FPDF()
pdf.set_font("Helvetica")
pdf.set_section_title_styles(
    # Level 0 titles:
    TitleStyle(
        font_family="Times",
        font_style="B",
        font_size_pt=24,
        color=128,
        underline=True,
        t_margin=10,
        l_margin=10,
        b_margin=0,
    ),
)
pdf.add_page()
pdf.set_y(50)
pdf.set_font(size=40)
p(pdf, "Doc Title", align="C")
pdf.set_font(size=12)
pdf.insert_toc_placeholder(render_toc)
for i in range(10):
    pdf.start_section(f"Title {i}")
    p(pdf, "Lorem ipsum dolor sit amet, consectetur adipiscing elit,"
           " sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
pdf.output("toc-example.pdf")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM