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

Python Reportlab中拉丁字符čćžšđ显示乱码如何解决

核心问题定位

你遇到的乱码由两个直接错误导致:

  1. 多余的手动编码操作:你对非ASCII字符串调用.encode('utf-8')将Unicode字符串转为了bytes类型,Reportlab的Paragraph组件仅接收原生字符串类型输入,传入bytes会触发错误解析,必然生成乱码。
  2. 字体配置失效:你提到更换了OpenSans字体,但大概率没有完成TTF字体的正确注册,也没有在段落、表格样式中强制指定该字体。Reportlab内置的默认字体(Helvetica、Times Roman等)仅支持基础ASCII字符,完全不包含č、ć、ž、š、đ这类东欧拉丁字符的字形,就算内容传入正确也会显示乱码/方块。

问题PDF截图

可直接落地的修复方案

按以下步骤调整代码即可解决问题:

  • 正确注册支持扩展拉丁字符的TTF字体
    不要依赖Reportlab内置的标准字体,提前将你准备好的OpenSans(推荐使用完整版本,或替换为Noto Sans Latin Extended,字符覆盖更稳定)通过TTFont模块注册,同时配置字体族避免加粗/斜体样式回退到默认字体:
    from reportlab.pdfbase import pdfmetrics
    from reportlab.pdfbase.ttfonts import TTFont
    from reportlab.pdfbase.pdfmetrics import registerFontFamily
    
    # 替换为本地字体文件的实际存储路径
    pdfmetrics.registerFont(TTFont('OpenSans', 'OpenSans-Regular.ttf'))
    pdfmetrics.registerFont(TTFont('OpenSans-Bold', 'OpenSans-Bold.ttf'))
    pdfmetrics.registerFont(TTFont('OpenSans-Italic', 'OpenSans-Italic.ttf'))
    pdfmetrics.registerFont(TTFont('OpenSans-BoldItalic', 'OpenSans-BoldItalic.ttf'))
    
    # 注册字体族映射,保证样式切换时不回退
    registerFontFamily(
        'OpenSans',
        normal='OpenSans',
        bold='OpenSans-Bold',
        italic='OpenSans-Italic',
        boldItalic='OpenSans-BoldItalic'
    )
    
  • 修正段落样式,强制指定已注册的字体
    你使用的styleN段落样式必须显式指定fontName为注册时的字体名,注意名称大小写敏感,必须完全匹配:
    from reportlab.lib.styles import ParagraphStyle
    styleN = ParagraphStyle(
        'normal',
        fontName='OpenSans', # 核心配置,不能遗漏
        fontSize=9,
        leading=11, # 行高可根据需求调整
        # 保留你原本配置的其他样式参数即可
    )
    
  • 删除冗余编码逻辑,直接传入原生字符串
    你代码中判断字符是否为ASCII、单独做encode的逻辑完全多余,Python3中字符串默认是Unicode编码,直接传入Paragraph即可,不需要任何手动转码:
    # 替换掉原来带encode判断的列表推导式
    data2 = [[Paragraph(cell, styleN) for cell in row] for row in array]
    
  • 表格样式全局指定字体,避免局部回退
    原TableStyle没有配置全局字体,需要补充FONTNAME规则,避免单元格内容自动回退到默认不支持特殊字符的字体:
    t = Table(
        data2,
        colWidths=[None] + [2.2*inch] + [1.3 * inch]*int(len(json.loads(request.POST['kolone'])) - 2 ),
        rowHeights= [None] + [0.5*inch] + [None] * int(len(array) -2),
        repeatRows=1
    )
    t.setStyle(TableStyle([
        ('FONTNAME', (0,0), (-1,-1), 'OpenSans'), # 全局指定表格字体
        ('TEXTCOLOR',(1,1),(-2,-2), "black"),
        ('FONTSIZE', (0,0),(-1,-1), 9),
        ('BOX', (0,0), (-1,0), 0.25, 'black'),
        ('PADDING', (0,0),(-1,-1), 2),
        ('VALIGN', (0,0), (-1,-1), 'TOP')
    ]))
    
避坑提示
  • 任何情况下都不要给Reportlab的文本组件传入bytes类型内容,所有文本保持Python原生str类型即可,PDF生成时的编码工作由Reportlab内部自动完成,手动编码只会触发解析错误。
  • 如果调整后仍有个别字符无法显示,检查你使用的字体文件是否为精简版,精简版字库常裁剪掉扩展拉丁区字符,替换为完整版字库即可。
  • 注册字体时自定义的字体名(比如示例里的'OpenSans')要和所有样式里的fontName参数完全一致,拼写错误、大小写不匹配都会导致字体配置失效,自动回退到默认字体。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:03:28