#!/usr/local/bin/python3
# -*- coding:utf-8 -*-
# 功能:csv與excel文件的相互轉換,可批量轉換
# 作者:wallace wang
# 用法:python3 csv-excel.py 路徑或文件名 [-y] -y默認將路徑下的所有csv文件轉換爲一個excel文件
# 環境:python3 Linux,windows下安裝了python3也可以在命令行下使用
# 使用到的庫:openpyxl, xlrd
import os,sys
import csv
from multiprocessing import pool
try:
import openpyxl as xlsx # 不能處理xls文件
except ModuleNotFoundError:
os.system("pip3 install openpyxl")
import openpyxl as xlsx
from openpyxl.styles import Font, colors, Alignment, PatternFill, fills, Border, Side
try:
import xlrd
except ModuleNotFoundError:
os.system("pip3 install xlrd")
import xlrd
# 表格樣式
def setStyle(sheet, row_height=20, column_width=20):
'''參數:sheet 工作表對象
row_height 行高
column_width 列寬
'''
font = Font(name="等線", size=14, color=colors.BLACK, bold=True) # 字體
fill = PatternFill(fill_type=fills.FILL_SOLID, fgColor='1ac6c0', bgColor="00FF0000") # 填充顏色
align = Alignment(horizontal='center', vertical='center', wrap_text=True) # 數據位置,居中
border = Border(right=Side(border_style='thin', color='808080')) # 邊框
rows = list(sheet.rows)
for row in rows:
if rows.index(row) == 0: # 首行樣式設置
for cell in row:
cell.font = font
cell.fill = fill
cell.alignment = align
cell.border = border
sheet.row_dimensions[cell.row].height = 20
sheet.column_dimensions[cell.column_letter].width = 20
continue
for cell in row: # 其他行樣式設置
cell.alignment = align
cell.border = border
sheet.row_dimensions[cell.row].height = row_height
sheet.column_dimensions[cell.column_letter].width = column_width
return sheet
def xlsx_to_csv(file_path):
print("正在處理" + file_path)
wb = xlsx.load_workbook(file_path) # 讀取excel文件
sheets = wb.get_sheet_names() # 獲取工作表名,返回列表
for sheet_name in sheets: # 遍歷excel文件中的工作表
sheet = wb.get_sheet_by_name(sheet_name) # 獲取表名
file_name = file_path[:-5] + '_' + sheet_name + '.csv' # 構建轉換後的文件名
with open(file_name, 'w', encoding='utf-8') as f:
fileWriter = csv.writer(f)
for row in sheet.rows: # 遍歷所有行
values = []
for cell in row: # 遍歷單元格
values.append(cell.value)
fileWriter.writerow(values) # 寫入csv文件
print(file_name, '.......ok')
def xls_to_csv(file_path):
print("正在處理" + file_path)
wb = xlrd.open_workbook(file_path) # 打開文件
sheets = wb.sheets() # 獲取所有的工作表
for sheet in sheets: # 遍歷工作表
rows = sheet.nrows # 有效行
file_name = file_path[:-4] + '_' + sheet.name + '.csv'
with open(file_name, 'w', encoding='utf-8') as f:
fileWriter = csv.writer(f, delimiter=',')
for row in range(rows):
values = sheet.row_values(row) # 獲取改行所有的數據
fileWriter.writerow(values)
print(file_name, '.......ok')
def csv_to_excel(file_path, YoN='no', path=''):
'''參數: file_path 文件路徑
YoN 表示是否寫入同一個excel文件
說明: 當YoN的值爲yes時,file_path爲列表數據類型;否則file_path爲字符串數據類型
'''
wb = xlsx.Workbook() # 創建excel工作薄對象
if YoN == 'no':
print("正在處理" + file_path)
L = file_path.split('/')
sheet = wb.active
sheet.title = L[-1][:-4] # 設置表標題
with open(file_path, 'r', encoding='utf-8') as f:
data = csv.reader(f)
for row in data: # 將數據寫入工作表
sheet.append(row)
cols = sheet.max_column
index = ['列名'+ str(i) for i in range(1, cols+1)] # 首行標題
sheet.insert_rows(0, 1)
first_row = list(sheet.rows)[0]
for cell in first_row:
cell.value = index[first_row.index(cell)]
sheet = setStyle(sheet) # 設置表格樣式,行高列寬可根據需要自行傳參
sheet.freeze_panes = 'B2' # 凍結第一行第一列
file_name = file_path[:-4] + '.xlsx'
wb.save(file_name)
print(file_name, '.......ok')
else:
L = [os.path.basename(item) for item in file_path] # 提取路徑中的csv文件名
sheet_name = [name[:-4] for name in L] # 提取文件名中的表名
# print(sheet_name)
for title in sheet_name: # 遍歷工作表
print('正在處理' + file_path[sheet_name.index(title)])
if sheet_name.index(title) != 0:
sheet = wb.create_sheet(title) # 創建工作表
else:
sheet = wb.active
with open(file_path[sheet_name.index(title)], 'r', encoding='utf-8') as f:
data = csv.reader(f)
for row in data: # 將數據寫入工作表
sheet.append(row)
cols = sheet.max_column
index = ['列名' + str(i) for i in range(1, cols+1)] # 首行標題
sheet.insert_rows(0, 1)
first_row = list(sheet.rows)[0]
for cell in first_row:
cell.value = index[first_row.index(cell)]
sheet = setStyle(sheet) # 設置表格樣式,行高列寬可根據需要自行傳參
sheet.freeze_panes = 'B2' # 凍結第一行第一列
# 構建轉換後的文件名
file_name = path + 'out.xlsx'
wb.save(file_name)
print(file_name, '.......ok')
def main():
try:
path = sys.argv[1]
except:
print("請輸入文件或路徑")
return 0
if os.path.isfile(path):
if path[-5:] == '.xlsx':
xlsx_to_csv(path)
elif path[-4:] == '.xls':
xls_to_csv(path)
elif path[-4:] == '.csv':
csv_to_excel(path)
else:
print('不支持的文件格式')
elif os.path.isdir(path):
if path[-1] != '/':
path += '/'
excels = []
for excelfile in os.listdir(path): # 檢測指定目錄下的excel文件
if excelfile[-4:] == '.xls' or excelfile[-5:] == '.xlsx':
excels.append(excelfile)
csvfiles = []
for csvfile in os.listdir(path): # 檢測指定目錄下的csv文件
if csvfile[-4:] == '.csv':
csvfiles.append(csvfile)
files = excels + csvfiles
if len(files) < 2:
print("該目錄下沒有檢測可以轉換的文件")
return 0
if len(csvfiles) >= 2 and '-y' in sys.argv:
select = [path + fn for fn in csvfiles]
csv_to_excel(select, YoN='yes', path=path)
return 0
print("檢測到以下可轉換的文件:")
for f in files:
print(files.index(f), path + f)
indexs = input('請選擇要轉換的文件序號(批量轉換用","隔開):')
indexs = indexs.split(',')
selectfile = []
for i in indexs:
try:
selectfile.append(files[int(i)])
except:
continue
if len(selectfile)>=2 and set(selectfile) < set(csvfiles):
YoN = input("是否寫入同一個excel文件(yes/no):")
if YoN == 'yes' or YoN == 'y':
select = [path + fn for fn in selectfile]
csv_to_excel(select, YoN='yes', path=path)
return 0
for i in indexs:
try:
i = int(i)
except:
continue
if files[i][-4:] == '.xls':
xls_to_csv(path + files[i])
elif files[i][-4:] == '.csv':
csv_to_excel(path + files[i])
elif files[i][-5:] == '.xlsx':
xlsx_to_csv(path + files[i])
else:
print("不支持的文件格式")
else:
print("文件或目錄不存在")
if __name__ == '__main__':
main()