所属课程:《Python数据分析与挖掘系列直播》.韦玮
题目:
我们此次的题目是写一个Python程序,实现多个Excel表格的合并。
目的:
希望大家通过此次课程将Python基础牢牢的掌握,此答案仅供参考,此次作业各位需要在理解的前提下写一份发到我的邮箱:ceo@iqianyue.com,会有相应的分数,最终前十名的同学至少可以获得老师亲笔签名的新书。
作业提交截止日期:
2016年26日中午12:00前
思路:
这个作业我们可以采用一些操作Excel的模块去实现,比如xlrd、xlwt、openpyxl、xlsxwriter等模块。xlrd模块主要用于读取Excel表,xlwt与xlsxwriter模块主要用于将数据写入表中,两个模块任选其一即可,但是xlwt与xlsxwriter模块不支持修改表,所以在信息追加的时候会较麻烦,有些朋友可能这个地方遇到了很大的问题,其实这个问题至少有两种思路解决:
A、换成其他模块,比如openpyxl等,这个模块实现起来会相对简单一些,比如目前已经收到的苏wisdom同学采用的就是这种方法,值得表扬,所以以下方法1会参照苏wisdom同学的答案。此外,截止至目前为止『歹ピ№ㄕ』同学、微雨同学、黄梦颖同学已经提交第二次作业,一并表扬。
B、仍然使用xlwt与xlsxwriter等模块,但是先将每次读取的信息存储到list(列表)中,然后,最后一次写入。这一种方式稍微复杂一些,所以老师在方法2中采用这种方式去写,目的是给大家一个解决方案的参考,有更优的方案可以随时邮箱反馈。
此外,还有一个难点,即一个表格中有多个sheet,我们希望能够用程序自动获取这多个sheet,然后将各sheet中的内容一并写入到最终表格中,目前答案中暂时没有看到解决这个问题,如果大家能解决这个问题,是极好的。各位同学可以参考老师的第二种方法,第二种方式中,考虑了多个sheet的问题,各位也可以对程序进行优化。
以下进入具体程序的实现。
实现方法1:
苏wisdom同学的方法,各位有兴趣的朋友可以在此基础上改进一下,比如自动获取每张表中的多个sheet,分别将每个sheet中的内容都写入最终文件中。openpyxl
wb1 = openpyxl.load_workbook()
wb2 = openpyxl.load_workbook()
wb3 = openpyxl.load_workbook()
wb = openpyxl.Workbook()
wsheet = wb.active
(wb):
sheet = wb.active
column = sheet.max_column
column
(wbcolumn):
ws = wb.active
row_obj (ws.rows):
t = (row_obj)
temp = []
j (column):
temp.append(t[j].value)
wsheet.append(temp)
column1 = get_column(wb1)
column2 = get_column(wb2)
column3 = get_column(wb3)
do_append(wb1column1)
do_append(wb2column2)
do_append(wb3column3)
wb.save()
实现方法2:
为了让大家了解稍难一点的解决方案,可以更深入地巩固所学知识,所以老师采用了稍难的方案解决,即上面的方案2。各位同学可以参考一下下面老师的程序,使用的是xlrd,xlsxwriter两个模块,关键部分给出注释。(考虑了一个表中有多个sheet的问题)
首先通过pip安装xlrd与xlsxwriter模块,如下所示(图为xlsxwriter模块的安装,xlrd模块安装类似,将xlsxwriter换成xlrd即可):
此时,我们在F盘下放了3个待合并的测试文件,如下所示:
每个文件都有两个sheet,每个sheet下都有不同内容,sheet1中放课程信息,sheet2中放书籍信息,如下所示:
sheet1
sheet2
我们需要将多个文件不同的sheet的内容都自动合并到同一个文件中,实现代码如下:import xlrd,xlsxwriter
#设置要合并的所有文件
allxls=["F:/第一个测试文件.xls","F:/第二个测试文件.xls","F:/第三个测试文件.xls"]
#设置合并到的文件
endxls ="F:/endxls.xls"
#打开表格
def open_xls(file):
try:
fh=xlrd.open_workbook(file)
return fh
except Exception as e:
print(str("打开出错,错误为:"+e))
#获取所有sheet
def getsheet(fh):
return fh.sheets()
#读取某个sheet的行数
def getnrows(fh,sheet):
table=fh.sheets()[sheet]
content=table.nrows
return content
#读取某个文件的内容并返回所有行的值
def getfilect(fh,fl,shnum):
fh=open_xls(fl)
table=fh.sheet_by_name(shname[shnum])
num=getnrows(fh,shnum)
lenrvalue=len(rvalue)
for row in range(0,num):
rdata=table.row_values(row)
rvalue.append(rdata)
#print(rvalue[lenrvalue:])
filevalue.append(rvalue[lenrvalue:])
return filevalue
#存储所有读取的结果
filevalue=[]
#存储一个标签的结果
svalue=[]
#存储一行结果
rvalue=[]
#存储各sheet名
shname=[]
#读取第一个待读文件,获得sheet数
fh=open_xls(allxls[0])
sh=getsheet(fh)
x=0
for sheet in sh:
shname.append(sheet.name)
svalue.append([])
x+=1
#依次读取各sheet的内容
#依次读取各文件当前sheet的内容
for shnum in range(0,x):
for fl in allxls:
print("正在读取文件:"+str(fl)+"的第"+str(shnum)+"个标签的…")
filevalue=getfilect(fh,fl,shnum)
svalue[shnum].append(filevalue)
#print(svalue[0])
#print(svalue[1])
#由于append具有叠加关系,分析可得所有信息均在svalue[0][0]中存储
#svalue[0][0]元素数量为sheet标签数(sn)*文件数(fn)
sn=x
fn=len(allxls)
endvalue=[]
#设置一个函数专门获取svalue里面的数据,即获取各项标签的数据
def getsvalue(k):
for z in range(k,k+fn):
endvalue.append(svalue[0][0][z])
return endvalue
#打开最终写入的文件
wb1=xlsxwriter.Workbook(endxls)
#创建一个sheet工作对象
ws=wb1.add_worksheet()
polit=0
linenum=0
#依次遍历每个sheet中的数据
for s in range(0,sn*fn,fn):
thisvalue=getsvalue(s)
tvalue=thisvalue[polit:]
#将一个标签的内容写入新文件中
for a in range(0,len(tvalue)):
for b in range(0,len(tvalue[a])):
for c in range(0,len(tvalue[a][b])):
#print(linenum)
#print(c)
data=tvalue[a][b][c]
ws.write(linenum,c,data)
linenum+=1
#叠加关系,需要设置分割点
polit=len(thisvalue)
wb1.close()
程序中注释掉的print主要供大家调试使用,不影响。
随后,我们运行程序,出现如下显示:
随后,我们查看自动写入的在F盘下的最终文件endxls.xls,点击开后出现如下界面:
可以看到,此时已经将所有待合并的文件的所有sheet中的内容都合并到了此Excel文件中,顺利实现。代码各位同学有兴趣仍可以再优化一下。
两种方法各位任选其一即可,方法1较简单,方法2较好玩。