Python PDF模板添加克罗地亚语特殊字符显示异常求助
Hey there! I’ve dealt with this exact frustration before—those black boxes popping up for Croatian diacritics are such a pain. The root issue here is that the default font used by ReportLab’s canvas (Helvetica) doesn’t support Central European extended characters like č, ć, š, ž, đ. Let’s walk through the fix step by step.
Core Problem
ReportLab’s default Helvetica font only includes basic ASCII characters. When you try to draw text with characters outside that set, the renderer can’t find matching glyphs, so it replaces them with black boxes. Your earlier attempts with UTF-8 encoding don’t help because the problem isn’t with string encoding—it’s with font support.
Step-by-Step Solution
1. Use a Font That Supports Croatian Characters
You need to load a TrueType (TTF) font that includes Central European glyphs. Common options include:
- Arial (preinstalled on Windows/macOS)
- Times New Roman
- Liberation Sans (open-source, cross-platform)
- DejaVu Sans (another open-source option)
First, import the necessary modules to register the font:
from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont
Then register your chosen font. You’ll need to provide the font name (for reference in your code) and the full path to the TTF file on your system:
# macOS example path for Arial pdfmetrics.registerFont(TTFont('Arial', '/Library/Fonts/Arial.ttf')) # Windows example path # pdfmetrics.registerFont(TTFont('Arial', 'C:/Windows/Fonts/arial.ttf')) # Linux example (if you have msttcorefonts installed) # pdfmetrics.registerFont(TTFont('Arial', '/usr/share/fonts/truetype/msttcorefonts/Arial.ttf'))
2. Set the Registered Font in Your Canvas
Before drawing text, tell the canvas to use your registered font instead of the default:
can.setFont('Arial', 12) # 12 is the font size—adjust as needed can.drawString(100, 100, "Kopačka")
3. Remove Unnecessary Encoding
Your earlier attempt to encode the string with .encode('utf-8') was counterproductive—ReportLab’s drawString expects a Python Unicode string, not a byte string. Stick with the raw string like "Kopačka" and let the font handle the glyph rendering.
Full Working Example
Here’s a complete code snippet putting it all together:
import io from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from PyPDF2 import PdfReader, PdfWriter # Use PdfReader/PdfWriter for newer PyPDF2 versions from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont # Register the font (update path to match your system) pdfmetrics.registerFont(TTFont('Arial', '/Library/Fonts/Arial.ttf')) # Create the text overlay packet = io.BytesIO() can = canvas.Canvas(packet, pagesize=A4) # Set the font and draw text with Croatian diacritics can.setFont('Arial', 12) can.drawString(100, 100, "Kopačka") can.drawString(100, 80, "Čačak, Šibenik, Županja, Đakovo") # Test more characters can.save() # Reset packet to read from the start packet.seek(0) new_pdf = PdfReader(packet) # Merge with your template PDF template = PdfReader(open("your_template.pdf", "rb")) output = PdfWriter() # Merge the first page of the overlay with the first page of the template page = template.pages[0] page.merge_page(new_pdf.pages[0]) output.add_page(page) # Save the final PDF with open("output_with_diacritics.pdf", "wb") as f: output.write(f)
Additional Notes
- If you don’t have access to system fonts, download an open-source font like Liberation Sans, place it in your project directory, and use a relative path (e.g.,
./fonts/LiberationSans-Regular.ttf). - For newer PyPDF2 versions, note that
PdfFileReader/PdfFileWriterare deprecated—usePdfReaderandPdfWriterinstead (as shown in the example). - Double-check that your font path is correct—incorrect paths will fall back to the default font, bringing back the black boxes.
Give this a try, and those Croatian diacritics should display perfectly instead of those annoying black boxes!
内容的提问来源于stack exchange,提问作者William Grey

