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

PyPDF2 PageObject无drawText属性报错,PDF翻译器开发遇阻

解决PyPDF2中'PageObject'没有'drawText'属性的问题

问题重现

运行PDF翻译器代码时出现以下错误:

Traceback (most recent call last):
File "c:\Users\Geovane\Desktop\TranslatePDF\translate_pdf.py", line 71, in translate_pdf
translated_page.drawText(10, 10, translated_page_text)
AttributeError: 'PageObject' object has no attribute 'drawText'

原代码如下:

import sys
import PyPDF2
from time import sleep
from PySide6 import QtWidgets
from googletrans import Translator

class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PDF Translator")
        self.resize(400, 200)

        self.select_pdf_button = QtWidgets.QPushButton("Selecionar PDF")
        self.select_pdf_button.clicked.connect(self.select_pdf)

        self.languages_combo = QtWidgets.QComboBox()
        self.languages_combo.addItem("Inglês", "en")
        self.languages_combo.addItem("Português", "pt")
        self.languages_combo.addItem("Espanhol", "es")

        self.translate_button = QtWidgets.QPushButton("Traduzir")
        self.translate_button.clicked.connect(self.translate_pdf)
        self.translate_button.setEnabled(False)

        self.progress_bar = QtWidgets.QProgressBar()
        self.progress_bar.setRange(0, 100)
        self.progress_bar.hide()

        # Criar o layout
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.select_pdf_button)
        layout.addWidget(self.languages_combo)
        layout.addWidget(self.translate_button)
        layout.addWidget(self.progress_bar)

        self.pdf_path = ""

    def select_pdf(self):
        file_dialog = QtWidgets.QFileDialog()
        file_dialog.setNameFilter("PDF (*.pdf)")
        if file_dialog.exec_():
            self.pdf_path = file_dialog.selectedFiles()[0]
            self.translate_button.setEnabled(True)

    def translate_pdf(self):
        dest_language, ok_pressed = QtWidgets.QInputDialog.getItem(
            window,
            "Selecionar idioma",
            "Idioma destino:",
            ["pt", "en", "es"],
            0,
            False
        )

        if ok_pressed:
            translator = Translator()

            with open(self.pdf_path, 'rb') as pdf_file:
                pdf_reader = PyPDF2.PdfReader(pdf_file)
                pdf_writer = PyPDF2.PdfWriter()

                for page_num in range(len(pdf_reader.pages)):
                    page = pdf_reader.pages[page_num]
                    page_text = page.extract_text()

                    translated_page_text = translator.translate(page_text, dest=dest_language).text

                    translated_page = PyPDF2.PageObject.create_blank_page(pdf_writer, width=page.mediabox.width, height=page.mediabox.height)

                    translated_page.merge_page(page)
                    translated_page.drawText(10, 10, translated_page_text)

                    pdf_writer.addPage(translated_page)

                new_file_path, _ = QtWidgets.QFileDialog.getSaveFileName(window, "Salvar PDF", "", "PDF (*.pdf)")

                if new_file_path:
                    with open(new_file_path, 'wb') as new_file:
                        pdf_writer.write(new_file)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

问题原因

PyPDF2的PageObject类并没有drawText方法,它仅支持PDF的拆分、合并、页面提取等基础操作,无法直接在页面上绘制文本。要实现添加文本的功能,需要使用专门的PDF绘图库,比如PyMuPDF(fitz)。

解决方案

1. 安装依赖库

执行以下命令安装所需依赖:

pip install pymupdf googletrans==4.0.0-rc1

注:指定googletrans版本是为了避免最新版本的兼容性问题

2. 修改代码使用PyMuPDF处理文本绘制

替换原代码中的translate_pdf方法,使用PyMuPDF完成PDF读取、文本提取、翻译文本绘制的流程:

修改后的完整代码:

import sys
import fitz  # PyMuPDF
from PySide6 import QtWidgets
from googletrans import Translator

class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PDF Translator")
        self.resize(400, 200)

        self.select_pdf_button = QtWidgets.QPushButton("Selecionar PDF")
        self.select_pdf_button.clicked.connect(self.select_pdf)

        self.languages_combo = QtWidgets.QComboBox()
        self.languages_combo.addItem("Inglês", "en")
        self.languages_combo.addItem("Português", "pt")
        self.languages_combo.addItem("Espanhol", "es")

        self.translate_button = QtWidgets.QPushButton("Traduzir")
        self.translate_button.clicked.connect(self.translate_pdf)
        self.translate_button.setEnabled(False)

        self.progress_bar = QtWidgets.QProgressBar()
        self.progress_bar.setRange(0, 100)
        self.progress_bar.hide()

        # Criar o layout
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.select_pdf_button)
        layout.addWidget(self.languages_combo)
        layout.addWidget(self.translate_button)
        layout.addWidget(self.progress_bar)

        self.pdf_path = ""

    def select_pdf(self):
        file_dialog = QtWidgets.QFileDialog()
        file_dialog.setNameFilter("PDF (*.pdf)")
        if file_dialog.exec_():
            self.pdf_path = file_dialog.selectedFiles()[0]
            self.translate_button.setEnabled(True)

    def translate_pdf(self):
        dest_language, ok_pressed = QtWidgets.QInputDialog.getItem(
            self,
            "Selecionar idioma",
            "Idioma destino:",
            ["pt", "en", "es"],
            0,
            False
        )

        if not ok_pressed:
            return

        translator = Translator()
        # 使用PyMuPDF打开PDF文件
        doc = fitz.open(self.pdf_path)
        
        # 遍历每一页处理
        for page_num in range(len(doc)):
            page = doc[page_num]
            page_text = page.get_text()
            
            if not page_text:
                continue
            
            # 翻译提取到的文本
            translated_page_text = translator.translate(page_text, dest=dest_language).text
            
            # 设置文本绘制参数:字体、字号、起始位置
            font = fitz.Font("helv")
            font_size = 12
            line_height = font_size * 1.2
            # 从页面底部往上100px开始绘制文本,避免覆盖原内容
            start_y = page.rect.height - 100 - (len(translated_page_text.splitlines()) * line_height)
            
            # 逐行绘制翻译后的文本
            current_y = start_y
            for line in translated_page_text.splitlines():
                if current_y < 20:
                    break
                page.insert_text((20, current_y), line, fontsize=font_size, font=font, color=(0,0,0))
                current_y += line_height
        
        # 保存翻译后的PDF
        new_file_path, _ = QtWidgets.QFileDialog.getSaveFileName(self, "Salvar PDF", "", "PDF (*.pdf)")
        if new_file_path:
            doc.save(new_file_path)
            doc.close()
            QtWidgets.QMessageBox.information(self, "Sucesso", "PDF traduzido com sucesso!")

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

代码说明

  • 使用fitz.open替代PyPDF2读取PDF,文本提取更准确
  • 通过page.get_text()提取页面内容,page.insert_text()绘制翻译后的文本,支持自定义字体、字号、颜色和位置
  • 文本绘制在页面底部区域,避免覆盖原PDF内容
  • 新增翻译成功提示,提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:20:25