項(xiàng)目下載github
前言:這個(gè)操作Excel表格相關(guān)內(nèi)容找了很久,很多代碼都達(dá)不到想要的效果,但最后還是功夫不負(fù)有心人啊。
一、開始之前的準(zhǔn)備工作
和自動(dòng)化辦公系列1這篇一樣:自動(dòng)化辦公系列1
二、開始多表(個(gè)人信息表)導(dǎo)入單表內(nèi)容(匯總信息表)中
需求:由于經(jīng)常需要對(duì)一些現(xiàn)有的表如個(gè)人信息表進(jìn)行匯總,全部匯總到一張表內(nèi),正常情況情況下就是一頓粘貼復(fù)制咯,有點(diǎn)累吧!那就讓程序來(lái)完成。
1、創(chuàng)建py文件的時(shí)候注意,2.7.15版本默認(rèn)編碼格式不是utf-8,而我們一般操作字符都是以u(píng)tf-8的方式,故需要添加一些代碼把編碼格式轉(zhuǎn)為utf-8。python3之后默認(rèn)格式都是utf-8了。
在文件開頭添加如下代碼:
#coding=utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
2、操作xlsx文件需要導(dǎo)入的模塊
2.1、 xlrd (讀取xls的文件內(nèi)容)
2.2、 openpyxl(把內(nèi)容寫入到xlsx文件中)
2.3、 pywin32 (方便調(diào)用windowsAPI)
3、開始編寫腳本
#coding=utf-8
import sys
import xlrd
import os
import openpyxl
import time
import pythoncom
import win32com.client as win32
reload(sys)
sys.setdefaultencoding('utf-8')
# 讀取路徑下的所有文件名
def read_file_name(file_dir):
L = []
for root,dirs,files in os.walk(file_dir):
for file in files:
L.append(file)
return L
# 進(jìn)行xls到xlsx的轉(zhuǎn)換
def xlstoxlsx(filePath):
if filePath.find('xls'):
pythoncom.CoInitialize()
excel = win32.gencache.EnsureDispatch('Excel.Application')
filePath1 = filePath.decode('utf-8').encode('gbk')
wb = None
try:
wb = excel.Workbooks.Open(filePath1)
wb.SaveAs(filePath1 + 'x', FileFormat=51) # FileFormat = 51 is for .xlsx extension
print "xls轉(zhuǎn)為xlsx的絕對(duì)路徑為"+filePath + 'x'
except IOError:
print '文件讀寫錯(cuò)誤'
finally:
wb.Close()
excel.Application.Quit()
time.sleep(2) # 避免未及時(shí)關(guān)閉的情況,等待關(guān)閉完成
return filePath1 + 'x'
# 進(jìn)行xlsx到xls的轉(zhuǎn)換
def xlsxtoxls(file,filePath):
if file.find('xlsx'):
pythoncom.CoInitialize()
excel = win32.gencache.EnsureDispatch('Excel.Application')
file = file.decode('utf-8').encode('gbk')
# 去除末尾的x[-1:]
# filepaths = filePath.split('.')
# filePath1 = filepaths[0]
filePath1 = "{}".format(filePath[:-4])
filePath1 = filePath1.decode('utf-8').encode('gbk')
# 打開文件需要進(jìn)行異常捕獲和關(guān)閉文件
wb = None
try:
wb = excel.Workbooks.Open(file)
wb.SaveAs(filePath1 + '.xls', FileFormat=56) # FileFormat = 51 is for .xlsx extension
print filePath1 + '.xls'
except IOError:
print '該文件讀寫發(fā)生錯(cuò)誤'
finally:
wb.Close()
excel.Application.Quit()
time.sleep(1) # 避免未及時(shí)關(guān)閉的情況,等待關(guān)閉完成
return filePath1 + '.xls'
# 寫入到execel表格
# 先打開原表然后復(fù)制一份最后另存為
# values為單表內(nèi)容總和 startCol為開始的列數(shù) row為開始的行數(shù) col為爬取的內(nèi)容數(shù)
def wExecel(path,row,col,startCol,values):
# 這里最開始先判斷一下填的路徑是否存在
print "是否存在路徑判斷"+path
if os.path.isfile(path.decode('utf-8').encode('gbk')):
# 這里需要對(duì)路徑文件格式進(jìn)行判斷一個(gè)if語(yǔ)句
if path.find('xlsx') != -1: # 把xlsx轉(zhuǎn)為xls,會(huì)把原路徑的xlsx文件替換
xlsxPath = path.decode('utf-8').encode('gbk')
print xlsxPath.decode('gbk').encode('utf-8') #為了方便控制臺(tái)查看轉(zhuǎn)為utf-8
else:
print '文件格式為:xls'
xlsxPath = xlstoxlsx(path)
# 轉(zhuǎn)換完成之后需要把原來(lái)xls這個(gè)文件刪除
path = path.decode('utf-8').encode('gbk')
# os.remove(path)
# print '原xls文件已刪除'
# wb = None
try:
wb = openpyxl.load_workbook(xlsxPath) # 打開這個(gè)xlsx文件得到wb對(duì)象
sheetnames = wb.get_sheet_names() # 獲取文件內(nèi)的所有表格
# sheet = wb.get_sheet_by_name(sheetnames[0])
for sheetname in sheetnames: # 遍歷這個(gè)文件的內(nèi)的所有表格 這里只取第一個(gè)表
sheet = wb.get_sheet_by_name(sheetname) # 取sheet表
# print "遍歷的表格數(shù)" + str(j)
# range(start,stop,step) 開始 結(jié)束(不包括) 步長(zhǎng)
for num in range(0, len(values)-(col-1), col): # col每次遍歷跳過(guò)的數(shù) 以col的數(shù)量為單位 len(values)一定是col的整數(shù)倍
for a in range(0, col): # 對(duì)一行數(shù)據(jù)進(jìn)行操作 一共col列循環(huán)col次
value = str(values[num+a]) # 獲取內(nèi)容
# value = value.decode('utf-8').encode('gbk')
print "寫入的內(nèi)容" + value
sheet.cell(row, startCol+a).value = value # 把內(nèi)容寫入到匯總表對(duì)應(yīng)位置
row += 1
break
# j += 1
# 這里保存的路徑需要修改,只需要路徑名
print "最終保存路徑---->"+xlsxPath.decode('gbk').encode('utf-8') #為了方便控制臺(tái)查看轉(zhuǎn)為utf-8
wb.save(xlsxPath)
except IOError:
print 'IO讀寫錯(cuò)誤----->107'
else:
print "你填入的導(dǎo)出路徑不存在請(qǐng)重新填寫"
# 該函數(shù)抓取導(dǎo)入的多張表的某些指定內(nèi)容,內(nèi)容指定由坐標(biāo)表示
# 因?yàn)樯婕暗揭粋€(gè)文件可能存在多個(gè)表的問(wèn)題所以要以表為單位進(jìn)行內(nèi)容抓取
def rwExecel(Rpath,eList_col,eList_entry):
# global list_col
xlsPath = Rpath
xls = None
# 這里需要對(duì)路徑文件格式進(jìn)行判斷一個(gè)if語(yǔ)句
if 'xlsx' in Rpath: # 把xlsx轉(zhuǎn)為xls,會(huì)把原路徑的xlsx文件替換為xls,讀的時(shí)候只能操作xls表格
print '文件格式為:xlsx'
xlsPath = xlsxtoxls(Rpath,Rpath)
# 轉(zhuǎn)換完成之后需要把原來(lái)xlsx這個(gè)文件刪除
path = Rpath.decode('utf-8').encode('gbk')
os.remove(path)
print '文件已刪除'
print xlsPath.decode('gbk').encode('utf-8') #為了方便控制臺(tái)查看轉(zhuǎn)為utf-8
# xls = xlrd.open_workbook(xlsPath)
else:
# xlsPath = xlsPath.decode('utf-8').encode('gbk')
print xlsPath.decode('gbk').encode('utf-8') #為了方便控制臺(tái)查看轉(zhuǎn)為utf-8
# --------對(duì)xlsx文件內(nèi)的所有表格都進(jìn)行判斷是否有內(nèi)容-----------
xls = xlrd.open_workbook(xlsPath)
tables = xls.sheets() # 獲取文件所有表格這樣就不需要表的標(biāo)號(hào)和名稱了
sheet_name = xls.sheet_names()
print sheet_name
for table in tables: # 如何判斷一個(gè)表是否有內(nèi)容
if table.nrows == 0: # 查看表的有效函數(shù)是否為0
continue # 直接進(jìn)入下一個(gè)循環(huán)
# 通過(guò)遍歷elist_entry來(lái)獲得對(duì)應(yīng)坐標(biāo),每三個(gè)為一個(gè)單位獲取
for num in range(0,len(eList_entry)-2,3):
# 只讀入有效坐標(biāo)只有行或列或者全沒(méi)有不讀入直接跳入下一個(gè)循環(huán)
if (eList_entry[num+1]!='' and eList_entry[num+2]!='') and (eList_entry[num+1]!=None and eList_entry[num+2]!=None):
r = int(eList_entry[num+1]) # 第二個(gè)是行
c = int(eList_entry[num+2]) # 第三個(gè)是列
eList_col.append(table.cell_value(r,c)) # 爬取表格內(nèi)容
print '每次爬取內(nèi)容' + str(table.cell_value(r,c))
else:
continue
# wExecel(Wpath,eRow,eCol,eList_col) #寫入的文件路徑
# del eList_col[:] #每次執(zhí)行完一行清空列表
# eRow = eRow + 1
return eList_col # 返回裝載所有多表信息的列表
# 爬取表格內(nèi)容并復(fù)制到表格力功能A
# 多個(gè)表格內(nèi)容復(fù)制到另一個(gè)表,一個(gè)表的內(nèi)容就是一行
def deal_Excel_A(start_row_col,content_row_col,importPath,exportPath):
print u"開始執(zhí)行任務(wù)"
print '用戶輸入行數(shù)'+start_row_col[0]
row = int(start_row_col[0]) + 1 # 獲得用戶輸入的開始行數(shù)
print '用戶輸入列數(shù)'+start_row_col[1]
col = int(start_row_col[1]) + 1 # 獲得用戶輸入的開始列數(shù)
list_col = [] # 用來(lái)保存一個(gè)人的表格內(nèi)容
list_entry = content_row_col # 獲得用戶輸入的行和列
allFilesNames = read_file_name(importPath) # 獲取每個(gè)xls的表名
i = 0
for fileName in allFilesNames: # 遍歷每個(gè)表名
print fileName.decode('gbk').encode('utf-8') # 打印獲得的每個(gè)表名 #為了方便控制臺(tái)查看轉(zhuǎn)為utf-8
list_col = rwExecel(importPath + '/' + fileName,
list_col, list_entry) # 抓取一張表的內(nèi)容然后暫存到list_col
i += 1
print '遍歷的表格文件數(shù)目---->' + str(i)
# 讀內(nèi)容到列表完畢后進(jìn)行統(tǒng)一寫入操作
wExecel(exportPath, row, len(list_entry)/3, col, list_col) # 把list_col的內(nèi)容全部寫入新的xlsx文件內(nèi)
# -------需要提供的數(shù)據(jù)--------
start_row_col = ["1","1"] # 最終導(dǎo)入的單表->數(shù)組第0個(gè)為開始行 數(shù)組第1個(gè)為開始列
content_row_col = ["姓名","0","1", "年齡","0","3", "出生日期","1","1"] # 抓取的坐標(biāo)以及內(nèi)容名稱(表明這個(gè)坐標(biāo)抓取的東西方便查看)
if __name__ == '__main__':
deal_Excel_A(start_row_col,content_row_col,"I:/pythonProject/xls_operation/importPath",
"I:/pythonProject/xls_operation/exportPath/某機(jī)構(gòu)匯總表.xls")
4、使用方式
1、新建兩個(gè)文件夾
2、在對(duì)應(yīng)的文件夾放入對(duì)應(yīng)的文件
3、按照對(duì)應(yīng)規(guī)則填入?yún)?shù)
注意:excecl表格的坐標(biāo)是從0開始的,如第一個(gè)格子的位置為0,0
# -------需要提供的數(shù)據(jù)--------
start_row_col = ["1","1"] # 最終導(dǎo)入的單表->數(shù)組第0個(gè)為開始行 數(shù)組第1個(gè)為開始列
content_row_col = ["姓名","0","1", "年齡","0","3", "出生日期","1","1"] # 抓取的坐標(biāo)以及內(nèi)容名稱(表明這個(gè)坐標(biāo)抓取的東西方便查看)
if __name__ == '__main__':
deal_Excel_A(start_row_col,content_row_col,"I:/pythonProject/xls_operation/importPath",
"I:/pythonProject/xls_operation/exportPath/某機(jī)構(gòu)匯總表.xls")
4.開始執(zhí)行程序
可以看到多出了一個(gè)xlsx的文件
查看內(nèi)容后發(fā)現(xiàn)數(shù)據(jù)已經(jīng)填入了,這里從左到右填入的順序是由你填入?yún)?shù)的那個(gè)數(shù)組順序決定的,后面的數(shù)字代表就是個(gè)人信息表內(nèi)容每個(gè)格子的坐標(biāo)
content_row_col = ["姓名","0","1", "年齡","0","3", "出生日期","1","1"]
使用注意事項(xiàng):
1、如果只是單純的使用,復(fù)制我的代碼按照之前說(shuō)的環(huán)境即win10,python2.7.15下是可以正常使用的。
2、使用時(shí)請(qǐng)關(guān)閉Excel或者wps等軟件。
3、程序中只使用了xlsToxlsx()函數(shù),還有一個(gè)xlsxToxls()沒(méi)使用,所以該方法刪除也不影響腳本運(yùn)行。
注:轉(zhuǎn)載請(qǐng)注明出處
本文如果對(duì)你有幫助的話希望能給我點(diǎn)個(gè)贊哦~