蛇之魅惑
首发于蛇之魅惑

Hello Word —— 使用Python读写Office文档之一

本系列文章将介绍如何使用Python读写主要Microsoft Office文档(Word,Excel和PowerPoint)

======================================================================================================================================

1. 操作Office文档的两种方法

本系列文章所指『Office文档』,特指Word文档、Excel工作簿和PowerPoint幻灯片。其他Office软件产生的文档不在讨论范围。

对一个Office文档进行读写,除了可以直接读写磁盘上的实质文件,还可以通过Office应用程序提供的COM接口进行。 COM接口相当于一个『官方中介』。而提供直接读写磁盘文件的库,相当于『小中介』。在Office 2003/2004以及以前,Office文档只采用微软私有的二进制格式,而这些私有格式直到2006年才公开于众。也就是说,小中介们以前都靠逆向工程以及各种猜测才实现了Office文档的读写。

时至今日,『官方中介』以及『小中介』都各有优劣。利用COM接口,优点在于能够使用到几乎Office所有的功能,并且由于COM的跨语言特性,知识迁移非常容易;缺点在于仅限于Windows + Office平台,操作系统和软件缺一不可。利用直接读写接口,优点在于跨平台,只要Python能够支持的平台基本上都可以,不需要Windows也不需要Office软件;缺点在于只能够使用一些基本的功能。

本系列文章只介绍如何使用直接读写接口操作Office文档。若想了解COM接口的使用,请参考pywin32的文档以及微软MSDN。

2. Hello Word!

下面的例子可以运行于任何平台(PC、Mac、树莓派……)。但是,如果想看到产生的文档,你还是需要一个能打开Office文档的应用。没有安装微软Office的话,其他替代软件比如AbiWord、OpenOffice、WPS之类的都可以。

首先安装python-docx这个Python库

$ pip install python-docx -U

(注意,在PyPi里还有一个叫docx的库,已经停止更新,不建议使用)

这个库依赖于lxml,在Windows下可能需要编译器。如果在安装python-docx过程中发现找不到编译器或者编译lxml错误的现象,可到 pypi.python.org/pypi/lx 下载和安装预编译的版本。

只需要4行代码就可以创建一个Word文档:

from docx import Document
document = Document()
document.add_paragraph('Hello,Word!')
document.save('demo.docx')

第一行引入docx库和Document类。Document类即代表了『文档』,第二行创建了Document类的一个实例document,相当于『这篇文档』。紧接着,我们在文档中利用add_paragraph函数添加一个段落,段落的内容是Hello,Word!。最后,用save函数将文档保存在磁盘上。

运行这个脚本,就得到了文件demo.docx。用Office软件打开,看看里面的内容。

3. 插入图片

下面一个任务是在一个Word文档里添加255个圆圈,颜色为红色由浅入深。显然,这个任务在Word里人工完成是非常麻烦的。但用代码就非常简单了。

from docx import Document
from PIL import Image,ImageDraw
from io import BytesIO

document = Document() #新建文档
p = document.add_paragraph() #添加一个段落
r = p.add_run() #添加一个游程
img_size = 20
for x in range(255):
    im = Image.new("RGB", (img_size,img_size), "white")
    draw_obj = ImageDraw.Draw(im)
    draw_obj.ellipse((0,0,img_size-1,img_size-1), fill=255-x)#画圆
    fake_buf_file = BytesIO()#用BytesIO将图片保存在内存里,减少磁盘操作
    im.save(fake_buf_file,"png")
    r.add_picture(fake_buf_file)#在当前游程中插入图片
    fake_buf_file.close()
    document.save("demo.docx")

画图我们利用了常用的PIL库。这段代码还展示了所谓『游程』的概念,在接下来的篇章中将加以介绍。

致谢:
感谢wanghz49指出用BytesIO

编辑于 2016-11-17

文章被以下专栏收录