Posts: 1
Threads: 1
Joined: Jul 2025
Jul-29-2025, 03:49 PM
(This post was last modified: Jul-29-2025, 03:57 PM by deanhystad.)
Can someone help with this? I just need to generate a stupid pdf I asked chat gpt to make and I'm researching for about two hours and I just can't figure out how to make this code work. If anyone can generate the pdf and annex it below I would appreciate. Thank you!
from fpdf import FPDF
class PDF(FPDF):
def header(self):
# Header with Unicode font for full emoji/text support
self.set_font("NotoEmoji", size=16)
self.cell(0, 10, "Nutrição Proativa", ln=True, align="C")
self.set_font("NotoEmoji", size=12)
self.cell(0, 10, "Plano Alimentar - 2400 kcal", ln=True, align="C")
self.ln(5)
def add_divider(self):
self.set_draw_color(220, 220, 220)
self.set_line_width(0.3)
self.line(10, self.get_y(), 200, self.get_y())
self.ln(5)
def add_meal(self, emoji, title, ingredients, totals):
self.set_fill_color(235, 235, 235)
self.set_font("NotoEmoji", size=13)
self.cell(0, 10, f"{emoji} {title}", ln=True, fill=True)
self.set_font("NotoEmoji", size=11)
for item in ingredients:
self.cell(0, 8, f"- {item}", ln=True)
self.set_text_color(90, 90, 90)
self.cell(0, 8, f"Total: {totals}", ln=True)
self.set_text_color(0, 0, 0)
self.ln(3)
self.add_divider()
# Create PDF instance
pdf = PDF()
pdf.add_page()
pdf.set_auto_page_break(auto=True, margin=15)
# Register and use Noto Color Emoji font
pdf.add_font("NotoEmoji", "", "fonts/NotoColorEmoji.ttf", uni=True)
# Meals
pdf.add_meal("☕", "Café da Manhã",
["Calorias: 809 kcal",
"Carboidratos: 117 g",
"Proteínas: 53,4 g",
"Gorduras: 2,6 g"],
"809 kcal | 117 C | 53,4 P | 2,6 G")
pdf.add_meal("🍽️", "Almoço",
["130g arroz cozido",
"140g frango cozido",
"100g feijão cozido",
"100g cenoura crua",
"5g azeite de oliva"],
"556 kcal | 60,5 C | 52,4 P | 9,96 G")
pdf.add_meal("🍌", "Lanche da Tarde",
["100g banana",
"30g whey 100%",
"170g iogurte grego 0%",
"15g nozes"],
"413 kcal | 42,7 C | 38 P | 11 G")
pdf.add_meal("🍲", "Jantar",
["130g arroz cozido",
"120g guisado de patinho",
"100g beterraba",
"5g azeite de oliva"],
"517 kcal | 46,5 C | 47,9 P | 14,1 G")
pdf.add_meal("🥚", "Ceia Extra",
["2 ovos cozidos",
"100g batata doce",
"200ml leite desnatado"],
"275 kcal | 28,9 C | 18,4 P | 9,7 G")
# Summary
pdf.set_font("NotoEmoji", size=13)
pdf.cell(0, 10, "\n📊 Resumo Final", ln=True)
pdf.set_font("NotoEmoji", size=11)
pdf.cell(0, 8, "Total Calorias: 2400 kcal", ln=True)
pdf.cell(0, 8, "Carboidratos: 239,6 g (meta: 240 g)", ln=True)
pdf.cell(0, 8, "Proteínas: 209,1 g (meta: 210 g)", ln=True)
pdf.cell(0, 8, "Gorduras: 66,96 g (meta: 67 g)", ln=True)
# Output PDF
pdf.output("Plano_Alimentar_2400kcal.pdf")
Posts: 6,981
Threads: 22
Joined: Feb 2020
What OS are you running on? What version of python?
What version of FPDF are you using? FPDF is still available on PYPI, but hasn't been maintained for 10 years. If you are using python 3, make sure you installed FPDF2. I also had to install lxml or I get an error calling pdf.output()
Did you have the NotoColorEmoji.ttf font on your computer? Is it saved in the fonts folder? Is the name correct? I couldn't find a font named NotoColorEmoji, so I downloaded a font named NotoColorEmoji-Regular.ttf. When I run your program (with the font name changed) I get errors that the font is missing several glyphs.
I also got a lot of depreciation warnings, indications that the code you are using as a reference is old.
Posts: 1,301
Threads: 151
Joined: Jul 2017
I would advise using reportlab, because of the total control over every aspect reportlab gives you. Also, there are many webpages which offer advice and tutorials.
Download and read reportlab-userguide.pdf
Starting on page 52 is advice about ttf fonts. I think reportlab comes with about 14 ttf fonts, like Times Roman and Vera.
But you can import any font you want to use.
Here is a simple function to create a pdf using reportlab.
can.showPage() ends the page and creates a new page.
# read the reportlab docs
# long but worth it to control every aspect when creating PDFs
from reportlab.pdfgen import canvas # a page or pages
from reportlab.lib.pagesizes import A4 # page size can be anything custom or standard
from reportlab.pdfbase.ttfonts import TTFont # path to fonts
from reportlab.pdfbase import pdfmetrics # font stuff
from reportlab.lib.units import mm # units to use default is 1/72"
from reportlab.lib.colors import pink, green, brown, white, black
import os
# the chinese font to use
# important for getting a Chinese ttf
fontpath = '/home/peterr/.local/share/fonts/'
ttfFile = os.path.join(fontpath, '1611909670779565.ttf')
ttfFile2 = os.path.join(fontpath, 'DroidSansFallback__.ttf')
pdfmetrics.registerFont(TTFont("Chinese", ttfFile))
pdfmetrics.registerFont(TTFont("Droid", ttfFile2))
def create_pdf():
pdf_file = '/home/peterr/pdfs/multipage.pdf'
can = canvas.Canvas(pdf_file, pagesize=A4)
can.setTitle("My PDF") # shown in PDF window
can.setFont('Chinese', 20)
can.drawString(20, 800, "First Page 第一页")
can.showPage() # ends the page and creates a new page
can.setFont('Times-Roman', 20)
can.drawString(20, 800, "Second Page")
can.setFont('Chinese', 20)
can.drawString(40, 700, "第二页")
can.showPage()
can.setFont('Times-Roman', 20)
can.drawString(20, 700, "Third Page")
can.setFont('Droid', 20)
can.drawString(40, 600, "第三页")
can.showPage()
can.save()
create_pdf()pymupdf is also very good!
Posts: 1,301
Threads: 151
Joined: Jul 2017
I remembered I had this little function to show the built-in fonts. This function is adapted from the user guide.
It makes a little pdf showing the fonts.
def available_fonts():
pdf_file = '/home/peterr/pdfs/available_fonts.pdf'
can = canvas.Canvas(pdf_file, pagesize=A4)
from reportlab.lib.units import inch
text = "Now is the time for all good men to..."
x = 1.8*inch
y = 10.7*inch
for font in can.getAvailableFonts():
can.setFont(font, 10)
can.drawString(x,y,text)
can.setFont("Helvetica", 10)
can.drawRightString(x-10,y, font+":")
y = y-13
can.showPage()
can.save()If you use one of these fonts, you don't need to import anything.
Gribouillis likes this post
Posts: 4,904
Threads: 79
Joined: Jan 2018
(Jul-29-2025, 11:45 PM)Pedroski55 Wrote: I remembered I had this little function to show the built-in fonts. This function is adapted from the user guide.
It makes a little pdf showing the fonts. I turned your function into a full script to generate the pdf from the command line
# availablefonts.py
from argparse import ArgumentParser
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import inch
import sys
def create_available_fonts(ofile):
"""Create pdf file showing available reportlab's pdfgen Canvas fonts
"""
can = canvas.Canvas(ofile, pagesize=A4)
text = "Now is the time for all good men to..."
x = 1.8*inch
y = 10.7*inch
for font in can.getAvailableFonts():
can.setFont(font, 10)
can.drawString(x,y,text)
can.setFont("Helvetica", 10)
can.drawRightString(x-10,y, font+":")
y = y-13
can.showPage()
can.save()
if __name__ == '__main__':
parser = ArgumentParser(
description="Create pdf file showing available reportlab's pdfgen Canvas fonts")
parser.add_argument('-o', '--output', dest='ofile', type=str, default='', help="Output file. Defaults to standard output")
ns = parser.parse_args()
if not ns.ofile:
ns.ofile = sys.stdout.buffer
create_available_fonts(ns.ofile)However the result shows that there are few available fonts: Courier, Helvetica, Times and their bold/italic/oblique... versions plus Symbol and ZapfDingbats which give nothing usable for me.
I'm more inclined to generate Pdf from Python by generating LaTeX source from Python and using the pdflatex command. The choice probably depends on your needs.
Pedroski55 likes this post
« We can solve any problem by introducing an extra level of indirection »
Posts: 7,431
Threads: 125
Joined: Sep 2016
I find easier to first make a page HTML and CSS,when happy with design, fonts,images...ect
Then convert to pdf,eg in Python can use pdfkit
Or better is some cases just use the browser eg Chrome from command line.
chrome --headless --disable-gpu --print-to-pdf=land_page.pdf land_page.html # need wkhtmltopdf in OS path
import pdfkit
pdfkit.from_file(
"land_page.html",
"land_page.pdf",
options={"enable-local-file-access": None}
)
Gribouillis likes this post
Posts: 232
Threads: 0
Joined: Jun 2019
(Jul-30-2025, 07:18 AM)Gribouillis Wrote: However the result shows that there are few available fonts: Courier, Helvetica, Times and their bold/italic/oblique... versions plus Symbol and ZapfDingbats which give nothing usable for me. It's been a while since I used ReportLab, but as far as I can recall it is somewhere mentioned in the ReportLab docs that these five fonts are the bare minimum of the PDF spec. Which means that a PDF generated with these fonts (or their equivalents on other platforms - I think e.g. Windows uses Arial instead of Helvetica?) will be display on every platform correctly without the need for embedding the fonts in the PDF.
Of course other fonts can be used, but need to be embedded in the PDF if it should be ensured that the PDF is displayed correctly on all platforms.
Regards, noisefloor
Posts: 1,301
Threads: 151
Joined: Jul 2017
The difficult bit for me is getting the emojis printed in the pdf! Still working on that, if anyone has a good idea, please let me know!
I downloaded NotoColorEmoji.ttf but I can't register it in reportlab, get an error. Any tips??
from reportlab.pdfgen import canvas # a page or pages
from reportlab.lib.pagesizes import A4 # page size can be anything custom or standard
from reportlab.pdfbase.ttfonts import TTFont # path to fonts
from reportlab.pdfbase import pdfmetrics # font stuff
from reportlab.lib.units import mm, inch # units to use default is 1/72"
from reportlab.lib.colors import pink, green, brown, white, black
import os
fontpath = '/home/peterr/.local/share/fonts/'
ttfFile = os.path.join(fontpath, 'NotoColorEmoji.ttf')
pdfmetrics.registerFont(TTFont("tofu", ttfFile))The error is:
Output: Traceback (most recent call last):
File "/usr/lib/python3.12/idlelib/run.py", line 580, in runcode
exec(code, self.locals)
File "<pyshell#10>", line 1, in <module>
File "/home/peterr/PVE/GPE/lib/python3.12/site-packages/reportlab/pdfbase/ttfonts.py", line 1207, in __init__
self.face = TTFontFace(filename, validate=validate, subfontIndex=subfontIndex)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peterr/PVE/GPE/lib/python3.12/site-packages/reportlab/pdfbase/ttfonts.py", line 1088, in __init__
TTFontFile.__init__(self, filename, validate=validate, subfontIndex=subfontIndex)
File "/home/peterr/PVE/GPE/lib/python3.12/site-packages/reportlab/pdfbase/ttfonts.py", line 448, in __init__
self.extractInfo(charInfo)
File "/home/peterr/PVE/GPE/lib/python3.12/site-packages/reportlab/pdfbase/ttfonts.py", line 869, in extractInfo
if 'loca' not in self.table: raise TTFError('missing location table')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
reportlab.pdfbase.ttfonts.TTFError: missing location table
In Libre Office writer I can put the emojis from NotoColorEmoji.ttf in a document using: Insert --> Special character
I can write emojis to a text file like this:
file = '/home/peterr/temp/emoji.txt'
with open(file, 'a') as outfile:
outfile.write('\n\U0001f603')Symbola.ttf can be imported into reportlab.
There is a list of all emoji codes here.
Posts: 232
Threads: 0
Joined: Jun 2019
Looking at https://github.com/rst2pdf/rst2pdf/issues/986 it may well be that ReportLab still does not support fonts having emojis?
Regards, noisefloor
Posts: 7,431
Threads: 125
Joined: Sep 2016
Jul-31-2025, 01:58 PM
(This post was last modified: Jul-31-2025, 01:58 PM by snippsat.)
(Jul-31-2025, 12:07 AM)Pedroski55 Wrote: he difficult bit for me is getting the emojis printed in the pdf! Still working on that, if anyone has a good idea, please let me know! As i mention make it html first,then convert to pdf,here i just use chrome.exe from command line to convert to pdf.
Example output emo1.pdf.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Emoji Boost 🚀</title>
<!-- Tailwind CSS CDN -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
<style>
/* Ensure emoji size consistency */
.emoji { font-size: 1.4rem; line-height: 1; }
</style>
</head>
<body class="bg-gradient-to-b from-white to-blue-50 text-gray-900 antialiased">
<!-- Hero -->
<header class="py-16">
<div class="max-w-4xl mx-auto px-6 text-center">
<h1 class="text-5xl font-extrabold mb-4">Emoji Boost <span class="emoji">🚀✨</span></h1>
<p class="text-lg mb-6">Make your content pop with emotions, clarity, and charm. Quick setup, beautiful style, zero fluff.</p>
<div class="flex justify-center gap-4">
<a href="#features" class="inline-block bg-blue-600 text-white px-7 py-3 rounded-full shadow hover:bg-blue-700 transition">
See Features <span class="emoji">🔍</span>
</a>
<a href="#signup" class="inline-block border border-blue-600 text-blue-600 px-7 py-3 rounded-full hover:bg-blue-50 transition">
Get Started <span class="emoji">🎉</span>
</a>
</div>
</div>
</header>
<!-- Features -->
<section id="features" class="py-16">
<div class="max-w-5xl mx-auto px-6">
<h2 class="text-3xl font-bold text-center mb-10">Features that spark joy <span class="emoji">🔥💡</span></h2>
<div class="grid gap-8 md:grid-cols-3">
<div class="bg-white p-6 rounded-xl shadow hover:shadow-lg transition">
<div class="flex items-center mb-4">
<div class="text-3xl mr-3">📝</div>
<h3 class="text-xl font-semibold">Smart Notes</h3>
</div>
<p class="text-sm">Capture ideas with emoji tags, auto summaries, and quick access. Everything feels alive. <span class="emoji">🧠✨</span></p>
</div>
<div class="bg-white p-6 rounded-xl shadow hover:shadow-lg transition">
<div class="flex items-center mb-4">
<div class="text-3xl mr-3">📊</div>
<h3 class="text-xl font-semibold">Live Insights</h3>
</div>
<p class="text-sm">Visualize progress, trends, and goals with friendly emoji cues. Stay motivated. <span class="emoji">📈😄</span></p>
</div>
<div class="bg-white p-6 rounded-xl shadow hover:shadow-lg transition">
<div class="flex items-center mb-4">
<div class="text-3xl mr-3">🤝</div>
<h3 class="text-xl font-semibold">Team Sync</h3>
</div>
<p class="text-sm">Collaborate in real time, react with emojis, and keep everyone in the loop. <span class="emoji">👥🔁</span></p>
</div>
</div>
</div>
</section>
<!-- Testimonials -->
<section class="bg-blue-50 py-16">
<div class="max-w-4xl mx-auto px-6">
<h2 class="text-3xl font-bold text-center mb-10">Loved by early users <span class="emoji">❤️</span></h2>
<div class="space-y-8">
<div class="bg-white p-6 rounded-lg shadow flex gap-4">
<div class="text-4xl">🌟</div>
<div>
<p class="italic">“Emoji Boost made our weekly reports feel human. Stakeholders actually smile now.”</p>
<p class="mt-2 font-semibold">— Lena Sørensen, Ops Lead</p>
</div>
</div>
<div class="bg-white p-6 rounded-lg shadow flex gap-4">
<div class="text-4xl">🎯</div>
<div>
<p class="italic">“The emoji tagging and summary snippets cut my review time in half.”</p>
<p class="mt-2 font-semibold">— Marcus Lee, Product Designer</p>
</div>
</div>
</div>
</div>
</section>
<!-- Call to Action -->
<section id="signup" class="py-16">
<div class="max-w-3xl mx-auto px-6 text-center">
<h2 class="text-2xl font-bold mb-4">Ready to add personality to your workflow? <span class="emoji">🎨🚀</span></h2>
<p class="mb-6">Sign up today for free and get your first emoji-enhanced dashboard in seconds.</p>
<a href="#" class="inline-block bg-green-500 text-white px-8 py-3 rounded-full shadow hover:bg-green-600 transition">
Start Free <span class="emoji">✅</span>
</a>
</div>
</section>
<!-- Footer -->
<footer class="mt-20 bg-white border-t">
<div class="max-w-4xl mx-auto px-6 py-8 flex flex-col md:flex-row justify-between items-center text-sm text-gray-600">
<div class="mb-4 md:mb-0">© 2025 Emoji Boost</div>
<div class="flex gap-4">
<a href="#" class="hover:underline">Privacy Policy</a>
<a href="#" class="hover:underline">Terms</a>
<a href="#" class="hover:underline">Contact</a>
</div>
</div>
</footer>
</body>
</html>
|