代码改变世界

python 操作 office

2014-02-13 20:28  youxin  阅读(7722)  评论(0编辑  收藏  举报

首先介绍下office win32 com接口,这个是MS为自动化提供的操作接口,比如我们打开一个WORD文档,就可以在里面编辑VB脚本,实现我们自己的效果。对于这种一本万利的买卖,Python怎么能放过,它内置了对于win32 com接口的支持,我们可以方便的控制。

要想熟练使用office win32 com接口,没有什么比MS提供的API文档更加权威了.

ORD中最重要的概念有几个:
Application - 这个毫无疑问是我们的WORD应用程序
Document - 这个就是一个打开的文档对象
Range - 这个东东必须要好好利用,基本上所有对象都是有Range属性的,而这也为我们排版提供了极大的便利。。。
Paragraph - 顾名思义,这个是段落的意思,也就是我们文档中的一个段内容(可以是文本、图片等)。
Section - 在我学习的时候,这个东东给我制造了最大的障碍,因为我当时苦苦琢磨,究竟怎么才能插入一个新的页,然后在新页上开始输出内容。。。
ParagraphFormat - 这个是为了设置格式的,你不可能不使用它。。。
有了以上几个最重要的概念铺垫,接下来的代码基本上可以平蹚了,来,看一段代码先,事先声明,这段代码摘自网上,不知道哪位兄台写的,只写了可写可不写的东西(这么说有点过分,不过确实没有实质性的内容),我添油加醋的处理了一下,确保营养比较丰富,大家看起来应该实用性更强一些。。。

import win32com
from win32com.client import Dispatch, constants

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

# 后台运行,显示程序界面,不警告
w.Visible = 1 #这个至少在调试阶段建议打开,否则如果等待时间长的话,它至少给你耐心。。。
w.DisplayAlerts = 0

# 打开新的文件
#worddoc = w.Documents.Open(file_name) #这句话用来打开已有的文件,当然,在此之前你最好判断文件是否真的存在。。。
doc = w.Documents.Add() # 创建新的文档,我用的更多的是这个,因为我要的是创建、然后保存为。。

# 插入文字
myRange = doc.Range(0,0) #这句话让你获取的是doc的最前面位置,如果想要获取到其他位置,就要改变Range中的参数,两个参数分别代表起始点,结束点。。。
myRange.InsertBefore('Hello from Python!')

'''
以下一段是增加10个新页,然后跳转到新页中增加内容。。。。
'''
section_index = 0
for i in range(0, 10):
 #由于增加页的使用如此频繁,我们最好将其提取为一个函数,类似def NewTable(self):
 pre_section = doc.Secitons(section_index)
 new_seciton = doc.Range(pre_section.Range.End, pre_section.Range.End).Sections.Add()
 new_range = new_seciton.Range
 
 content_pg = new_range.Paragraphs.Add()
 content_pg.Range.Font.Name,content_pg.Range.Font.Size = 'Times New Roman',24
 caption_pg.Range.ParagraphFormat.Alignment = 0 # 0,1,2 分别对应左对齐、居中、右对齐
 caption_pg.Range.InsertBefore('Hello,Page ' + str(i+1))
 
 section_index = section_index + 1 #记录这个的目的是为了方便的找到doc的尾端,不然的话,我还真没有想到怎么搞。。。

# 正文文字替换
w.Selection.Find.ClearFormatting()
w.Selection.Find.Replacement.ClearFormatting()
w.Selection.Find.Execute(OldStr, False, False, False, False, False, True, 1, True, NewStr, 2)

#设置页眉文字,如果要设置页脚值需要把SeekView由9改为10就可以了。。。
w.ActiveWindow.ActivePane.View.SeekView = 9 #9 - 页眉; 10 - 页脚
w.Selection.ParagraphFormat.Alignment = 0
w.Selection.Text = 'New Header'
w.ActiveWindow.ActivePane.View.SeekView = 0 # 释放焦点,返回主文档

# 页眉文字替换
w.ActiveDocument.Sections[0].Headers[0].Range.Find.ClearFormatting()
w.ActiveDocument.Sections[0].Headers[0].Range.Find.Replacement.ClearFormatting()
w.ActiveDocument.Sections[0].Headers[0].Range.Find.Execute(OldStr, False, False, False, False, False, True, 1, False, NewStr, 2)

# 在文档末尾新增一页,并添加一个表格。。。
pre_section = doc.Secitons(section_index)
new_seciton = doc.Range(pre_section.Range.End, pre_section.Range.End).Sections.Add()
new_range = new_seciton.Range
new_table = new_range.Tables.Add(doc.Range(new_range.End,new_range.End), 5, 5) #在文档末尾添加一个5*5的表格
#接下来Table怎么操作,这里就不细说了,检索Table对象参照就OK了。。。

# 表格操作
doc.Tables[0].Rows[0].Cells[0].Range.Text ='123123'
worddoc.Tables[0].Rows.Add() # 增加一行

# 转换为html
wc = win32com.client.constants
w.ActiveDocument.WebOptions.RelyOnCSS = 1
w.ActiveDocument.WebOptions.OptimizeForBrowser = 1
w.ActiveDocument.WebOptions.BrowserLevel = 0 # constants.wdBrowserLevelV4
w.ActiveDocument.WebOptions.OrganizeInFolder = 0
w.ActiveDocument.WebOptions.UseLongFileNames = 1
w.ActiveDocument.WebOptions.RelyOnVML = 0
w.ActiveDocument.WebOptions.AllowPNG = 1
w.ActiveDocument.SaveAs( FileName = filenameout, FileFormat = wc.wdFormatHTML )

# 打印
doc.PrintOut()

# 关闭
# doc.Close()
w.Documents.Close(wc.wdDoNotSaveChanges)
w.Quit()

 

简单示例:(wps下)

#导入引用win32com.client模块
import win32com.client
#新建WPS进程
wpsApp=win32com.client.Dispatch("wps.Application")
#可视
wpsApp.Visible=1
#添加文档
wpsDoc=wpsApp.Documents.Add()
#添加内容
wpsDoc.content.text="Hello World!"
#保存文档
wpsDoc.SaveAs("C:\Sample.wps")
#关闭文档 wpsdoc.Close()
#关闭进程 wpsApp.Quit()

 

参考:

http://blog.csdn.net/lzl001/article/details/8435048

另一篇:

import win32com

from win32com.client import Dispatch, constants

接著,要讓我們的Python程式和MS Word建立起連結。

msword = Dispatch('Word.Application')

用Dispatch()的方式將會啟動MS Word。不過,如果您已經有執行MS Word,則此方式只會與現存的MS Word建立連結。如果您強烈希望能夠有一個新的MS Word程式出現,可用下面的方式:

msword = DispatchEx('Word.Application')

此時您會發現畫面上沒有任何MS Word出現,其實他已經在背後執行了。您可以透過工作管理員來查看是否有一個名為"WINWORD.EXE"的

Process。不產生畫面的好處是您可 以在背景來處理您要進行的工作。如果您想要看看到底是不是真的有成功的啟動MS Word,請設定Visible屬性。

msword.Visible = 1 # 1表示要顯示畫面,若為0則不顯示畫面。您可以隨時的更改此屬性。

除了不顯示畫面外,您也許還會希望不要顯示一些警告訊息。此時請設定DisplayAlerts屬性:

详细看:

http://wenku.baidu.com/view/c248150d6c85ec3a87c2c57f.html

更多:

 

http://wenku.baidu.com/view/d65d36728e9951e79b892737

http://my.oschina.net/duxuefeng/blog/64137

 

我遇到错误com_error: (-2147221164, '\xc3\xbb\xd3\xd0\xd7\xa2\xb2\xe1\xc0\xe0', None, None),网上找了好久没发现解决方案,说是没找到word进程。最后猛然想到自己电脑用的不是office,而是wps,看来还是有区别的。

又搜了下python 调用 wps,方法与word下类似,只是进程名不同而已:

import win32com.client<br />
o = win32com.client.Dispatch("wps.application")  (office下是Word.application)
o.Visible=True 
doc = o.Documents.Add() 
doc.Content.text="Hello world!"

执行。会看到弹出一个 WPS 窗口,其中新建了一个文档,正文为“Hello World”。

如果在交互环境中逐行执行,会看到每一步的效果(有时需要激活一下WPS窗口)。

参考:http://blog.csdn.net/ccat/article/details/5784933

如果操作excel,在网上搜了下,一篇文章是这样说的:

我在网上找了下,发现至少有两种方法,第一种是直接操作excle的com库,当然python自带的lib里面已经给我们封装好了实现,直接使用就可以了,win32com.client,这种方法甚至可以直接把excle的进程调用起来。用法很简单,网上的文章也汗牛充栋,就不详细解说了,给个小例子吧,嘻嘻。这种只能在windows下运行,并且需要安装MS Excel。

wps下面的Excel.application叫et.application

# -*- coding: utf-8 -*-
from win32com.client import constants, Dispatch

xlsApp = Dispatch("Excel.Application") (wps下叫et.application)
# 通过赋值Visible为True或者False可以控制是否调出excle
xlsApp.Visible = 1

# xlsBook = xlsApp.Workbooks.Open("c://magictong.xls")
# xlsSht = xlsBook.Worksheets("sheet1") (第一个sheet1)。

xlsBook = xlsApp.Workbooks.Add() (wps已经默认帮你创建了sheet1,sheet2,sheet3,这里创建另一个sheet,)
xlsSht = xlsBook.Sheets.Add()
xlsSht.Cells(2, 3).Value = "Tecent QQ"
xlsSht.Cells(2, 3).Font.Color = 0xff0000

xlsSht.Name = "GCD go to bell" 
xlsBook.SaveAs("c://magictong.xls")
xlsApp.Quit()

print "__end"

参考:http://blog.csdn.net/magictong/article/details/4966822

一个操作word的类:

http://wenku.baidu.com/view/ef59d6d728ea81c758f578da.html

一个操作excel的类:(Python Programming on Win32》书中也有很详细的介绍)

#!/usr/bin/python
#coding=utf-8
import win32com
from  win32com.client import Dispatch,constants

class  EasyExcel:
    def __init__(self,filename=None):
        self.xlApp=win32com.client.Dispatch("et.Application")
        self.xlApp.Visible=True
        if filename:
            self.filename=filename
            self.xlBook=self.xlApp.Workbooks.Open(filename)
        else:
            self.xlBook=self.xlApp.Workbooks.Add()
            self.filename=''
        

    def save(self,newfilename=None):
            if newfilename:
                self.filename=newfilename
                self.xlBook.SaveAs(newfilename)
            else:
                self.xlBook.Save()
    def close(self):
            #self.xlBook.Close(SaveChanges=0)
            #self.xlApp.Quit()
            #del self.xlApp
            print "close"
    def getCell(self,sheet,row,col):
            "get value of one cell"
            sht=self.xlBook.Worksheets(sheet)
            return sht.Cells(row,col).Value
    def setCell(self,sheet,row,col,value):
            'set value of one cell'
            sht=self.xlBook.Worksheets(sheet)
            sht.Cells(row,col).Value=value
    def getRange(self,sheet,row1,col1,row2,col2):
            'return a 2d array(ie:tuple of tuples'
            sht=self.xlBook.Worksheets(sheet)
            return sht.Range(sht.Cells(row1,col1),sht.Cells(row2,col2)).Value
    def addPicture(self,sheet,pictureName,Left,Top,Width,Height):
            'insert a picture in sheet'
            sht=self.xlBook.Worksheets(sheet)
            sht.Shapes.AddPicture(pictureName,1,1,Left,Top,Width,Height)
    def cpSheet(self,before):
            'copy sheet'
            shts=self.xlBook.Worksheets
            shts(1).Copy(None,shts(1))

    def  addSheet(self,sheetName='MySheet1'):
            self.sht1=self.xlBook.Sheets.Add()
            self.sht1.Name=sheetName
                


if __name__=="__main__":
        
        pic='D:/image/sunyanzi/yanzi760_580.jpg'
        xls=EasyExcel()
        sht1=xls.addSheet()
        xls.addPicture("MySheet1",pic,20,20,700,700)

        xls.setCell("MySheet1",1,1,"1_1_value")
        xls.setCell("MySheet1",1,2,"1_2_value");
        xls.setCell("MySheet1",1,3,"1_3_value")
        xls.setCell("MySheet1",2,1,"2_1_value")
        xls.setCell("MySheet1",2,2,"2_2_value")

        
        xls.save("D:/MySheet.xls")
        xls.close()
        
                        
            

 一个更详细的类:http://blog.sina.com.cn/s/blog_3fcd4ff90100n2mb.html

setting-a-cells-fill-rgb-color-with-pywin32-in-excel

http://stackoverflow.com/questions/11444207/setting-a-cells-fill-rgb-color-with-pywin32-in-excel

interior.color expects a hex value If you want to specify in RGB form below code can be used.

def rgb_to_hex(rgb):
    strValue ='%02x%02x%02x'% rgb
    iValue = int(strValue,16)return iValue

xl.ActiveSheet.Cells(row, column).interior.color = rgb_to_hex((255,255,0))

font颜色可以直接设置:
 sht.Rows(1).Font.Color= 0xff0000

非常好的文档:
http://pythonexcels.com/python-excel-mini-cookbook/



Ranges and Offsets


This script illustrates different techniques for addressing cells by using the Cells() and Range()operators. Individual cells can be addressed using Cells(row,column), where row is the row number, column is the column number, both start from 1. Groups of cells can be addressed using Range(), where the argument in the parenthesis can be a single cell denoted by its textual name (eg "A2"), a group noted by a textual name with a colon (eg "A3:B4") or a group denoted with two Cells() identifiers (eg ws.Cells(1,1),ws.Cells(2,2)). The Offsetmethod provides a way to address a cell based on a reference to another cell.


#
# Using ranges and offsets
#
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets("Sheet1")
ws.Cells(1,1).Value = "Cell A1"
ws.Cells(1,1).Offset(2,4).Value = "Cell D2"
ws.Range("A2").Value = "Cell A2"
ws.Range("A3:B4").Value = "A3:B4"
ws.Range("A6:B7,A9:B10").Value = "A6:B7,A9:B10"
wb.SaveAs('ranges_and_offsets.xlsx')
excel.Application.Quit()



Autofill Cell Contents


This script uses Excel’s autofill capability to examine data in cells A1 and A2, then autofill the remaining column of cells through A10.


#
# Autofill cell contents
#
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets("Sheet1")
ws.Range("A1").Value = 1
ws.Range("A2").Value = 2
ws.Range("A1:A2").AutoFill(ws.Range("A1:A10"),win32.constants.xlFillDefault)
wb.SaveAs('autofill_cells.xlsx')
excel.Application.Quit()

Cell Color

This script illustrates adding an interior color to the cell using Interior.ColorIndex. Column A, rows 1 through 20 are filled with a number and assigned that ColorIndex.

#
# Add an interior color to cells
#
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets("Sheet1")
for i in range (1,21):
    ws.Cells(i,1).Value = i
    ws.Cells(i,1).Interior.ColorIndex = i
wb.SaveAs('cell_color.xlsx')
excel.Application.Quit()

Column Formatting

This script creates two columns of data, one narrow and one wide, then formats the column width with the ColumnWidth property. You can also use the Columns.AutoFit() function to autofit all columns in the spreadsheet.

#
# Set column widths
#
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets("Sheet1")
ws.Range("A1:A10").Value = "A"
ws.Range("B1:B10").Value = "This is a very long line of text"
ws.Columns(1).ColumnWidth = 1
ws.Range("B:B").ColumnWidth = 27
# Alternately, you can autofit all columns in the worksheet
# ws.Columns.AutoFit()
wb.SaveAs('column_widths.xlsx')
excel.Application.Quit()

Copying Data from Worksheet to Worksheet

This script uses the FillAcrossSheets() method to copy data from one location to all other worksheets in the workbook. Specifically, the data in the range A1:J10 is copied from Sheet1 to sheets Sheet2 and Sheet3.

#
# Copy data and formatting from a range of one worksheet
# to all other worksheets in a workbook
#
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets("Sheet1")
ws.Range("A1:J10").Formula = "=row()*column()"
wb.Worksheets.FillAcrossSheets(wb.Worksheets("Sheet1").Range("A1:J10"))
wb.SaveAs('copy_worksheet_to_worksheet.xlsx')
excel.Application.Quit()

Format Worksheet Cells

This script creates two columns of data, then formats the font type and font size used in the worksheet. Five different fonts and sizes are used, the numbers are formatted using a monetary format.

#
# Format cell font name and size, format numbers in monetary format
#
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets("Sheet1")

for i,font in enumerate(["Arial","Courier New","Garamond","Georgia","Verdana"]):
    ws.Range(ws.Cells(i+1,1),ws.Cells(i+1,2)).Value = [font,i+i]
    ws.Range(ws.Cells(i+1,1),ws.Cells(i+1,2)).Font.Name = font
    ws.Range(ws.Cells(i+1,1),ws.Cells(i+1,2)).Font.Size = 12+i

ws.Range("A1:A5").HorizontalAlignment = win32.constants.xlRight
ws.Range("B1:B5").NumberFormat = "$###,##0.00"
ws.Columns.AutoFit()
wb.SaveAs('format_cells.xlsx')
excel.Application.Quit()


 

Setting Row Height


This script illustrates row height. Similar to column height, row height can be set with the RowHeight method. You can also useAutoFit() to automatically adjust the row height based on cell contents


#
# Set row heights and align text within the cell
#
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets("Sheet1")
ws.Range("A1:A2").Value = "1 line"
ws.Range("B1:B2").Value = "Two\nlines"
ws.Range("C1:C2").Value = "Three\nlines\nhere"
ws.Range("D1:D2").Value = "This\nis\nfour\nlines"
ws.Rows(1).RowHeight = 60
ws.Range("2:2").RowHeight = 120
ws.Rows(1).VerticalAlignment = win32.constants.xlCenter
ws.Range("2:2").VerticalAlignment = win32.constants.xlCenter

# Alternately, you can autofit all rows in the worksheet
# ws.Rows.AutoFit()

wb.SaveAs('row_height.xlsx')
excel.Application.Quit()

Prerequisites

Python (refer to http://www.python.org)

Win32 Python module (refer to http://sourceforge.net/projects/pywin32)

Microsoft Excel (refer to http://office.microsoft.com/excel)

Source Files and Scripts

Source for the program and data text file are available athttp://github.com/pythonexcels/examples

转自:http://pythonexcels.com/python-excel-mini-cookbook/

 

如果设置了某行的背景色,那么边框将看不见,这是很不爽的,要设置单元格的格式border显示格式,有line style,等多种,怎么用程序

设置呢?找了n久,终于发现了,

 sht.Rows(1).Borders.LineStyle=1