#!/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()