竟然可以用Python操作 Word 文档,这么多的骚操作!

前言

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

python免费学习资料以及群交流解答点击即可加入

本文主要讲解python中操作word的思路。

一、Hello,world!

使用win32com需要安装pypiwin32

pip install pypiwin32

推荐使用python的IDLE,交互方便

1、如何新建文档

from win32com.client import Dispatch


app = Dispatch('Word.Application')
# 新建word文档
doc = app.Documents.Add()

按F5运行,发现什么效果都没有, 这是因为Word被隐藏了。

2、如何显示Word

app.Visible = 1

运行后,熟悉的Word界面出现。现在来输入文字。


3、如何输入

我们在Word中输入文字时,一般会先使用鼠标点击需要输入文字的位置,这个过程是获得了光标焦点。

当我们需要替换某些文字时,首先会选中某些文字,然后再输入、被选择的文字呈现出灰色的背景,表示被选中了。

光标焦点和选择范围在Word中,都是Selection。什么都没选择的光标焦点,和选择了整片文章的选择范围,代表了Selection的最小和最大范围。

这也是为什么整个Word中只能有一个Selection的原因。因为光标或者选择范围就只能有一个。

# 运行下句代码后,s获得新建文档的光标焦点,也就是图中的回车符前
s = app.Selection
# 用“Hello, World!“替换s代表的范围的文本
s.Text = 'Hello, world!'

此时,s的范围为'Hello, world!'这句话的选择区域。



能如此方便的调用Word,得益于其底层的COM(组件对象模型)可以被任意语言调用。

Selection是Word对象模型中的类,此处的s是它的对象(实例)。

4、如何查看选择区域是什么

s.Text可以查看或者设置s选择区域的文本。Word对象模型中很多对象都有默认属性,Text就是Selection的默认属性,类似python的__ str __方法。运行s()调用s的默认属性,此处等于于运行了s.Text。

s()

控制台显示,s的范围为'Hello, world!'这句话的选择区域。


二、对Word对象模型的简单理解

Word中最重要的类(对象)有以下几个。

1、Application对象:Word应用。Application包含了菜单栏、工具栏、命令以及所有文档等。

# 如何获得
app = win32com.client.Dispatch('Word.Application')

2、Document对象:文档。可以有多个Document,就像Word可以打开多个文档。

使用下列代码新建文档或者打开文档

# 如何获得

# 新建文档
doc = app.Documents.Add()
# 打开已有文档
doc = app.Documents.Open('你的Word文件路径')

3、Selection对象:选区:代表当前窗口的选区。它可以是文档中的选择(高亮)区域,也可以是插入点(如果没有什么被选中)。同一时间只能激活一个Selection。

  • 如何获得
s = app.Selection

在Word中,按下Alt+F11打开宏编辑器



然后按下F2打开对象浏览器



输入selection并回车,发现成员一列中完全匹配Selection的只有4个类,这表示只有这些类的Selection属性可以返回Selection对象(如图)。

Application我们前面介绍过,其它的类可以用同样的方法查询如何获得。

  • 如何使用Selection输入
# 替换当前选择
s.Text = 'Hello, world!'
# 输入
s.TypeText('Hello, world!')
# 把当前选择复制到剪贴板
s.Copy()
# 粘贴剪贴板中的内容
s.Paste()

Text和TypeText的不同在于完成后的选区:
Text:输入的文本(前例中选区为'Hello, world!');
TypeText:文本后的插入点(前例中选区为!后的插入点)。

  • 如何变更Selection
# 使用Start,End指定字符范围
s.Start = 0
s.End = n
# s从第0个字符(第1个字符前的插入点)到第n个字符。
# 汉字是每字为1字符

# 相当于按下Delete键
s.Delete() 
# 相当于按下Ctrl+A
s.WholeStory() 
# 向左移动
s.MoveLeft()
# 向右移动2个字符,第1个参数是移动单位WdUnits,见下图
s.MoveRight(1, 2)

所有能获得Selection的类

4、Range对象:连续区域。Range表示一个连续区域。Range由Start和End位置定义,用来区分文档的不同部分。Range是独立于Selection的。不管Selection是否改变,都可以定义和操作Range。文档中可以定义多个Range。这个连续区域同样可以小到一个插入点,大到整个文档。Selection有Range属性,而Range没有Selection属性。

当使用Range(Start, End)方法来指定文档的特定范围时。文档的第一个字符位置为0,最后一个字符的位置和文档的字符总数相等。不提供参数时代表选择所有范围。

  • 如何获得
r = doc.Range()
# 或
r = s.Range()

Word中有很多对象的Range属性都能返回Range对象,请在Word-宏编辑器-对象浏览器中自己查询。

  • 如何使用

因为本文仅使用Selection就可以达到效果,Range的很多属性和方法和Selection是类似的。
5、Font对象:字体。包含对象的字体属性(字体名称、字号、颜色等)。

  • 如何获得
font = s.Font
# 或
font = r.Font

同样,其余获得方法可在Word-宏编辑器-对象浏览器中查询。

  • 如何使用
# 字体设置为仿宋,电脑上必须安装有该字体
font.Name = '仿宋'
# 字号设置为三号
font.Size = 16

6.ParagraphFormat对象:段落格式。用来设置段落格式,包括对齐、缩进、行距、边框底纹等。

  • 如何获得
pf = s.ParagraphFormat
# 或
pf = r.ParagraphFormat

同样,其余获得方法可在Word-宏编辑器-对象浏览器中查询。

  • 如何使用
# 左、中、右 对齐分别为0, 1, 2,其他对齐方式见.NET 文档中的ParagraphFormat
pf.Alignment = 0
# 单倍、1.5倍、双倍行距分别为0, 1, 2,其他见ParagraphFormat文档
pf.LineSpacingRule = 0
# 指定段落的左缩进值为21磅。
pf.LeftIndent = 21

7、PageSetup对象:页面设置。代表所有的页面设置属性,包括左边距,底边距,纸张大小等等。

  • 如何获得
ps = doc.PageSetup
# 或
ps = s.PageSetup
# 或
ps = r.PageSetup

同样,其余获得方法可在Word-宏编辑器-对象浏览器中查询。

  • 如何使用
# 上边距79磅 
ps.TopMargin = 79
# 页面大小,A3、A4分别为6,7
ps.PageSize = 7

8、Styles对象:样式集。Styles包含指定文档中内置和用户定义的所有样式,它返回一个样式集。其中的每个样式的属性包括字体、 字形、 段落间距等。如常见的正文、页眉、标题1样式。

  • 如何获得
# 只能通过文档获得
styles = doc.Styles
  • 如何使用
# 返回正文样式
normal = styles(-1)

# 修改正文样式的字体字号
normal.Font.Name = '仿宋'
normal.Font.Size = 16

Styles的返回参数,标题1、标题2、标题3分别为-2、-3、-4,页眉为-32,标题为-63,其他见Styles文档

三、解决问题思路

因为有很多功能,在文档中难以直接找到,需要使用如下方法。
1、把想实现的功能,使用word的录制宏,在宏编辑器里查看VBA代码,从而了解大概使用什么方法。
2、使用在线的 .NET API,从而了解详细的语法
3、如果不知道从哪获得实现该功能的对象,则可以使用word宏编辑器的对象浏览器(F2键),具体见前文Selection部分
4、使用Python的IDLE进行实时交互

app = win32com.client.Dispatch('word.application')
app.Visible='True' 
# 让word程序可见,这样在交互命令行做的修改就可以实时显示
doc = app.Documents.Open('你的桌面路径/test.docx') 
# word文件放在桌面方便手动修改

然后输入自己想尝试的对象属性或方法。

四、实例:格式化word文件为最新的公文国家标准

只进行两个部分的设置,一是页面设置、二是页码设置

from win32com.client import Dispatch #需要安装的是pypiwin32模块


app=Dispatch('Word.Application')
doc = app.Documents.Open('你的word文档路径')

# 页面设置
cm_to_points = 28.35 # 1厘米为28.35磅
# 国家公文格式标准要求是上边距版心3.7cm
# 但是如果简单的把上边距设置为3.7cm
# 则因为文本的第一行本身有行距
# 会导致实际版心离上边缘较远,上下边距设置为3.3cm
# 是经过实验的,可以看看公文标准的图示
# 版心指的是文字与边缘距离
doc.PageSetup.TopMargin = 3.3*cm_to_points  
# 上边距3.3厘米
doc.PageSetup.BottomMargin = 3.3*cm_to_points  
# 下边距3.3厘米
doc.PageSetup.LeftMargin = 2.8*cm_to_points  
# 左边距2.8厘米
doc.PageSetup.RightMargin = 2.6*cm_to_points  
# 右边距2.6厘米

# 设置正常样式的字体
# 是为了后面指定行和字符网格时
# 按照这个字体标准进行
doc.Styles(-1).Font.Name = '仿宋' 
# word中的“正常”样式字体为仿宋
doc.Styles(-1).Font.NameFarEast = '仿宋' 
# word中的“正常”样式字体为仿宋
doc.Styles(-1).Font.NameAscii = '仿宋'
# word中的“正常”样式字体为仿宋
doc.Styles(-1).Font.NameOther = '仿宋' 
# word中的“正常”样式字体为仿宋
doc.Styles(-1).Font.Size = 16 
# word中的“正常”样式字号为三号

doc.PageSetup.LayoutMode = 1 
# 指定行和字符网格
doc.PageSetup.CharsLine = 28 
# 每行28个字
doc.PageSetup.LinesPage = 22 
# 每页22行,会自动设置行间距

# 页码设置
doc.PageSetup.FooterDistance = 2.8*cm_to_points  
# 页码距下边缘2.8厘米
doc.PageSetup.OddAndEvenPagesHeaderFooter = 0 
# 首页页码相同
doc.PageSetup.OddAndEvenPagesHeaderFooter = 0 
# 页脚奇偶页相同
w = doc.windows(1)  
# 获得文档的第一个窗口
w.view.seekview = 4 
# 获得页眉页脚视图
s = w.selection  
# 获取窗口的选择对象
s.headerfooter.pagenumbers.startingnumber = startingnumber  
# 设置起始页码
s.headerfooter.pagenumbers.NumberStyle = 0  
# 设置页码样式为单纯的阿拉伯数字
s.WholeStory() 
# 扩选到整个部分(会选中整个页眉页脚)
s.Delete() 
#按下删除键,这两句是为了清除原来的页码
s.headerfooter.pagenumbers.Add(4)  
# 添加页面外侧页码
s.MoveLeft(1, 2)  
# 移动到页码左边,移动了两个字符距离
s.TypeText('— ')  
# 给页码左边加上一字线,注意不是减号
s.MoveRight() 
#移动到页码末尾,移动了一个字符距离
# 默认参数是1(字符)
s.TypeText(' —') 
s.WholeStory() 
# 扩选到整个页眉页脚部分,此处是必要的
# 否则s只是在输入一字线后的一个光标,没有选择区域
s.Font.Name = '宋体'
s.Font.Size = 14 
#页码字号为四号
s.paragraphformat.rightindent = 21 
#页码向左缩进1字符(21磅)
s.paragraphformat.leftindent = 21 
# 页码向右缩进1字符(21磅)
doc.Styles('页眉').ParagraphFormat.Borders(-3).LineStyle = 0 
# 页眉无底边框横线
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容