使用 Python 管理 Word 节及页面布局设置
小李盯着刚写完的80页项目报告,眉头拧成一团。前面的章节都是标准纵向排版,但中间有两张数据表实在太宽,放在纵向页面里,字小得得拿放大镜看。他试过把这两页改成横向,结果整个文档都跟着转了,完全乱套。
这其实是Word里一个特别经典的问题。大部分人都在“页面布局”里点来点去,改了一页,后面全跟着变,气得想摔鼠标。秘密就藏在Word的一个核心概念里——节(Section)。
一、你以前的操作,问题出在哪
新建一个Word文档时,它只有一个“节”。你可以把“节”想象成一个容器,这个容器里装着几页纸,这几页纸的页边距、纸张方向、页眉页脚全都一样。平时在一份文档里随便改设置,改的就是整个容器。把第二页改成横向,相当于把这个唯一的容器整个翻转了,后面的页面当然跟着乱套。
想要中间几页与众不同,就得在特殊页面的前后“切一刀”,制造出新的容器。有了三个独立的容器(节),你改中间那个,两头的不会受影响。
二、用Python看见“节”
纸上谈兵没意思,直接上手操作。python-docx就是干这活的利器。
from docx import Document # 打开小李的报告 doc = Document('项目报告.docx') # 看看这个文档里有多少个“容器”(节) print(len(doc.sections)) # 不出意外,打印出来是 1 # 拿到第一个(也是唯一的)节 first_section = doc.sections[0]这段代码就像给文档做了个CT扫描。文档结构一目了然。默认情况下,你永远只有一个节,也就是doc.sections[0]。
三、在你想分页的地方,“切”上一刀
小李需要在第3页后面插入一个横向的大表格。这意味着要在第3页结束的地方,切出一个新节。
from docx import Document from docx.enum.section import WD_SECTION_START doc = Document('项目_report.docx') # 假设文档已经有3页内容了,我们在这后面创建新节 # 注意:add_section() 是在文档末尾追加新节 # 如果你想在中间插入,逻辑稍微不同,但核心是下面这行 new_section = doc.add_section(WD_SECTION_START.NEW_PAGE) # 此时,doc.sections 的长度变成了 2 # sections[0] 是原来的第一页到第三页 # sections[1] 就是我们新建的空节,从新的一页开始add_section()就像一把刀,在文档末尾切出一个独立的新空间。WD_SECTION_START.NEW_PAGE的意思是,切完之后,新节的内容从新的一页开始。
四、给新节“换衣服”
现在有了独立的容器(第二节),怎么改它的设置都不会影响前面的内容。
# 获取第二个节(索引为1) target_section = doc.sections[1] from docx.enum.section import WD_ORIENTATION from docx.shared import Inches # 获取当前纸张的宽高,准备交换(纵向变横向) original_width = target_section.page_width original_height = target_section.page_height # 设置方向为横向 target_section.orientation = WD_ORIENTATION.LANDSCAPE # 交换宽高 target_section.page_width = original_height target_section.page_height = original_width # 再把页边距调窄一点,给大表格腾地方 target_section.left_margin = Inches(0.5) target_section.right_margin = Inches(0.5) doc.save('项目_report_已排版.docx')执行完这段代码,文档中间的这几页就神奇地变成了横向,前后的纵向排版纹丝不动。这就是“节”的魔力。
五、页眉页脚的独立王国
更头疼的是页眉页脚。公司要求封面不能有页码,目录要用罗马数字,正文要用阿拉伯数字从“1”开始。这种需求在没搞懂“节”之前,简直反人类。
原理一模一样:每个“节”的页眉页脚默认是“链接到前一节”的。想要独立,得先“断开关联”。
# 假设现在有3个节:封面节、目录节、正文节 # 我们操作第三节(正文)的页脚 third_section = doc.sections[2] # 关键一步:断开与前一节(目录)的链接 third_section.footer.is_linked_to_previous = False # 现在可以放心设置正文的页码了 # 注意:设置页码格式涉及到操作页脚里的域代码 footer = third_section.footer # ... 在这里添加页码并设置起始为1拿到第三节的页脚后,执行is_linked_to_previous = False,这根“脐带”就被剪断了。从此以后,正文节的页码跟目录节的页码再也没关系,各走各的。
还有一个常用功能是“首页不同”。有的章节开头那一页不想显示页眉,这个设置也是挂在“节”下面的。
section = doc.sections[0] section.different_first_page_header_footer = True # 单独设置首页页眉 first_page_header = section.first_page_header first_page_header.paragraphs[0].text = "封面不留页眉" # 其他页面的正常页眉 other_pages_header = section.header other_pages_header.paragraphs[0].text = "内部资料"打开different_first_page_header_footer开关后,Word就会把这个节的首页和其他页分开对待,你可以分别往里面填内容。
六、批量修改,降维打击
学会了控制“节”,能玩的花样就多了。比如公司换了新logo,要批量给几百份标书统一加上“机密”水印和页眉。
import os from docx import Document folder_path = './reports/' for filename in os.listdir(folder_path): if filename.endswith('.docx'): doc = Document(os.path.join(folder_path, filename)) # 遍历每一个节 for section in doc.sections: # 强制断开页眉链接,防止有些文档设置过特殊属性 section.header.is_linked_to_previous = False header = section.header # 清空原来的页眉 header.paragraphs[0].clear() # 写入新内容 header.paragraphs[0].text = "XX集团 绝密文件" doc.save(os.path.join(folder_path, 'new_' + filename))一个循环,遍历所有节,几秒钟完成几百个文件的手工活儿。
七、把大象放进冰箱
回过头看小李遇到的麻烦。把Word里的一页单独改变布局,就像把大象放进冰箱,也是分三步:
打开冰箱门:用
sections属性看到文档的结构。把大象放进去:用
add_section()在目标位置切出新的节。把冰箱门关上:修改新节的
orientation、margin等属性。
理解了“节”这个概念,Word自动化的大门才算真正推开了。页眉页脚、页码格式、分栏布局,全都建立在这个基础上。以后遇到再复杂的排版需求,心里就有底了——无非就是切几刀,改几个参数的事。
这份技能在手里,不管是一份80页的报告,还是800页的标书,用Python管理起来都格外轻松。
