brunch

You can make anything
by writing

C.S.Lewis

by 이종우 Peter Lee Apr 11. 2023

python으로 text 을 pdf 파일로 저장하기

python으로 text 을 pdf 파일로 저장하기 


Now that you have understood how to lay out a PDF document, let’s fill the cells with some content.


from fpdf import FPDF

pdf = FPDF()


pdf.add_page()

pdf.set_font('Arial', '', 16)

pdf.cell(w=0, h=10, txt="This is regular text.", ln=1)

pdf.set_font('Arial', 'B', 16)

pdf.cell(w=0, h=10, txt="This is bold text.", ln=1)

pdf.set_font('Arial', 'I', 16)

pdf.cell(w=0, h=10, txt="This is italic text.", ln=1)

pdf.set_font('Arial', '', 16) # Reset text back to regular

pdf.cell(w=0, h=10, txt="This is left aligned text.", ln=1,  align='L')

pdf.cell(w=0, h=10, txt="This is center aligned text.", ln=1,  align='C')

pdf.cell(w=0, h=10, txt="This is right aligned text.", ln=1,  align='R')

pdf.set_fill_color(r= 0, g= 128, b = 0)

pdf.cell(w=0, h=10, txt="This is text with filled background.", ln=1,    fill=True)

pdf.set_text_color(r= 0, g= 128, b = 0)

pdf.cell(w=0, h=10, txt="This is colored text.", ln=1)

pdf.output(f'./example.pdf', 'F')







# Margin
m = 10 
# Page width: Width of A4 is 210mm
pw = 210 - 2*MARGIN 
# Cell height
ch = 50pdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', '', 12)pdf.cell(w=0, h=ch, txt="Cell 1", border=1, ln=1)pdf.cell(w=(pw/2), h=ch, txt="Cell 2a", border=1, ln=0)
pdf.cell(w=(pw/2), h=ch, txt="Cell 2b", border=1, ln=1)pdf.cell(w=(pw/3), h=ch, txt="Cell 3a", border=1, ln=0)
pdf.cell(w=(pw/3), h=ch, txt="Cell 3b", border=1, ln=0)
pdf.cell(w=(pw/3), h=ch, txt="Cell 3c", border=1, ln=1)pdf.cell(w=(pw/3), h=ch, txt="Cell 4a", border=1, ln=0)
pdf.cell(w=(pw/3)*2, h=ch, txt="Cell 4b", border=1, ln=1)pdf.set_xy(x=10, y= 220) # or use pdf.ln(50)
pdf.cell(w=0, h=ch, txt="Cell 5", border=1, ln=1)pdf.output(f'./example.pdf', 'F')



Creating a PDF layout with cells (Image by the author)


Header and Footer


You can also specify a header and footer shown on each page in the PDF document. For this, you need to overwrite the 

header()


and


footer()


methods in a custom class. Don’t forget to use an instance of your custom class instead of the


FPDF


class.


# Custom class to overwrite the header and footer methods
class PDF(FPDF):
    def __init__(self):
        super().__init__()
    def header(self):
        self.set_font('Arial', '', 12)
        self.cell(0, 10, 'Header', 1, 1, 'C')
    def footer(self):
        self.set_y(-15)
        self.set_font('Arial', '', 12)
        self.cell(0, 10, 'Footer', 1, 0, 'C')pdf = PDF() # Instance of custom class
pdf.add_page()
pdf.set_font('Arial', '', 12)
pdf.cell(w=0, h=255, txt = "Body", border = 1, ln = 1, align = 'C')pdf.output(f'./example.pdf', 'F')



Header, Body, and Footer of PDF document generated in Python (Image by the author)


How to Add Text to a PDF File


Now that you have understood how to lay out a PDF document, let’s fill the cells with some content.


Styling Text


The 

fpdf


library offers you the basics to style your text:



With the set_font() method, you can set the font, the font size, and the emphasis (regular, bold, italic).


In the cell method, you can define the text alignment with the align parameter.


To fill the background of a cell, you need to define a color with the set_fill_color() method and also define fill = True in the cell() method.


To change the color of a cell’s text, you can define a color with the set_text_color() method.



pdf = FPDF()
pdf.add_page()pdf.set_font('Arial', '', 16)
pdf.cell(w=0, h=10, txt="This is regular text.", ln=1)pdf.set_font('Arial', 'B', 16)
pdf.cell(w=0, h=10, txt="This is bold text.", ln=1)pdf.set_font('Arial', 'I', 16)
pdf.cell(w=0, h=10, txt="This is italic text.", ln=1)pdf.set_font('Arial', '', 16) # Reset text back to regularpdf.cell(w=0, h=10, txt="This is left aligned text.", ln=1,   
         align='L')
pdf.cell(w=0, h=10, txt="This is center aligned text.", ln=1,
         align='C')
pdf.cell(w=0, h=10, txt="This is right aligned text.", ln=1,
         align='R')pdf.set_fill_color(r= 0, g= 128, b = 0)
pdf.cell(w=0, h=10, txt="This is text with filled background.", ln=1,
         fill=True)pdf.set_text_color(r= 0, g= 128, b = 0)
pdf.cell(w=0, h=10, txt="This is colored text.", ln=1)pdf.output(f'./example.pdf', 'F')



Different styles of text in generated PDF: left, center, right alignment, bold and italic text, font and background color (Image by the author)


Line and Page Breaks


If you need a block of longer text, the 

cell()


method is insufficient because it doesn’t allow for line or page breaks, as you can see below.


For this purpose, you should use the 

multi_cell()


method instead, which can handle line and page breaks.


import lorem # Use this package to showcase long textspdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', '', 16)pdf.cell(w=0, h=50, txt="This and the below cells are regular cells." , border=1, ln=1)pdf.cell(w=0, h=50, txt="Example: " + lorem.text(), border=1, ln=1)pdf.multi_cell(w=0, h=50, txt="This and the below cells are multi cells.", border=1, )pdf.multi_cell(w=0, h=5, txt="Example: " + lorem.text(), border=1, )pdf.output(f'./example.pdf', 'F')



Use multi_cells for longer texts with line and page breakes instead of regular cells (Image by the author)


Template


With everything you have learned so far, you can now create a simple template like the one shown below. We will use this for the following examples.


# cell height
ch = 8class PDF(FPDF):
    def __init__(self):
        super().__init__()
    def header(self):
        self.set_font('Arial', '', 12)
        self.cell(0, 8, 'Header', 0, 1, 'C')
    def footer(self):
        self.set_y(-15)
        self.set_font('Arial', '', 12)
        self.cell(0, 8, f'Page {self.page_no()}', 0, 0, 'C')pdf = PDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 24)
pdf.cell(w=0, h=20, txt="Title", ln=1)pdf.set_font('Arial', '', 16)
pdf.cell(w=30, h=ch, txt="Date: ", ln=0)
pdf.cell(w=30, h=ch, txt="01/01/2022", ln=1)
pdf.cell(w=30, h=ch, txt="Author: ", ln=0)
pdf.cell(w=30, h=ch, txt="Max Mustermann", ln=1)pdf.ln(ch)
pdf.multi_cell(w=0, h=5, txt=lorem.paragraph())pdf.ln(ch)
pdf.multi_cell(w=0, h=5, txt=lorem.paragraph())pdf.output(f'./example.pdf', 'F')



PDF template generated in Python (Image by the author)




For the following examples, we will be using a small fictional dataset.


import pandas as pddf = pd.DataFrame(
          {'feature 1' : ['cat 1', 'cat 2', 'cat 3', 'cat 4'],
           'feature 2' : [400, 300, 200, 100]
          })


Fictional dataset imported as pandas DataFrame (Image by the author)


How to Add Matplotlib Plots as Images to a PDF File


Aside from text, you might need to add plots to your PDF report.


To add plots to your PDF report, you first need to save your Matplotlib plots as images (e.g., PNG files).


import matplotlib.pyplot as plt
import seaborn as snsfig, ax = plt.subplots(1,1, figsize = (6, 4))sns.barplot(data =  df, x = 'feature 1', y = 'feature 2')
plt.title("Chart")plt.savefig('./example_chart.png', 
           transparent=False,  
           facecolor='white', 
           bbox_inches="tight")


Matplotlib plot saved as PNG file (Image by the author)


Once your Matplotlib plot is saved as an image, you can add it to the report with the 

image()


method.


pdf = PDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 24)
pdf.cell(w=0, h=20, txt="Title", ln=1)pdf.set_font('Arial', '', 16)
pdf.cell(w=30, h=ch, txt="Date: ", ln=0)
pdf.cell(w=30, h=ch, txt="01/01/2022", ln=1)
pdf.cell(w=30, h=ch, txt="Author: ", ln=0)
pdf.cell(w=30, h=ch, txt="Max Mustermann", ln=1)pdf.ln(ch)
pdf.multi_cell(w=0, h=5, txt=lorem.paragraph())pdf.image('./example_chart.png', 
          x = 10, y = None, w = 100, h = 0, type = 'PNG')pdf.ln(ch)
pdf.multi_cell(w=0, h=5, txt=lorem.paragraph())pdf.output(f'./example.pdf', 'F')



Matplotlib plot added to PDF report in Python (Image by the author)


How to Add a Pandas DataFrame as a Table to a PDF File


Unfortunately, there is no simple way to add a pandas DataFrame to a PDF report with the 

FPDF


library. Although adding a pandas DataFrame as a table to a PDF report requires some light coding, it is not difficult either: By using the


cell()


method with


border=1


and effectively utilizing the


ln


parameter, you can iterate over the DataFrame to create a table.


pdf = PDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 24)
pdf.cell(w=0, h=20, txt="Title", ln=1)pdf.set_font('Arial', '', 16)
pdf.cell(w=30, h=ch, txt="Date: ", ln=0)
pdf.cell(w=30, h=ch, txt="01/01/2022", ln=1)
pdf.cell(w=30, h=ch, txt="Author: ", ln=0)
pdf.cell(w=30, h=ch, txt="Max Mustermann", ln=1)pdf.ln(ch)
pdf.multi_cell(w=0, h=5, txt=lorem.paragraph())pdf.image('./example_chart.png', x = 10, y = None, w = 100, h = 0, type = 'PNG', link = '')pdf.ln(ch)
pdf.multi_cell(w=0, h=5, txt=lorem.paragraph())pdf.ln(ch)# Table Header
pdf.set_font('Arial', 'B', 16)
pdf.cell(w=40, h=ch, txt='Feature 1', border=1, ln=0, align='C')
pdf.cell(w=40, h=ch, txt='Feature 2', border=1, ln=1, align='C')# Table contents
pdf.set_font('Arial', '', 16)
for i in range(0, len(df)):
    pdf.cell(w=40, h=ch, 
             txt=df['feature 1'].iloc[i], 
             border=1, ln=0, align='C')
    pdf.cell(w=40, h=ch, 
             txt=df['feature 2'].iloc[i].astype(str), 
             border=1, ln=1, align='C')pdf.output(f'./example.pdf', 'F')



Pandas DataFrame added to PDF report as a table in Python (Image by the author)


Technically, you could also convert your pandas DataFrame to a Matplotlib table, save it as an image and insert the table as an image to the PDF. But I tried this out, so you don’t have to: It’s not very pretty.


Conclusion


Although critics say there are better alternatives to the 

fpdf


library, it is simple to use.


This article showed you:



How to Create a PDF File: Layout and Placing Text and Header and Footer


How to Add Text to a PDF File: Styling Text and Line and Page Breaks


How to Add Matplotlib Plots as Images to a PDF File


How to Add a Pandas DataFrame as a Table to a PDF File



Below you can copy the template code that generates the following PDF and adjust it for your purposes.







Enjoyed This Story?


If you’d like to get my new stories directly to your inbox, subscribe!


Become a Medium member to read more stories from other writers and me. You can support me by using my referral link when you sign up. I’ll receive a commission at no extra cost to you.


                                                      Join Medium with my referral link — Leonie Monigatti                                          Read every story from Leonie Monigatti (and thousands of other writers on Medium). Your membership fee directly…                                                              medium.com                                                                                                              


Find me on Twitter, LinkedIn, and Kaggle!


References


[1] “FPDF for Python”, “PyFPDF” https://pyfpdf.readthedocs.io/en/latest/ (accessed October 22, 2022)






        Python


        Programming


        Data Visualization


        Tips And Tricks


        Pdf





575














575






매거진의 이전글 [번역]Netflix에서 45만달러 개발자 그만둔 이유
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari