You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Tkinter文本框内容导出为PDF文件 出现latin-1编码报错

问题描述

实现Tkinter文本框内容导出为PDF功能时,运行代码抛出Unicode编码错误,相关代码与报错信息如下:

功能实现代码

from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkinter.filedialog import askopenfile
from tkinter.filedialog import * 
from fpdf import FPDF

def export(self):
    pdf = FPDF()
    pdf.add_page()
    pdf.set_font("Arial", size=15)
    pdf.cell(40, 10, self.agreemanttext.get("1.0", END).strip())
    pdf.output(asksaveasfilename(filetypes=[("PDF file", "*.pdf")]), "F")


def agreemnttext(self):
    self.buying_agreementsample_cash ="""text"""
    self.agreemanttextframe = Frame(self.agreemantpage, width=900, height=900)
    self.agreemanttextframe.place(x=1, y=40)
    self.agreemanttext = Text(self.agreemanttextframe, width=124, height=57)
    self.agreemanttext.pack()
    self.agreemanttext.tag_configure('tag-center', justify='right')
    self.agreemanttext.insert('end', self.buying_agreementsample_cash, 'tag-center')
    self.agreemanttext.config(state='disabled')

    self.exportbutton=Button(self.agreemantpage,text="export as pdf",command=self.export)
    self.exportbutton.place(x=80,y=600)

报错信息

p = self.pages[n].encode("latin1") if PY3K else self.pages[n]
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 50-54: ordinal not in range(256)
故障原因
  • 旧版fpdf库默认使用latin-1(ISO-8859-1)编码,仅支持编码值在0-255区间的西欧拉丁字符,无法识别中文、特殊符号等超出该范围的Unicode字符
  • 代码中调用的内置Arial字体没有嵌入对应非拉丁字符的字形,遇到超出编码范围的字符时直接抛出编码错误
  • 代码使用cell()方法渲染文本,该方法不支持自动换行,长文本会直接溢出页面边界
修复步骤
  1. 卸载旧版fpdf,安装支持Unicode的维护分支fpdf2,API完全兼容原有代码:
    pip uninstall fpdf -y
    pip install fpdf2
    
  2. 准备支持目标文本字符集的TTF格式字体文件(比如导出中文可使用思源黑体、系统自带的宋体/微软雅黑等)
  3. 修改导出函数逻辑:加载自定义字体、替换cell()为支持自动换行的multi_cell()、增加保存路径非空判断避免用户取消时报错,修改后的参考代码:
    def export(self):
        pdf = FPDF()
        pdf.add_page()
        # 加载本地TTF字体,参数依次为:自定义字体名、字体样式、字体文件本地路径
        pdf.add_font("CustomFont", "", "msyh.ttc") # 此处以微软雅黑字体为例,可替换为自己的字体文件路径
        pdf.set_font("CustomFont", size=15)
        # 获取文本框内容
        content = self.agreemanttext.get("1.0", END).strip()
        # multi_cell第一个参数设为0表示占满页面可用宽度,自动换行
        pdf.multi_cell(0, 10, content)
        save_path = asksaveasfilename(defaultextension=".pdf", filetypes=[("PDF file", "*.pdf")])
        # 用户点击取消时save_path为空,不执行保存避免报错
        if save_path:
            pdf.output(save_path, "F")
    

注意:不要依赖fpdf内置的Helvetica、Arial等字体,这类字体均为latin-1编码的西文字体,无法渲染中文等非拉丁字符,必须手动加载支持对应语言的TTF字体文件。

内容的提问来源于stack exchange,提问作者asaad kittaneh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 06:42:34