在批量处理 Word 文档时,页眉页脚往往比正文排版更容易出现重复劳动和规则错乱,尤其是封面不显示页眉、双面打印奇偶页位置不同、页码需要随页数变化等场景。本文围绕 Spire.Doc for Python 的对象模型,把常见页眉页脚操作拆成可复用函数,说明文本、图片、页码域、页眉表格以及首页/奇偶页差异化的代码实现和参数注意点。
环境准备
本文示例使用 Spire.Doc for Python,通过 pip 安装:
安装后在脚本中导入模块:
- from spire.doc import *
- from spire.doc.common import *
复制代码
一、页眉页脚中写入文本、图片和页码
页眉通常放文档标题、公司名称或 Logo,页脚多用于页码。该库通过 Section.HeadersFooters.Header 和 Section.HeadersFooters.Footer 分别获取页眉、页脚对象,再向其中添加段落和内容。下面的函数把操作封装起来,便于对多个节复用,同时演示图片、文本、边框和页码域的组合使用:
- def InsertHeaderAndFooter(section):
- header = section.HeadersFooters.Header
- footer = section.HeadersFooters.Footer
- headerParagraph = header.AddParagraph()
- headerPicture = headerParagraph.AppendPicture('Header.png')
- text = headerParagraph.AppendText('添加页眉')
- text.CharacterFormat.FontName = '宋体'
- text.CharacterFormat.FontSize = 10
- text.CharacterFormat.Italic = True
- headerParagraph.Format.HorizontalAlignment = HorizontalAlignment.Right
- headerParagraph.Format.Borders.Bottom.BorderType = BorderStyle.Single
- headerParagraph.Format.Borders.Bottom.Space = 0.05
- headerPicture.TextWrappingStyle = TextWrappingStyle.Behind
- headerPicture.HorizontalOrigin = HorizontalOrigin.Page
- headerPicture.HorizontalAlignment = ShapeHorizontalAlignment.Left
- headerPicture.VerticalOrigin = VerticalOrigin.Page
- headerPicture.VerticalAlignment = ShapeVerticalAlignment.Top
- footerParagraph = footer.AddParagraph()
- footerPicture = footerParagraph.AppendPicture('Footer.png')
- footerPicture.TextWrappingStyle = TextWrappingStyle.Behind
- footerPicture.HorizontalOrigin = HorizontalOrigin.Page
- footerPicture.HorizontalAlignment = ShapeHorizontalAlignment.Left
- footerPicture.VerticalOrigin = VerticalOrigin.Page
- footerPicture.VerticalAlignment = ShapeVerticalAlignment.Bottom
- footerParagraph.AppendText('第 ')
- footerParagraph.AppendField('页码', FieldType.FieldPage)
- footerParagraph.AppendText('页 共 ')
- footerParagraph.AppendField('页数', FieldType.FieldNumPages)
- footerParagraph.AppendText('页')
- footerParagraph.Format.HorizontalAlignment = HorizontalAlignment.Center
- footerParagraph.Format.Borders.Top.BorderType = BorderStyle.Single
- footerParagraph.Format.Borders.Top.Space = 0.05
- document = Document()
- document.LoadFromFile('示例文档.docx')
- section = document.Sections.get_Item(0)
- InsertHeaderAndFooter(section)
- document.SaveToFile('添加页眉页脚.docx', FileFormat.Docx)
- document.Close()
复制代码
这里有两个关键点。第一,页码必须使用域字段 FieldType.FieldPage 与 FieldType.FieldNumPages,不能手动填写固定数字,否则文档页数变化后页码会错位。第二,页眉页脚中的图片通过 HorizontalOrigin.Page 和 VerticalOrigin.Page 以页面为参照定位,配合 TextWrappingStyle.Behind 衬于文字下方,可以避免挤压正文区域。
二、在页眉中插入表格
有些场景需要在页眉放置出版号、日期、文档编号等结构化信息。该库支持直接在页眉中添加表格,行高、单元格对齐方式、背景色都可以逐项设置:
- def InsertTableToHeader(section):
- header = section.HeadersFooters.Header
- tableHeader = header.AddTable(True)
- tableHeader.ResetCells(2, 2)
- data = [['出版号', '日期'], ['SC12546', '2019年7月24日']]
- for i in range(len(data)):
- dataRow = tableHeader.Rows.get_Item(i)
- dataRow.Height = 20
- dataRow.HeightType = TableRowHeightType.Exactly
- dataRow.RowFormat.BackColor = Color.Empty()
- for c in range(len(data[i])):
- dataRow.Cells[c].CellFormat.VerticalAlignment = VerticalAlignment.Middle
- dataRow.Cells[c].CellFormat.HorizontalAlignment = HorizontalAlignment.Center
- range = dataRow.Cells[c].AddParagraph().AppendText(data[i][c])
- range.CharacterFormat.FontName = '宋体'
复制代码
需要注意,页眉表格会占用页眉区域高度。如果表格行数较多,应同步调整 section.PageSetup.HeaderDistance,避免正文被向下推挤。
三、首页不同的处理方式
正式报告常要求封面不显示页眉页脚。将 DifferentFirstPageHeaderFooter 设为 True 后,第一节的第一页会使用独立的 FirstPageHeader 和 FirstPageFooter 容器,其余页面仍然使用常规的 Header 与 Footer:
- section.PageSetup.DifferentFirstPageHeaderFooter = True
- p1 = section.HeadersFooters.FirstPageHeader.AddParagraph()
- p1.Format.HorizontalAlignment = HorizontalAlignment.Left
- r1 = p1.AppendText('首页页眉')
- r1.CharacterFormat.FontName = '宋体'
- r1.CharacterFormat.FontSize = 12
- p2 = section.HeadersFooters.FirstPageFooter.AddParagraph()
- p2.Format.HorizontalAlignment = HorizontalAlignment.Left
- r2 = p2.AppendText('首页页脚')
- r2.CharacterFormat.FontName = '宋体'
- r2.CharacterFormat.FontSize = 12
- p3 = section.HeadersFooters.Header.AddParagraph()
- p3.Format.HorizontalAlignment = HorizontalAlignment.Right
- r3 = p3.AppendText('非首页页眉')
- r3.CharacterFormat.FontName = '微软雅黑'
- r3.CharacterFormat.FontSize = 14
- p4 = section.HeadersFooters.Footer.AddParagraph()
- p4.Format.HorizontalAlignment = HorizontalAlignment.Right
- r4 = p4.AppendText('非首页页脚')
- r4.CharacterFormat.FontName = '微软雅黑'
- r4.CharacterFormat.FontSize = 14
复制代码
开启“首页不同”后,FirstPageHeader 与 FirstPageFooter 是独立对象。只要不向其中添加任何内容,封面就不会显示页眉页脚,无需额外执行清除操作。
四、奇偶页不同的处理方式
双面打印装订时,页码通常要求靠外侧对齐。开启 DifferentOddAndEvenPagesHeaderFooter 后,需要分别操作 OddHeader、OddFooter 与 EvenHeader、EvenFooter。按原文说明,原先设置在 Header / Footer 上的内容只对奇数页生效,偶数页要单独设置 Even 容器:
- section.PageSetup.DifferentOddAndEvenPagesHeaderFooter = True
- P3 = section.HeadersFooters.OddHeader.AddParagraph()
- OH = P3.AppendText('奇数页页眉')
- P3.Format.HorizontalAlignment = HorizontalAlignment.Center
- OH.CharacterFormat.FontName = '微软雅黑'
- OH.CharacterFormat.FontSize = 10
- P2 = section.HeadersFooters.OddFooter.AddParagraph()
- OF = P2.AppendText('奇数页页脚')
- P2.Format.HorizontalAlignment = HorizontalAlignment.Center
- OF.CharacterFormat.FontName = '微软雅黑'
- OF.CharacterFormat.FontSize = 10
- P4 = section.HeadersFooters.EvenHeader.AddParagraph()
- EH = P4.AppendText('偶数页页眉')
- P4.Format.HorizontalAlignment = HorizontalAlignment.Center
- EH.CharacterFormat.FontName = '微软雅黑'
- EH.CharacterFormat.FontSize = 10
- P1 = section.HeadersFooters.EvenFooter.AddParagraph()
- EF = P1.AppendText('偶数页页脚')
- EF.CharacterFormat.FontName = '微软雅黑'
- EF.CharacterFormat.FontSize = 10
- P1.Format.HorizontalAlignment = HorizontalAlignment.Center
复制代码
两个开关可以叠加使用。如果同时开启首页不同与奇偶页不同,需要确保 FirstPageHeader、OddHeader、EvenHeader 三个容器都有明确的处理逻辑,避免某类页面出现空白页眉或残留内容。另外,HeadersFooters 是按节独立管理的,多节文档需要遍历 document.Sections 逐节设置,不能只处理第一节。
五、调整页眉页脚与正文的距离
页眉页脚区域高度由 HeaderDistance 和 FooterDistance 控制,单位为磅(pt)。默认值通常为 36 pt,适合单行小字。如果页眉中放入较高的 Logo 或表格,或者页脚内容较多,正文可能被向下推挤,此时可以适当调小这两个值,让页眉页脚更贴近页面边缘:
- section.PageSetup.HeaderDistance = 30
- section.PageSetup.FooterDistance = 30
复制代码
调整时要注意,HeaderDistance 过小可能导致页眉内容被裁切,建议结合页边距一起考虑。正文的上边距至少应大于页眉距离加上页眉实际高度。
六、实践要点
1. 页码使用 FieldType.FieldPage 与 FieldType.FieldNumPages 域字段,不要写固定数字,避免页数变化后错位。
2. HeadersFooters 按节独立管理,多节文档需遍历 document.Sections 逐节设置,并留意节与节之间是否存在继承关系。
3. 首页不同、奇偶页不同可以叠加,但要分别处理 FirstPageHeader、OddHeader、EvenHeader 等容器,避免出现空白页眉或残留内容。
4. 页眉中放图片或表格时,要同步检查 HeaderDistance 和正文页边距,防止正文被推挤或页眉被裁切。
5. 如果文档结构复杂,建议先在 Word 中理清各节页眉页脚设置状态,再编写脚本,避免代码与文档实际状态不一致。不同文档处理库在页眉页脚对象模型上也有差异,迁移代码时需要留意容器名称和定位方式的对应关系。 |