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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章