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

通过Acrobat COM接口用Python为PDF添加页脚(AddWatermarkFromText)

编辑补充:我已找到解决方案,详见下方内容。

原帖内容

我可以通过以下VBA代码为PDF添加页脚:

Dim PDDocDestination As Object
Dim JSO As Object
Dim i As Long, numPages As Long

Set PDDocDestination = CreateObject("AcroExch.PDDoc")

Set JSO = PDDocDestination.GetJSObject
numPages = PDDocDestination.GetNumPages

' Loop through each page and add the footer
For i = 1 To numPages
    JSO.addWatermarkFromText cText:="text", cFont:="CenturyGothic", nFontSize:=7, nHorizAlign:=1, nVertAlign:=4, nVertValue:=12.5, nStart:=i - 1, nEnd:=i - 1
Next i

'Save destination (merged) PDF
PDDocDestination.Save PDSaveFull, mergedPDF
PDDocDestination.Close

'Cleanup
Set PDDocDestination = Nothing
Set JSO = Nothing

然而,当我尝试将这段代码转换为Python版本时,调用addWatermarkFromText方法时出现错误:pywintypes.com_error: (-2147467263, 'Not implemented', None, None)。我尝试了各种可能的写法,以下是我的Python代码:

def add_footer_to_pdf(pdf_path, output_path, text, font="CenturyGothic", font_size=7, horiz_align=1, vert_align=4, vert_value=12.5):
    # Create COM object to interact with Acrobat
    try:
        AcroApp = Dispatch("AcroExch.App")
        AcroPDDoc = Dispatch("AcroExch.PDDoc")
        AcroPDDoc.Open(pdf_path)
        JSO = AcroPDDoc.GetJSObject()
        num_pages = AcroPDDoc.GetNumPages()

        # Loop through each page and add the footer
        for i in range(num_pages):
            JSO.addWatermarkFromText(cText=f"{text}, page {i+1}", cFont=font, nFontSize=font_size, nHorizAlign=horiz_align, nVertAlign=vert_align, nVertValue=vert_value, nStart=i, nEnd=i)

        # Save the modified PDF
        AcroPDDoc.Save(1, output_path)
        # if not AcroPDDoc.Save(1, output_path):
        #     print("Failed to save the PDF")
    finally:
        AcroPDDoc.Close()
        AcroApp.Exit()
        del AcroApp, AcroPDDoc

我不确定是否因为该方法无法通过pywin32/win32com调用,但既然VBA中可用,理论上Python也应该支持。我检查过PDDoc对象初始化和文档打开都没问题——AcroPDDoc.GetNumPages()能返回正确页数。尝试过带/不带参数、带/不带括号、调整方法名首字母大小写,都无效。


解决方案

问题根源是Python的win32com在处理Acrobat JS方法的命名参数时存在兼容问题,改用位置参数传递即可解决。修正后的代码如下:

def add_footer_to_pdf(pdf_path, output_path, text, font="CenturyGothic", font_size=7, horiz_align=1, vert_align=4, vert_value=12.5):
    try:
        AcroApp = Dispatch("AcroExch.App")
        AcroPDDoc = Dispatch("AcroExch.PDDoc")
        if not AcroPDDoc.Open(pdf_path):
            print("无法打开目标PDF文件")
            return
        
        JSO = AcroPDDoc.GetJSObject()
        if JSO is None:
            print("无法获取Acrobat JS对象,请确认安装了Acrobat Pro(Reader不支持编辑操作)")
            return
            
        num_pages = AcroPDDoc.GetNumPages()

        # 按位置顺序传递参数,避免命名参数的兼容问题
        for i in range(num_pages):
            JSO.addWatermarkFromText(
                f"{text}, page {i+1}",  # cText
                font_size,              # nFontSize
                horiz_align,            # nHorizAlign
                vert_align,             # nVertAlign
                vert_value,             # nVertValue
                font,                   # cFont
                i,                      # nStart
                i                       # nEnd
            )

        # 保存修改后的PDF(1对应PDSaveFull常量)
        if not AcroPDDoc.Save(1, output_path):
            print("保存PDF文件失败")
    finally:
        # 确保资源正确释放
        if 'AcroPDDoc' in locals() and AcroPDDoc.IsOpen():
            AcroPDDoc.Close()
        if 'AcroApp' in locals():
            AcroApp.Exit()
            del AcroApp, AcroPDDoc

额外注意事项:

  • 必须使用Acrobat Pro,Acrobat Reader不支持JS编辑PDF的功能
  • 调用GetJSObject()后务必检查返回值,避免后续空对象调用报错
  • 增加文件打开、保存的状态检查,提升代码容错性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:39:52