python excel sheet复制
在日常的工作中,经常会在生成报表的时候用到python的excel操作,因为大多数人还是比较喜欢excel的风格。
python操作excel主要会用到2个库。一个是xlwt用于写excel。一个是xlrd用于excel文件的读取。
这时候会出现2种情况。
所有内容都是动态生成的
这种情况还是比较好处理,我们只需要使用xlwt进行操作即可。
Python | | 复制 | | ? |
01 | |
02 | from xlwt import * |
03 | |
04 | '''对excel增加行''' |
05 | def writeRow(tableObj,rowNum,tmpList,xlsStyleDict={}): |
06 | for num,o in enumerate(tmpList): |
07 | if num in xlsStyleDict: |
08 | style = xlsStyleDict.get(num) |
09 | tableObj.write(rowNum,num,o,style) |
10 | else: |
11 | tableObj.write(rowNum,num,o) |
12 | |
13 | '''@param fileName:文件名 |
14 | @param dataDict:数据 |
15 | dataDict格式 {"_sheetName":[u'a',u'b',u'c'], |
16 | "_sheetData":{"a":[['1','2','3'],['a','b','c']], |
17 | "b":[['11','22','33'],['aa','bb','cc']], |
18 | "c":[['111','222','333'],['aaa','bbb','ccc']] |
19 | }, |
20 | "_sheetTitle":{"a":[[u'日期',u'visits数量',u'leads数量']]} |
21 | "_sheetStyle":{"a":{0:XFStyleobject,1:XFStyleobject}} |
22 | } |
23 | ''' |
24 | def createExcelFile(fileName,dataDict): |
25 | if dataDict: |
26 | excelfile = Workbook() |
27 | sheetNameList = dataDict.get("_sheetName",[]) |
28 | sheetDataDict = dataDict.get("_sheetData",{}) |
29 | sheetTitleDict = dataDict.get("_sheetTitle",{}) |
30 | sheetStyleDict = dataDict.get("_sheetStyle",{}) |
31 | |
32 | for sheetName in sheetNameList: |
33 | ws = excelfile.add_sheet(sheetName) |
34 | titleList = sheetTitleDict.get(sheetName,[]) |
35 | styleDict = sheetStyleDict.get(sheetName,{}) |
36 | dataList = sheetDataDict.get(sheetName,[]) |
37 | rowIdx = 0 |
38 | for title in titleList: |
39 | writeRow(ws,rowIdx,title) |
40 | rowIdx +=1 |
41 | for data in dataList: |
42 | writeRow(ws,rowIdx,data,styleDict) |
43 | rowIdx +=1 |
44 | |
45 | excelfile.save(fileName) |
46 | |
47 |
已经存在了一个复杂的excel模板,需要向里面填入数据
此种情况又会分为2种,一种是模板固定;一种是动态模板。
固定模板
比如就是3个sheet页,我们只需要对应的填入每行的数据即可。
这种情况,我们就需要用到xlrd及xlutils。
Python | | 复制 | | ? |
01 | |
02 | import xlwt |
03 | import xlrd |
04 | from xlrd import open_workbook |
05 | from xlutils.copy import copy |
06 | '''@param:targetPath 新生成的excel名字 |
07 | @param:templatePath 模板的名字 |
08 | @sheetDataList:数组,数组下标对应模板中的sheet下标;下标对应的值要写入到各个sheet中. |
09 | ''' |
10 | def createExcelFromTemplate(targetPath,templatePath,sheetDataList): |
11 | cf = Utils.getConf("excel") |
12 | rb = open_workbook(templatePath) #通过sheet_by_index()获取的sheet没有write()方法 |
13 | wb = copy(rb) #通过get_sheet()获取的sheet有write()方法 |
14 | for idx in range(0,len(sheetDataList)): |
15 | sheetStartIdx = int(cf.get(excelName,"sheet%s_startIdx" % idx))#此行特殊,我这里是通过配置文件读入sheet模板中表头的行数 |
16 | ws = wb.get_sheet(idx) |
17 | insertList = sheetDataList[idx] |
18 | for data in insertList: |
19 | try: |
20 | writeRow(ws,sheetStartIdx,newData,{}) |
21 | sheetStartIdx +=1 |
22 | except: |
23 | pass |
24 | wb.save(targetPath) |
25 |
动态模板
比如一个模板中就1个sheet页,但是我们生成的excel报表需要根据第一个sheet页的样式来生成多个相同样式的sheet。
这种情况比较复杂,所以需要用到一些xlrd中的获取原模板的数据的方式。
Python | | 复制 | | ? |
01 | |
02 | from xlwt import * |
03 | import xlrd |
04 | from xlrd import open_workbook |
05 | sourceFile ="/home/test/a.xls" |
06 | targetFile ="/home/test/b.xls" |
07 | rb = open_workbook(sourceFile) |
08 | wb = Workbook() |
09 | for o in range(0,rb._all_sheets_count): |
10 | t_ws = wb.add_sheet("--%s" % o)#写入sheet名称 |
11 | s_ws = rb.sheet_by_index(o)#rb.sheet_by_name('111') |
12 | numRow = s_ws.nrows |
13 | numCol = s_ws.ncols |
14 | |
15 | for row in xrange(numRow): |
16 | rowList = s_ws.row_values(row) |
17 | for col in xrange(numCol): |
18 | oneValue = rowList[col] |
19 | t_ws.write(row, col, oneValue) |
20 | wb.save(targetFile) |
21 |
另外附上一个不错的代码。也是用于sheet复制的,但是他是从同一个workbook中复制。
Python | | 复制 | | ? |
01 | |
02 | from xlwt import * |
03 | import xlrd |
04 | from xlutils import copy |
05 | ''' |
06 | workbook == book in use |
07 | source_index == index of sheet you want to copy (0 start) |
08 | new_name == name of new copied sheet |
09 | ''' |
10 | def copy_sheet(workbook, source_index, new_name): |
11 | new_sheet = copy.copy(workbook.get_sheet(source_index)) |
12 | workbook._Workbook__worksheets.append(new_sheet) |
13 | append_index = len(workbook._Workbook__worksheets)-1 |
14 | workbook.set_active_sheet(append_index) |
15 | workbook.get_sheet(append_index).set_name(new_name) |
16 |
另注意,现在python的类库对excel支持有一定限制,当行数超过65535即报错。
一旦遇到这种问题,不要犹豫了,改csv吧!明天我再简单介绍一下python操作csv。