Python操作Excel文件

与Python中csv模块不同,Python中没有处理Excel文件的标准模块,所有需要xlrd和xlwt扩展包,这两个包的具体安装过程,请大家自行百度,我就不在这多叙述了,本文主要讲的是Python对Excel文件的几个简单操作,由于代码里注释比较详细,所以本文文字会相对来说会少一下,如有不懂地方,可以私信我。

一、利用xlrd和xlwt进行简单读写Excel文件:

import sys
from xlrd import open_workbook
'''
利用xlrd模块读取excel工作簿三个表的name,行数和列数
'''
input_file="E:\\studytest\\data\\excel\\sales_2013.xlsx"
workbook=open_workbook(input_file)
print("Number of worksheets:",workbook.nsheets)
for worksheet in workbook.sheets():
    print("Worksheet name:",worksheet.name,"\tRows:",worksheet.nrows,"\tColumns:",worksheet.ncols)

二、处理单个文件:

import sys
from xlrd import open_workbook,xldate_as_tuple
from xlwt import Workbook
'''
处理单个工作表
1、读写excel文件
'''
input_file='E:\\studytest\\data\\excel\\sales_2013.xlsx'
output_file='E:\\studytest\\data\\excel_test\\2output.xlsx'
output_workbook=Workbook()
output_worksheet=output_workbook.add_sheet('jan_2013_output')
with open_workbook(input_file) as workbook:
    #根据工作表名字选区工作表
    worksheet=workbook.sheet_by_name('january_2013')
    for row_index in range(worksheet.nrows):
        for column_index in range(worksheet.ncols):
            output_worksheet.write(row_index,column_index,worksheet.cell_value(row_index,column_index))
output_workbook.save(output_file)

但是需要注意的是,当工作表中存在日期格式的列时,写入时会变成数字,该数字为时间数值与1900年1月1日之间的天数差,为了保证数据的完整性,我们需要对格式为日期的列进行格式化,代码如下:

from datetime import date
input_file='E:\\studytest\\data\\excel\\sales_2013.xlsx'
output_file='E:\\studytest\\data\\excel_test\\2output_date.xlsx'
output_workbook=Workbook()
output_worksheet=output_workbook.add_sheet('jan_2013_output')
with open_workbook(input_file) as workbook:
    worksheet=workbook.sheet_by_name('january_2013')
    #循环行
    for row_index in range(worksheet.nrows):
        #用于存放构造好的行数据
        row_list_output = []
        #循环列
        for column_index in range(worksheet.ncols):
            #type=3表示该列类型为日期
            #若该列为日期格式,则格式化日期
            if worksheet.cell_type(row_index,column_index) == 3:
                date_cell = xldate_as_tuple(worksheet.cell_value(row_index,column_index),workbook.datemode)
                date_cell = date(*date_cell[0:3]).strftime('%m/%d/%Y')
                row_list_output.append(date_cell)
                output_worksheet.write(row_index,column_index,date_cell)
            #否则直接拼接row_list_output
            else:
                non_date_cell = worksheet.cell_value(row_index,column_index)
                row_list_output.append(non_date_cell)
                output_worksheet.write(row_index,column_index,non_date_cell)
output_workbook.save(output_file)

在处理单个文件时,我们经常会有筛选特定的行的需求,而筛选特定存在一下三种情况:

1、行中某列数值满足某个条件;

2、行中某列数值在某个集合里;

3、行中某列的值匹配于特定的模式。

三种情况代码大致相同,本文只列出第一种情况的代码,大家可以试着做一下后两中。

2、筛选特定行
 2、1 行中的值满足某个条件
 2、2 行中的值属于某个集合(和上面的差不多,判断条件改成in A集合)
 2、3 行中的值匹配于特定的模式(和上面的差不多,判断条件改成pattern.search(数值))
'''
from datetime import date
input_file='E:\\studytest\\data\\excel\\sales_2013.xlsx'
output_file='E:\\studytest\\data\\excel_test\\4output.xlsx'
output_workbook=Workbook()
output_worksheet=output_workbook.add_sheet('jan_2013_output')
#条件:第四列的值
sale_amount_column_index=3
with open_workbook(input_file) as workbook:
    worksheet=workbook.sheet_by_name('january_2013')
    data = []
    #取表头
    header = worksheet.row_values(0)
    data.append(header)
    #循环第1行到最后一行
    for row_index in range(1,worksheet.nrows):
        #用于存放构造好的行数据
        row_list_output = []
        #取出需要判断列的值,比如某列值大于1400
        sale_amount = worksheet.cell_value(row_index,sale_amount_column_index)
        if sale_amount > 1400.0:
            #循环该列
            for column_index in range(worksheet.ncols):
                #type=3表示该列类型为日期
                #若该列为日期格式,则格式化日期
                if worksheet.cell_type(row_index,column_index) == 3:
                    date_cell = xldate_as_tuple(worksheet.cell_value(row_index,column_index),workbook.datemode)
                    date_cell = date(*date_cell[0:3]).strftime('%m/%d/%Y')
                    row_list_output.append(date_cell)
                #否则直接拼接row_list_output
                else:
                    non_date_cell = worksheet.cell_value(row_index,column_index)
                    row_list_output.append(non_date_cell)
            if row_list_output:
                data.append(row_list_output)
    #此处用迭代的原因是因为,如果直接写入的话,会导致索引也写入到新文件中,写入后的文件会出现空白行的情况
    for list_index,output_list in enumerate(data):
        for element_index,element in enumerate(output_list):
            output_worksheet.write(list_index,element_index,element)
output_workbook.save(output_file)

大家可以看一下,上面代码倒数第四行用到了迭代,为什么要用迭代呐,因为直接写入时会把行的索引也写入到新文件中,就会导致文件出现空白行的现象,如下图:



所以,为了避免出现这种情况,这里使用了迭代,后面的所有代码中凡是利用迭代实现,都是为了避免这种情况的出现。

当然,除了筛选特定行,我们还会有筛选特定列的需求,筛选特定列存在一下两种方法:

1、根据列索引来筛选,工作表中每个列都有一个对应的索引值,从0开始;

2、根据列标题来筛选,其中这种筛选方法和1原理一样,先根据列标题找出对应的索引值,单后根据索引值筛选,好处是不会出错,只要列标题正确,筛选的结果就不会出错。

下面是两种方法的实现代码:

'''
3、选取特定的列
 3、1 根据列索引值
'''
from datetime import date
input_file='E:\\studytest\\data\\excel\\sales_2013.xlsx'
output_file='E:\\studytest\\data\\excel_test\\7output.xlsx'
output_workbook=Workbook()
output_worksheet=output_workbook.add_sheet('jan_2013_output')
#条件:只取索引号为1和4的两列
my_columns = [1,4]
with open_workbook(input_file) as workbook:
    worksheet=workbook.sheet_by_name('january_2013')
    data = []
    for row_index in range(worksheet.nrows):
        #用于存放构造好的行数据
        row_list = []
        #循环满足条件的列
        for column_index in my_columns:
            cell_value = worksheet.cell_value(row_index,column_index)
            cell_type = worksheet.cell_type(row_index,column_index)
            #type=3表示该列类型为日期
            #若该列为日期格式,则格式化日期
            if cell_type == 3:
                date_cell = xldate_as_tuple(cell_value,workbook.datemode)
                date_cell = date(*date_cell[0:3]).strftime('%m/%d/%Y')
                row_list.append(date_cell)
            #否则直接拼接row_list_output
            else:
                row_list.append(cell_value)
        data.append(row_list)
    #此处用迭代的原因是因为,如果直接写入的话,会导致索引也写入到新文件中,写入后的文件会出现空白行的情况
    for list_index,output_list in enumerate(data):
        for element_index,element in enumerate(output_list):
            output_worksheet.write(list_index,element_index,element)
output_workbook.save(output_file)
'''
 3、2 根据列标题选取(同上,先根据标题选出列索引值,然后再使用列索引值)
'''
from datetime import date
input_file='E:\\studytest\\data\\excel\\sales_2013.xlsx'
output_file='E:\\studytest\\data\\excel_test\\8output.xlsx'
output_workbook=Workbook()
output_worksheet=output_workbook.add_sheet('jan_2013_output')
#条件:只取索引号为1和4的两列
my_columns = ['Customer ID','Purchase Date']
with open_workbook(input_file) as workbook:
    worksheet=workbook.sheet_by_name('january_2013')
    data = [my_columns]
    #取出列标题行
    header_list=worksheet.row_values(0)
    header_index_list = []
    #循环标题列表,找出符合条件列的索引号
    for header_index in range(len(header_list)):
        if header_list[header_index] in my_columns:
            header_index_list.append(header_index)
    for row_index in range(1,worksheet.nrows):
        #用于存放构造好的行数据
        row_list = []
        #循环满足条件的列
        for column_index in header_index_list:
            cell_value = worksheet.cell_value(row_index,column_index)
            cell_type = worksheet.cell_type(row_index,column_index)
            #type=3表示该列类型为日期
            #若该列为日期格式,则格式化日期
            if cell_type == 3:
                date_cell = xldate_as_tuple(cell_value,workbook.datemode)
                date_cell = date(*date_cell[0:3]).strftime('%m/%d/%Y')
                row_list.append(date_cell)
            #否则直接拼接row_list_output
            else:
                row_list.append(cell_value)
        data.append(row_list)
    #此处用迭代的原因是因为,如果直接写入的话,会导致索引也写入到新文件中,写入后的文件会出现空白行的情况
    for list_index,output_list in enumerate(data):
        for element_index,element in enumerate(output_list):
            output_worksheet.write(list_index,element_index,element)
output_workbook.save(output_file)

三、处理工作簿中多个Excel工作表

在处理多个Excel文件时,我们基本的操作和单个相似,有如下三种:

1、选取特定的行;(存在三种情况,请参看二中处理单个文件)

2、选取特定的列;(存在两种方法,请参看二中处理单个文件)

3、选取特定的工作表(一个工作簿中存在多个Excel工作表,有时候我们并不是都需要处理,这个时候我们就可以根据条件来处理相应的文件)

三种情况代码如下:

1、选取特定的行;

'''
读取工作簿中的所有工作表
1、在所有工作表中筛选特定行
'''
import sys
from datetime import date
from xlrd import open_workbook,xldate_as_tuple
from xlwt import Workbook
input_file='E:\\studytest\\data\\excel\\sales_2013.xlsx'
output_file='E:\\studytest\\data\\excel_test\\10output.xlsx'
output_workbook=Workbook()
output_worksheet=output_workbook.add_sheet('filtered_rows_all_worksheets')
sale_column_index = 3
threshold = 2000.0
first_worksheet = True
with open_workbook(input_file) as workbook:
    data = []
    for worksheet in workbook.sheets():
        if first_worksheet:
            header_row=worksheet.row_values(0)
            data.append(header_row)
            first_worksheet= False
        for row_index in range(1,worksheet.nrows):
            row_list = []
            sale_amount=worksheet.cell_value(row_index,sale_column_index)
            if sale_amount > threshold:
                for column_index in range(worksheet.ncols):
                    cell_value = worksheet.cell_value(row_index,column_index)
                    cell_type = worksheet.cell_type(row_index,column_index)
                    if cell_type == 3:
                        date_cell=xldate_as_tuple(cell_value,workbook.datemode)
                        date_cell=date(*date_cell[0:3]).strftime('%m/%d/%Y')
                        row_list.append(date_cell)
                    else:
                        row_list.append(cell_value)
            if row_list:
                data.append(row_list)
    for list_index,output_list in enumerate(data):
        for element_index,element in enumerate(output_list):
            output_worksheet.write(list_index,element_index,element)
output_workbook.save(output_file)

2、筛选特定列:

'''
2、在所有工作表中筛选特定列
    根据前面操作单工作表的代码,我们可以发现这个地方存在两种方法,一是根据索引值;二是根据列标题。我们以第二种为例。
'''
import sys
from datetime import date
from xlrd import open_workbook,xldate_as_tuple
from xlwt import Workbook
input_file='E:\\studytest\\data\\excel\\sales_2013.xlsx'
output_file='E:\\studytest\\data\\excel_test\\10output.xlsx'
output_workbook=Workbook()
output_worksheet=output_workbook.add_sheet('selected_columns_all_worksheets')
#条件,取列标题为XX的两列
my_columns = ['Customer Name','Sale Amount']
first_worksheet = True
with open_workbook(input_file) as workbook:
    data = [my_columns]
    #存放列标题对应的索引值
    index_of_cols_to_keep = []
    for worksheet in workbook.sheets():
        if first_worksheet:
            header_row=worksheet.row_values(0)
            for column_index in range(len(header_row)):
                if header_row[column_index] in my_columns:
                    index_of_cols_to_keep.append(column_index)
            first_worksheet= False
        for row_index in range(1,worksheet.nrows):
            row_list = []
            for column_index in index_of_cols_to_keep:
                cell_value = worksheet.cell_value(row_index,column_index)
                cell_type = worksheet.cell_type(row_index,column_index)
                if cell_type == 3:
                    date_cell=xldate_as_tuple(cell_value,workbook.datemode)
                    date_cell=date(*date_cell[0:3]).strftime('%m/%d/%Y')
                    row_list.append(date_cell)
                else:
                    row_list.append(cell_value)
            data.append(row_list)
    for list_index,output_list in enumerate(data):
        for element_index,element in enumerate(output_list):
            output_worksheet.write(list_index,element_index,element)
output_workbook.save(output_file)

3、选取特定的工作表

'''
3、在excel工作簿中读取一组工作表
'''
import sys
from datetime import date
from xlrd import open_workbook,xldate_as_tuple
from xlwt import Workbook
input_file='E:\\studytest\\data\\excel\\sales_2013.xlsx'
output_file='E:\\studytest\\data\\excel_test\\11output.xlsx'
output_workbook=Workbook()
output_worksheet=output_workbook.add_sheet('set_of_worksheets')
#条件,取索引号为0和1的两个工作表
my_sheets = [0,1]
first_worksheet = True
with open_workbook(input_file) as workbook:
    data = []
    #循环工作簿中每个工作表
    for sheet_index in range(workbook.nsheets):
        #判断是否为需要处理的工作表
        if sheet_index in my_sheets:
            # 找到符合要求的工作表,并取出表内容
            worksheet = workbook.sheet_by_index(sheet_index)
            if first_worksheet:
                header_row=worksheet.row_values(0)
                data.append(header_row)
                first_worksheet= False
            for row_index in range(1,worksheet.nrows):
                row_list = []
                for column_index in range(worksheet.ncols):
                    cell_value = worksheet.cell_value(row_index,column_index)
                    cell_type = worksheet.cell_type(row_index,column_index)
                    if cell_type == 3:
                        date_cell=xldate_as_tuple(cell_value,workbook.datemode)
                        date_cell=date(*date_cell[0:3]).strftime('%m/%d/%Y')
                        row_list.append(date_cell)
                    else:
                        row_list.append(cell_value)
                if row_list:
                    data.append(row_list)
    for list_index,output_list in enumerate(data):
        for element_index,element in enumerate(output_list):
            output_worksheet.write(list_index,element_index,element)
output_workbook.save(output_file)

四、处理多个工作簿

1、工作表计数和每个工作表中行列的计数:

'''
处理多个工作簿
1、工作表计数以及每个工作表中的行列计数
'''
import glob
import os
import sys
from xlrd import open_workbook
input_directory = 'E:\\studytest\\data\\excel'
workbook_counter = 0
for input_file in glob.glob(os.path.join(input_directory,'*.xlsx')):
    workbook = open_workbook(input_file)
    print('Workbook:%s'%os.path.basename((input_file)))
    print('Number of worksheets:%d'%workbook.nsheets)
    for worksheet in workbook.sheets():
        print('Worksheet name:',worksheet.name,'\tRows:',worksheet.nrows,'\tColumns:',worksheet.ncols)
    workbook_counter += 1
print('Number of Excel workbooks:%d'%(workbook_counter))

2、从多个工作簿中连接数据:

下面代码实现的是将多个工作簿中数据放到一个Excel工作表中

'''
2、从多个工作簿中连接数据
'''
import glob
import os
import sys
from datetime import date
from xlrd import open_workbook,xldate_as_tuple
from xlwt import Workbook
input_directory = 'E:\\studytest\\data\\excel'
output_file = 'E:\\studytest\\data\\excel_test\\13output.xlsx'
output_workbook = Workbook()
output_worksheet = output_workbook.add_sheet('all_data_all_workbooks')
data = []
first_worksheet = True
#循环多个工作簿
for input_file in glob.glob(os.path.join(input_directory,'*.xls*')):
   print(os.path.basename(input_file))
   #打开当前工作簿
   with open_workbook(input_file) as workbook:
       #循环当前工作簿的每个工作表
       for worksheet in workbook.sheets():
           if first_worksheet:
               header_row = worksheet.row_values(0)
               data.append(header_row)
               first_worksheet = False
            #循环行
           for row_index in range(1,worksheet.nrows):
               row_list = []
               #循环列
               for column_index in range(worksheet.ncols):
                    cell_value = worksheet.cell_value(row_index,column_index)
                    cell_type = worksheet.cell_type(row_index,column_index)
                    if cell_type == 3:
                        date_cell = xldate_as_tuple(cell_value,workbook.datemode)
                        date_cell = date(*date_cell[0:3]).strftime('%m/%d/%Y')
                        row_list.append(date_cell)
                    else:
                        row_list.append(cell_value)
               data.append(row_list)
for list_index,output_list in enumerate(data):
    for element_index,element in enumerate(output_list):
        output_worksheet.write(list_index,element_index,element)
output_workbook.save(output_file)

3、为每个工作簿和工作表计算总数和均值

'''
3、为每个工作簿和工作表计算总数和均值
'''
import glob
import os
import sys
from datetime import date
from xlrd import open_workbook,xldate_as_tuple
from xlwt import Workbook
input_directory = 'E:\\studytest\\data\\excel'
output_file = 'E:\\studytest\\data\\excel_test\\14output.xlsx'
output_workbook = Workbook()
output_worksheet = output_workbook.add_sheet('sums_and_averages')
all_data = []
#对索引号为3的列求总值和平均值
sale_column_index = 3
#输出文件列标题
header = ['workbook','worksheet','worksheet_total','worksheet_average','workbook_total','workbook_average']
all_data.append(header)
#循环多个工作簿
for input_file in glob.glob(os.path.join(input_directory,'*.xls*')):
   #打开当前工作簿
   with open_workbook(input_file) as workbook:
       #存放当前工作簿所求列的总值
       list_of_totals = []
       # 存放当前工作簿所求列的个数
       list_of_number = []
       workbook_output = []
       #循环当前工作簿的每个工作表
       for worksheet in workbook.sheets():
           #当前工作表所求列总值
           total_sales = 0
           #当前工作表所求列个数
           number_of_sales = 0
           #存放当前工作表的名字,总值,平均值
           worksheet_list = []
           worksheet_list.append(os.path.basename(input_file))
           worksheet_list.append(worksheet.name)
            #循环行
           for row_index in range(1,worksheet.nrows):
               try:
                   total_sales += float(str(worksheet.cell_value(row_index,sale_column_index)))
                   number_of_sales += 1
               except:
                   total_sales += 0
                   number_of_sales += 0
           average_sales = '%.2f'%(total_sales/number_of_sales)
           worksheet_list.append(total_sales)
           worksheet_list.append(float(average_sales))
           list_of_totals.append(total_sales)
           list_of_number.append(float(average_sales))
           workbook_output.append(worksheet_list)
       workbook_total = sum(list_of_totals)
       workbook_average = sum(list_of_totals)/sum(list_of_number)
       for list_element in workbook_output:
           list_element.append(workbook_total)
           list_element.append(workbook_average)
       all_data.extend(workbook_output)

for list_index,output_list in enumerate(all_data):
    for element_index,element in enumerate(output_list):
        output_worksheet.write(list_index,element_index,element)
output_workbook.save(output_file)

由于代码相对基础,所以我只贴出来比较细节的代码结果截图,其余的大家可以根据代码自己实现一下看看效果,使用以上代码只需要修改代码前几号文件的路径即可。

如有什么问题和疑问,请私信我,我会在第一时间帮你解决!谢谢支持


猜你喜欢

转载自blog.csdn.net/zly412934578/article/details/80867624