2007年12月13日星期四

用python操作word

中午练车效果奇佳,得意的向lp炫耀,lp出乎意料的没有给我泼冷水~不过一会儿就露出猪尾巴来了,想让我帮她想个法子能把多个word文档集中在一个文档中,生成一个目录,这还不算什么,问题是未来可能要多次改变先后顺序。由于文档数目比较多,用手工复制粘贴工作量太大,领导看一遍改一遍那简直要人命了~~
lp有求当然要比应了!在回来的车上就开始想该怎么整。用word界面的菜单功能,添加一个文件进来就要点数次鼠标,不好;用word的VBA功能,肯定能完成任务,不过VBA我不熟,看着那语法就头疼,不好;用python倒是不错,谁用谁知道,而且在邮件列表上看过有人用来操作excell,想必也一定能操作word,就用这个试试吧,搞不出来再用VBA也不迟。
回来以后就开始找操作word的库,google一下就找到了,叫win32com。照着网上的例子写了一个简单的脚本,居然出错了!找到出错的地方,注释掉,直到成功。发现错误的地方都是一些常量的使用,报错信息是没有该属性~先不管它了,还好我用不到什么常量。
新建文档没有问题,可是打开已有的文档总是报错,更令人郁闷的是错误信息全是16进制的代码,完全不明白哪里出了问题!忙乎了一个下午,试了N种可能,就是不行!以为是编码问题,找了半天怎么修改python的默认编码,成功后发现还是不行!又从命令行执行代码,居然成功了!比较两者的不同,发现命令行上由于不是在当前目录,所以写全了路径,可是从代码执行时也能通过'.\\'获得当前目录的文件列表啊?!不管,先加上全路径再说!
终于可以打开了,下面就是如何把一个文档里的内容拷贝到另一个文档的最后了~看了半天的VBA的帮助文件,终于成功了(中间的N多挫折就不说了)~~
然后给每个文档内容后后插入换行符,这需要常量wdPageBreak,没有,就直接查帮助其对应的值为7,填上就是~
lp那里没有装python,还要用py2exe打包为exe文件来发布~
不多说了,贴上代码:
#!/usr/bin/env python
#coding=cp936

import win32com
from win32com.client import Dispatch, constants
import os
import sys

#print sys.getdefaultencoding(), sys.getfilesystemencoding()
reload(sys)
sys.setdefaultencoding('cp936')
#print sys.getdefaultencoding(), sys.getfilesystemencoding()

def move2End(w, newdoc):
newdoc.Content.Select()
sel = w.Selection
sel.EndKey()
return sel

#获取当前目录
dirname = os.getcwd()+'\\'
filedir = dirname+'all\\'
# 读入单个文件列表
fileList = [f for f in os.listdir(filedir)]
# 读入文件顺序文件
f = open("order.txt", "r")
lines = f.readlines()
f.close()
#print lines
text = " ".join(lines)
fileOrder = text.split(',')
for i in range(len(fileOrder)):
order = fileOrder[i].strip("\n")
fileOrder[i] = order.strip()
print '指定排列顺寻为:', fileOrder
#fileOrder=range(1,len(fileList)+1)

#w = win32com.client.Dispatch('Word.Application')
# 或者使用下面的方法,使用启动独立的进程:
w = win32com.client.DispatchEx('Word.Application')

# 后台运行,不显示,不警告
w.Visible = 0
w.DisplayAlerts = 0

# 打开新的文件
newdoc = w.Documents.Add() # 创建新的文档

for order in fileOrder:
for f in fileList:
filenum = f.split('-')[0]
try:
if order==filenum:
# 将游标定位于newdoc的尾部
sel = move2End(w, newdoc)
# 插入换行符(wdPageBreak=7)
sel.InsertBreak(Type=7)
sel = move2End(w, newdoc)
# 打开要插入的文档
f = filedir + f
#print f
doc = w.Documents.Open(FileName=f)
doc.Content.Select()
w.Selection.Copy()
# 插入文字
sel.Paste()
# 关闭插入文档
doc.Close()

print f, ' is copied~'
except ValueError:
pass

# 关闭
newdoc.SaveAs(dirname+'all.doc')
newdoc.Close()
w.Quit()

print '完成!~~:)'


没有评论: