【问题标题】:Header and footer creation in versions before 0.8.8在 0.8.8 之前的版本中创建页眉和页脚
【发布时间】:2018-11-18 22:39:09
【问题描述】:

是否有在 Microsoft Word (docx) 文件中添加页眉和页脚的解决方法?

这些在python-docx之前0.8.8的版本中没有实现。

更具体地说,我想补充一点:

  1. 页码到页脚
  2. 一些随机文本到标题

理想的代码如下所示:

from docx import Document

document = Document()

# Add header and footer on all pages

document.save("demo.docx")

【问题讨论】:

    标签: python python-3.x header footer python-docx


    【解决方案1】:

    它不是最优雅的(它需要您在 VBA 和 Python 之间导航),但您可以使用 win32com 库来利用 MS Word 功能。这当然需要安装了 MS Office 的 Windows 机器。

    import win32com.client as win32
    msword = win32.gencache.EnsureDispatch('Word.Application')
    doc = msword.Documents.Add
    doc.Sections(1).Footers(1).Range.Text = r'Text to be included'
    doc.Sections(1).Footers(1).PageNumbers.Add()
    

    【讨论】:

    • 如何将它链接到由 python docx api 创建的文档
    • 啊。所以你希望代码使用 docx Document 对象工作?
    【解决方案2】:

    您可以使用的一种解决方法是利用在 Word 中创建的模板文档。创建一个空白文档,添加带有所需文本的任何标题和带有页码的页脚并保存文档。然后使用:

    from docx import Document
    document = Document("template.docx")
    # Do your editing
    document.save("demo.docx")
    

    ...您应该能够在保留页眉和页脚的同时编辑其他所有内容。

    最终我认为这个解决方案非常适合页码问题。如果您需要每个文档的唯一标题文本,事情可能会变得有点棘手。如果是这种情况,您可能想尝试直接编辑 docx 文件的 XML。您可以在终端中使用它:

    unzip template.docx
    

    ... 将 docx XML 文件吐出到目录中。你也可以在 python 中使用 zipfile 来做:

    import zipfile
    
    document = zipfile.ZipFile("template.docx")
    for xml in document.filelist:
        if "header" in xml.filename:
            read = document.read(xml.filename)
            print(read.decode())
    

    print 语句会打印整个 XML 文件,但是你应该可以找到这个花絮:

    <w:r><w:t>ThisIsMyHeader</w:t></w:r>
    

    这将是您标题中的文本。您所要做的就是编辑 XML 文件,将文件重新组合在一起,然后将文件类型更改回 docx。

    这显然是一个超级 hacky 的解决方法,不幸的是我无法让它完全工作,但如果你绝对需要它,它至少会是朝着正确方向迈出的一大步。

    祝你好运!

    【讨论】:

    • 试过模板的东西。这种方法的问题是无法识别表格和段落的样式,这给了我错误:KeyError: u"no style with name 'Heading 1'"
    • 不幸的是,我对存档格式的 docx 文件的了解非常有限,因此我不确定是否有解决方法。希望对这个过程有更多了解的其他人可以加入并更全面地回答。对不起:(。
    【解决方案3】:

    模板方法有效,其主要优势在于它是一个真正的跨平台解决方案。但是,它要求一个样式已经在文档中应用过一次

    让我们考虑来自python-docx 的玩具示例的(简化)版本 documentation page.

    第一步涉及创建模板文档:

    from docx import Document
    
    document = Document()
    
    document.add_heading('Document Title', 0)
    
    p = document.add_paragraph('A plain paragraph having some ')
    p.add_run('bold').bold = True
    p.add_run(' and some ')
    p.add_run('italic.').italic = True
    
    document.add_heading('Heading, level 1', level=1)
    document.add_paragraph('Intense quote', style='IntenseQuote')
    
    document.add_paragraph(
        'first item in unordered list', style='ListBullet'
    )
    document.add_paragraph(
        'first item in ordered list', style='ListNumber'
    )
    
    document.save('demo.docx')
    

    (请注意,您也可以在第一步中手动应用样式,而无需使用 python-docx,即在 Word 中。)

    接下来,您在 Microsoft Word 中打开此 demo.docx,您可以:

    1. 添加所需的标题
    2. 从菜单中插入页码
    3. 保存文档

    完成上述操作后,您只需删除demo.docx 文档的主要内容(但不删除页眉和页脚的内容!)并再次保存文件。

    在第二步中,使用python-docx 调用demo.docx 进行所需的更改:

    from docx import Document
    
    document = Document('demo.docx')
    
    document.add_heading('A New Title for my Document', 0)
    
    p = document.add_paragraph('A new paragraph having some plain ')
    p.add_run('bold').bold = True
    p.add_run(' and some ')
    p.add_run('italic.').italic = True
    
    document.add_heading('New Heading, level 1', level=1)
    document.add_paragraph('Intense quote', style='IntenseQuote')
    
    document.add_paragraph(
        'first new item in unordered list', style='ListBullet'
    )
    document.add_paragraph(
        'first new item in ordered list', style='ListNumber'
    )
    
    document.save('demo.docx')
    

    您甚至可以添加更多内容,例如具有现有表格样式的表格:

    from docx import Document
    
    document = Document('demo.docx')
    
    document.add_page_break()
    
    recordset = [ [1, "101", "Spam"], [2, "42", "Eggs"], [3, "631", "Spam, spam, eggs, and spam"]]
    
    table = document.add_table(rows=1, cols=3)
    hdr_cells = table.rows[0].cells
    hdr_cells[0].text = 'Qty'
    hdr_cells[1].text = 'Id'
    hdr_cells[2].text = 'Desc'
    
    for item in recordset:
        row_cells = table.add_row().cells
        row_cells[0].text = str(item[0])
        row_cells[1].text = str(item[1])
        row_cells[2].text = item[2]
    
    table.style = 'ColorfulShading'
    
    document.save('demo.docx')
    

    当然,可以避免一直重复第一步,通过copying the customized file 然后在那里进行必要的更改(例如demo_copy.docx)而不影响模板:

    import shutil
    shutil.copyfile('demo.docx', 'demo_copy.docx')
    

    最后值得一提的是,您还可以使用自定义样式!有关如何使用python-docx 和表格样式see here 执行此操作的示例。

    【讨论】:

      【解决方案4】:

      这样的事情怎么样(感谢 Eliot K)

      from docx import Document
      import win32com.client as win32
      import os.path
      import tempfile
      
      tempdir = tempfile.gettempdir()
      msword = win32.gencache.EnsureDispatch('Word.Application')
      tempfile = os.path.join(tempdir, "temp.doc")
      
      document = Document()
      
      document.save(tempfile)
      
      doc = msword.Documents.Open(tempfile)
      
      doc.Sections(1).Footers(1).Range.Text = r'Text to be included'
      doc.Sections(1).Footers(1).PageNumbers.Add()
      doc.SaveAs(tempfile, FileFormat = 0)
      
      document = Document(tempfile)
      

      也许不是最优雅的方法,但应该做你需要的。 也许将丑陋的保存/加载代码隔离在代码尘土飞扬的角落某处的函数中;-)

      同样,确实需要安装了 microsoft office 的 windows 机器。

      祝你好运!

      【讨论】:

        【解决方案5】:

        我一直用它来工作

        from docx import Document
        document = Document()
        
        header = document.sections[0].header
        header.add_paragraph('Test Header') 
        
        header = document.sections[0].footer
        header.add_paragraph('Test Footers')
        

        https://python-docx.readthedocs.io/en/latest/dev/analysis/features/header.html

        【讨论】:

        • 您的答案有两个问题:1) 所描述的步骤无法在 0.8.8 之前的版本中完成;2) 它没有提供关于如何按照 OP 要求插入页码的解决方案。
        猜你喜欢
        • 1970-01-01
        • 2011-12-24
        • 2011-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-12
        • 2019-02-13
        相关资源
        最近更新 更多