Python调用google.cloud做PDF英译中时如何将protobuff.repeated结果写入PDF
Google Cloud翻译protobuf结果写入中文PDF实现
核心前置处理:解析protobuf.repeated类型翻译结果
Google Cloud翻译API返回的repeated结构是可迭代的protobuf容器对象,不能直接作为字符串传入PDF写入接口,先按顺序提取翻译后的纯中文文本:
# 假设response是调用translate_text后拿到的接口响应对象 zh_content_list = [] for single_trans in response.translations: # 单条翻译结果存放在translated_text属性中 zh_content_list.append(single_trans.translated_text)
注意:必须保证提取原PDF文本块的顺序、传入翻译接口的文本顺序、接口返回翻译结果的顺序三者完全一致,否则写入后会出现内容错位。
依赖安装
选择对中文支持友好的PDF操作库,推荐用pymupdf(导入名为fitz)做原PDF排版替换,排版还原度远高于其他库:
pip install pymupdf
如果需要从零生成新PDF,搭配安装reportlab即可。
写入方案1:原PDF位置覆盖替换(保留原排版)
如果你在提取原PDF内容时,同步记录了每个文本块的页码、坐标范围、原字号信息,直接对应位置覆盖写入中文即可,这是效果最接近原版PDF的方案:
import fitz # 打开原始英文PDF src_pdf = fitz.open("input_en.pdf") # 替换为本地中文字体路径:Windows系统参考 C:/Windows/Fonts/msyh.ttc(微软雅黑),Mac参考 /System/Library/Fonts/PingFang.ttc(苹方),Linux可以放任意开源中文字体ttf/ttc文件 zh_font_path = "your_local_chinese_font.ttc" # 假设origin_blocks是你之前提取原PDF时存储的文本块列表,每个元素包含page_num(页码,从0开始)、bbox(fitz.Rect类型的坐标框)、font_size(原文本字号) # 顺序必须和zh_content_list一一对应 for idx, block in enumerate(origin_blocks): page = src_pdf[block["page_num"]] # 先用白色矩形覆盖原位置的英文内容 page.draw_rect(block["bbox"], color=(1, 1, 1), fill=(1, 1, 1)) # 写入对应翻译文本,中文比英文占宽高,字号缩小15%避免溢出 page.insert_text( point=block["bbox"].tl, # 原文本框左上角坐标 text=zh_content_list[idx], fontname="zh_font", fontfile=zh_font_path, fontsize=block["font_size"] * 0.85, color=(0, 0, 0) ) # 保存翻译后的中文PDF src_pdf.save("output_zh.pdf") src_pdf.close()
写入方案2:全新生成中文PDF(无需保留原排版)
如果不需要还原原PDF的复杂版式,直接把翻译好的文本按顺序写入新PDF即可:
from reportlab.pdfgen import canvas from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont # 注册中文字体 zh_font_path = "your_local_chinese_font.ttc" pdfmetrics.registerFont(TTFont("zh_font", zh_font_path)) # 初始化PDF画布 new_pdf = canvas.Canvas("output_zh.pdf") page_w, page_h = new_pdf._pagesize margin = 50 line_gap = 22 cur_y = page_h - margin new_pdf.setFont("zh_font", 12) for para in zh_content_list: # 自动换行+自动分页逻辑 while para: # 计算当前行能放下的最大文本长度 for split_pos in range(len(para), 0, -1): line_text = para[:split_pos] line_w = new_pdf.stringWidth(line_text, "zh_font", 12) if line_w <= page_w - 2*margin: new_pdf.drawString(margin, cur_y, line_text) cur_y -= line_gap para = para[split_pos:] # 触底新建页面 if cur_y < margin: new_pdf.showPage() new_pdf.setFont("zh_font", 12) cur_y = page_h - margin break new_pdf.save()
常见问题排查
- 写入后中文显示方块/乱码:没有加载本地中文字体,库默认西文字体不支持中文字符渲染,必须手动指定中文字体路径
- 内容错位:检查三个顺序是否一致:原文本提取顺序、翻译请求传入顺序、翻译结果返回顺序
- 文本超出页面边界:中文视觉宽度大于英文,可适当缩小字号,或增加自动换行截断逻辑
- protobuf取值报错:不要直接对repeated对象做str()强转,必须遍历每个元素取
translated_text属性值
内容的提问来源于stack exchange,提问作者blackang
相关产品推荐
相关产品推荐

