python 之csv文件与excel文件的相互转换,可批量转换

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

发布了8 篇原创文章 · 获赞 5 · 访问量 1156
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章