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

ReportLab生成PDF:文本对齐、换行及加粗格式问题求助

解决ReportLab生成PDF的文本格式问题

1. 实现文本两端对齐+自动换行不越界

ReportLab的drawString不支持复杂排版,必须用Paragraph组件配合样式来实现两端对齐和自动换行。

步骤:

  1. 导入必要模块,定义两端对齐的样式,设置左右边距避免文本超出页面:
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.platypus import Paragraph
from reportlab.lib.pagesizes import A1

# 定义两端对齐样式,限制左右边距
justified_style = ParagraphStyle(
    name='JustifiedStyle',
    alignment=TA_JUSTIFY,
    leftIndent=20,  # 左页边距
    rightIndent=20, # 右页边距
    fontSize=12,
    leading=15      # 行间距
)
  1. 用Paragraph渲染文本,而非canvas.drawString:
# content为从S3 JSON读取的文本内容
para = Paragraph(content, justified_style)
# 计算可绘制宽度(页面总宽度减去左右边距)
para.wrapOn(canvas, A1[0] - 40, A1[1] - 40)
# 指定起始位置绘制文本
para.drawOn(canvas, 20, 1000)

Paragraph会自动处理换行,确保文本不超出右页边距,同时实现两端对齐。

2. 解析JSON中的\n换行和**加粗标记

ReportLab的Paragraph支持类HTML标记,只需将JSON中的自定义格式转换为它能识别的语法:

写一个格式转换函数:

def format_text(raw_text):
    # 替换**为<b>和</b>,支持多组加粗标记
    formatted = raw_text
    while '**' in formatted:
        formatted = formatted.replace('**', '<b>', 1).replace('**', '</b>', 1)
    # 替换\n为<br/>实现换行
    formatted = formatted.replace('\n', '<br/>')
    return formatted

使用示例:

# 从S3读取的JSON数据
raw_content = json_data.get('content', '')
# 转换格式后再渲染
formatted_content = format_text(raw_content)
para = Paragraph(formatted_content, justified_style)

完整流程示例

import json
import boto3
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.platypus import Paragraph
from reportlab.lib.pagesizes import A1
from reportlab.pdfgen import canvas

# 从S3读取JSON数据
s3 = boto3.client('s3')
response = s3.get_object(Bucket='your-bucket-name', Key='your-file.json')
json_data = json.loads(response['Body'].read().decode('utf-8'))

# 定义标题和内容样式
title_style = ParagraphStyle(
    name='TitleStyle',
    alignment=TA_JUSTIFY,
    leftIndent=20,
    rightIndent=20,
    fontSize=24,
    leading=30,
    fontName='Helvetica-Bold'
)
content_style = ParagraphStyle(
    name='ContentStyle',
    alignment=TA_JUSTIFY,
    leftIndent=20,
    rightIndent=20,
    fontSize=14,
    leading=18,
    fontName='Helvetica'
)

# 格式转换函数
def format_text(raw_text):
    formatted = raw_text
    while '**' in formatted:
        formatted = formatted.replace('**', '<b>', 1).replace('**', '</b>', 1)
    formatted = formatted.replace('\n', '<br/>')
    return formatted

# 创建A1尺寸PDF画布
c = canvas.Canvas('a1_report.pdf', pagesize=A1)
page_width, page_height = A1

# 添加背景图
c.drawImage('background.jpg', 0, 0, width=page_width, height=page_height)

# 渲染标题
formatted_title = format_text(json_data.get('title', ''))
title_para = Paragraph(formatted_title, title_style)
title_para.wrapOn(c, page_width - 40, page_height - 40)
title_para.drawOn(c, 20, page_height - 100)

# 渲染内容
formatted_content = format_text(json_data.get('content', ''))
content_para = Paragraph(formatted_content, content_style)
content_width = page_width - 40
content_height = content_para.wrap(content_width, page_height - 200)[1]
content_para.drawOn(c, 20, page_height - 150 - content_height)

# 保存PDF
c.save()

注意事项

  • 若使用SimpleDocTemplate而非直接操作canvas,只需将Paragraph加入Flowables列表即可,排版逻辑一致。
  • 确保使用的字体支持加粗(如Helvetica-Bold),自定义字体需提前注册。
  • 确保AWS权限足够读取目标S3存储桶和文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 14:49:54