# -*- coding: UTF-8 -*-
# @File: operation_Xlsx.py
# @Description: excle的基本操作
# @Author: WenQing
# @Date: 2021-08-26 11:15:08
import os
import xlrd, xlwt
import pandas as pd
from xlutils.copy import copy
import openpyxl
from base_framework.base_config.current_pth import env_choose_path
from base_framework.public_tools.read_config import ReadConfig


class ExcelApi:
    def __init__(self):
        self.p_here = os.path.dirname(os.path.abspath(__file__))
        self.c_team = ReadConfig(env_choose_path).get_value(sections='run_evn_name', options='current_team')
        self.up_file_path = os.path.abspath(os.path.join(self.p_here, '../../{}/library/UpFile/'.format(self.c_team)))

    def excel_create_excel_file(self, file_name, file_dict_data=None, file_path=None):
        """
        功能：按列将数据写入excel文件，没有文件时就新建文件
        Args:
            file_name: 文件名
            file_dict_data: 文件内容，字典类型，格式：{'title1':[], 'title2':[],..... 'titleN':[],}
            file_path: 文件路径，没有时默认放在小组目录下的UpFile文件夹中
        Returns:
        """
        if not file_path:
            full_path = self.up_file_path + os.sep + file_name
        else:
            full_path = file_path + os.sep + file_name
        if not file_dict_data:
            file_dict_data = {}
        df = pd.DataFrame(file_dict_data)
        # 将 DataFrame 的数据保存到 Excel 文件中
        df.to_excel(full_path, index=False)

    def excel_create_file_by_column(self, file_name, file_dict_data=None, file_path=None):
        """
        功能：按列将数据写入excel文件，没有文件时就新建文件
        Args:
            file_name: 文件名
            file_dict_data: 文件内容，字典类型，格式：{'title1':[], 'title2':[],..... 'titleN':[],}
            file_path: 文件路径，没有时默认放在小组目录下的UpFile文件夹中
        Returns:
        """
        if not file_path:
            full_path = self.up_file_path + os.sep + file_name
        else:
            full_path = file_path + os.sep + file_name
        if not file_dict_data:
            file_dict_data = {}
        df = pd.DataFrame(file_dict_data)
        # 将 DataFrame 的数据保存到 Excel 文件中
        df.to_excel(full_path, index=False)

    def excel_write_file_by_line(self, file_name, line_data=None, file_path=None, w_type='new'):
        """
        功能：按行将数据写入excel文件，没有文件时就新建文件
        Args:
            file_name: 文件名
            line_data: 文件内容，列表类型，格式：[[字段1,字段2],[字段1,字段2]]
            file_path: 文件路径，没有时默认放在小组目录下的UpFile文件夹中
            w_type: 写入类型：new-重写，append-追加
        """
        if not file_path:
            full_path = self.up_file_path + os.sep + file_name
        else:
            full_path = file_path + os.sep + file_name
        if w_type == 'new':
            self.write_xlsx(path=full_path, sheet_name="Sheet1", value=line_data)
        elif w_type == 'append':
            self.append_xlsx(path=full_path, value=line_data)
        else:
            raise Exception("目前仅支持new和append两种模式，而当前传入的是；{}".format(w_type))

    def excel_replace_cell_value(self, file_name, replace_dict, sheet_name=None, skip_first_row=True):
        """
        功能：替换excel文件中的指定单元格的值
        Args:
            file_name: 文件名,如果文件不在UpFile文件夹中，需要传入完整路径
            sheet_name: 工作表名称,默认为全部工作表
            replace_dict: 替换的数据，字典类型，格式：{'old_txt_1': 'new_txt_1', 'old_txt_2': 'new_txt_2',..... }
            skip_first_row: 是否跳过第一行，默认跳过,用于第一行是标题的情况
        Returns:
        """
        if "/" not in file_name:  # 如果没有路径，就默认在UpFile文件夹中
            file_name = self.up_file_path + os.sep + file_name
        # 读取指定工作表的数据
        wb = openpyxl.load_workbook(file_name)
        # 遍历所有要替换的数据
        for old_text, new_text in replace_dict.items():
            # 遍历所有工作表
            for sheet in wb.worksheets:
                # 遍历工作表中的所有行和列
                for row in sheet.iter_rows():
                    if skip_first_row:  # 跳过第一行
                        skip_first_row = False
                        continue
                    for cell in row:
                        if cell.value == old_text:
                            cell.value = new_text
        wb.save(file_name)

    def excel_read_columns(self, file_name, sheet_name, column_names):
        """
        功能：按列读取excel文件的数据
        Args:
            file_name:  文件名，如果文件不在UpFile文件夹中，需要传入完整路径
            sheet_name: 工作表名称
            column_names: 列名列表，格式：['title1', 'title2',..... 'titleN']
        Returns:
            返回指定列的数据，格式为：[[字段1,字段2],[字段1,字段2]]
        """
        if "/" not in file_name:  # 如果没有路径，就默认在UpFile文件夹中
            file_name = self.up_file_path + os.sep + file_name
        # 读取指定工作表的数据
        df = pd.read_excel(file_name, sheet_name=sheet_name)

        # 检查指定列是否存在
        missing_columns = [col for col in column_names if col not in df.columns]
        if missing_columns:
            raise ValueError(f"Columns {missing_columns} do not exist in the sheet '{sheet_name}'.")

        # 返回指定列的数据
        return df[column_names].values.tolist()

    def read_asDict(self, path):
        """
            | 功能说明： | 读取excle,输出字典格式|
            | 传入参数： | 读取文件路径 |
            | 返回数据： | 表头字段作为key,单元格值作为value |
            | 作者信息： | 作者  文青  | 修改时间      |
            举例说明：
        """
        self.table = pd.read_excel(path)
        data = []
        for i in self.table.index.values:
            data_dict = self.table.loc[i].to_dict()
            data.append(data_dict)
        return data

    def read_asList(self, path, sheetname=None):
        """
            | 功能说明： | 读取excle和sheetname,输出列表格式|
            | 传入参数： | 读取excle和sheetname |
            | 返回数据： | 列表[] |
            | 作者信息： | 作者  文青  | 修改时间      |
            举例说明：
        """
        wb = openpyxl.load_workbook(path)
        if not sheetname:
            sheets = wb.sheetnames
            sheetname = sheets[0]
        ws = wb[sheetname]
        rows = ws.rows
        columns = ws.columns
        data = []
        for row in rows:
            line = [col.value for col in row]
            data.append(line)
        return data

    def read_xls_txt(self, path):
        """
            | 功能说明： | 读取excle的第一列放在一个列表中|
            | 传入参数： | 读取excle路径 |
            | 返回数据： | 列表[] |
            | 作者信息： | 作者  文青  | 修改时间      |
            举例说明：
        """
        data = pd.read_excel(path, header=None)
        data_list = []
        nrows = data.shape[0]
        for irow in range(nrows):
            data_list.append(data.iloc[irow, 0])
        string = ''
        for i in range(len(data_list)):
            string += data_list[i] + ','
        return string

    def write_xls(self, value, sheetname, path):
        """
            | 功能说明： | 创建一个xls的文件并且写入数据 |
            | 传入参数： | value:传入列表,格式:[[字段1,字段2],[字段1,字段2],[字段1,字段2],[字段1,字段2]] |
                       |sheetname:sheet名称 |
                       |path:写入文件路径 |
            | 返回数据： |   |
            | 作者信息： | 作者  文青  | 修改时间      |
            举例说明：
        """
        index = len(value)  # 获取需要写入数据的行数
        workbook = xlwt.Workbook()  # 新建一个工作簿
        sheet = workbook.add_sheet(sheetname=sheetname)  # 在工作簿中新建一个sheetname的表格
        for i in range(0, index):
            for j in range(0, len(value[i])):
                sheet.write(i, j, value[i][j])
        workbook.save(path)
        # return "写入成功！"

    def append_xls(self, value, path):
        """
            | 功能说明： | 对xls文件第一个sheet内容进行追加 |
            | 传入参数： | value:传入列表,格式:[[字段1,字段2],[字段1,字段2],[字段1,字段2],[字段1,字段2]] |
                       |path:写入文件路径 |
            | 返回数据： |   |
            | 作者信息： | 作者  文青  | 修改时间      |
            举例说明：
        """
        index = len(value)  # 获取需要写入数据的行数
        workbook = xlrd.open_workbook(path)  # 打开工作簿
        sheets = workbook.sheet_names()  # 获取所有表格
        worksheet = workbook.sheet_by_name(sheets[0])  # 获取所有表格中的第一个表格
        rows_old = worksheet.nrows  # 获取表格的总行数
        new_workbook = copy(workbook)  # 把原文件复制一份
        new_worksheet = new_workbook.get_sheet(0)  # 获取副本第一个表格
        for i in range(0, index):
            for j in range(0, len(value[i])):
                new_worksheet.write(i + rows_old, j, value[i][j])
        new_workbook.save(path)
        # return "追加成功！！"

    def write_xlsx(self, path, sheet_name, value):
        """
            | 功能说明： | 创建一个xls的文件并且写入数据 |
            | 传入参数： | value:传入列表,格式:[[字段1,字段2],[字段1,字段2],[字段1,字段2],[字段1,字段2]] |
                       |sheetname:sheet名称 |
                       |path:写入文件路径 |
            | 返回数据： |   |
            | 作者信息： | 作者  文青  | 修改时间      |
            举例说明：
        """
        index = len(value)
        workbook = openpyxl.Workbook()
        sheet = workbook.active
        sheet.title = sheet_name
        for i in range(0, index):
            for j in range(0, len(value[i])):
                sheet.cell(row=i + 1, column=j + 1, value=str(value[i][j]))
        workbook.save(path)
        return "写入成功！！"

    def append_xlsx(self, path, value):
        """
            | 功能说明： | 对xls文件第一个sheet内容进行追加 |
            | 传入参数： | value:传入列表,格式:[[字段1,字段2],[字段1,字段2],[字段1,字段2],[字段1,字段2]] |
                       |path:写入文件路径 |
            | 返回数据： |   |
            | 作者信息： | 作者  文青  | 修改时间      |
            举例说明：
        """
        data = openpyxl.load_workbook(path)
        sheets = data.sheetnames
        table = data[sheets[0]]
        for i in value:
            table.append(i)
        data.save(path)
        return "追加成功！！"


if __name__ == '__main__':
    ea = ExcelApi()
    f_data = {"教师ID": [1, 2, 3, 4],
              "教师姓名": [11, 22, 33, 44],
              "课程ID": [111, 222, 333, 444],
              "课程名称": [1111, 2222, 3333, 4444],
              "更新类型（1.新增；0.删除，填写数字）": [0, 1, 0, 1]
              }
    ea.excel_create_excel_file(file_name="测试大盘A标签.xlsx", file_dict_data=f_data)

