#!/usr/bin/python
# -*- coding: utf-8 -*-
# @version        : 1.0
# @Create Time    : 2022/11/11 12:01 
# @File           : write_xlsx.py
# @IDE            : PyCharm
# @desc           : 简要说明

"""
XlsxWriter:https://github.com/jmcnamara/XlsxWriter
博客教程:https://blog.csdn.net/lemonbit/article/details/113855768
"""

import os.path
import xlsxwriter
from typing import List
from application.settings import STATIC_ROOT, STATIC_URL
from utils.file.file_base import FileBase
from pathlib import Path


class WriteXlsx:
    """
    写入xlsx文件
    """

    def __init__(self):
        self.file_path = None
        self.sheet_name = None
        self.wb = None
        self.sheet = None

    def create_excel(self, file_path: str = None, sheet_name: str = "sheet1", save_static: bool = False) -> None:
        """
        创建 excel 文件
        :param file_path: 文件绝对路径或相对路径
        :param sheet_name: sheet 名称
        :param save_static: 保存方式 static 静态资源或者临时文件
        :return:
        """
        if not file_path:
            if save_static:
                self.file_path = FileBase.generate_static_file_path(path="write_xlsx", suffix="xlsx")
            else:
                self.file_path = FileBase.generate_temp_file_path(suffix="xlsx")
        elif not os.path.isabs(file_path):
            if save_static:
                self.file_path = FileBase.generate_static_file_path(path="write_xlsx", filename=file_path)
            else:
                self.file_path = FileBase.generate_temp_file_path(filename=file_path)
        else:
            self.file_path = file_path
        Path(self.file_path).parent.mkdir(parents=True, exist_ok=True)
        self.sheet_name = sheet_name
        self.wb = xlsxwriter.Workbook(self.file_path)
        self.sheet = self.wb.add_worksheet(sheet_name)

    def generate_template(self, headers: List[dict] = None, max_row: int = 101) -> None:
        """
        生成模板
        :param headers: 表头
        :param max_row: 设置下拉列表至最大行
        :return: 文件链接地址
        """
        max_row = max_row + 100
        for index, field in enumerate(headers):
            font_format = {
                'bold': False,  # 字体加粗
                'align': 'center',  # 水平位置设置:居中
                'valign': 'vcenter',  # 垂直位置设置,居中
                'font_size': 11,  # '字体大小设置'
            }
            if field.get("required", False):
                # 设置单元格必填样式
                field["label"] = "* " + field["label"]
                font_format["font_color"] = "red"
            if field.get("options", False):
                # 添加数据验证,下拉列表
                validate = {'validate': 'list', 'source': [item.get("label") for item in field.get("options", [])]}
                self.sheet.data_validation(1, index, max_row, index, validate)
            cell_format = self.wb.add_format(font_format)
            self.sheet.write(0, index, field.get("label"), cell_format)
        # 设置列宽
        self.sheet.set_column(0, len(headers) - 1, 22)
        # 设置行高
        self.sheet.set_row(0, 25)

    def write_list(self, rows: list, start_row: int = 1) -> None:
        """
        写入 excel文件

        :param rows: 行数据集
        :param start_row: 开始行
        """
        font_format = {
            'bold': False,  # 字体加粗
            'align': 'center',  # 水平位置设置:居中
            'valign': 'vcenter',  # 垂直位置设置,居中
            'font_size': 11,  # '字体大小设置'
        }
        cell_format = self.wb.add_format(font_format)
        for index, row in enumerate(rows):
            row_number = index+start_row
            self.sheet.write_row(row_number, 0, row, cell_format)
        # 设置列宽
        self.sheet.set_column(0, len(rows[0]) - 1, 22)
        # 设置行高
        self.sheet.set_default_row(25)

    def close(self) -> None:
        """
        关闭文件
        """
        self.wb.close()

    def get_file_url(self) -> str:
        """
        获取访问文件的 url
        :return:
        """
        if not self.file_path:
            raise ValueError("还未创建文件,请先创建 excel 文件!")
        assert isinstance(self.file_path, str)
        if self.file_path.startswith(STATIC_ROOT):
            return self.file_path.replace(STATIC_ROOT, STATIC_URL)
        else:
            print("write_xlsx 生成文件:", self.file_path)
            raise ValueError("生成文件为临时文件,无法访问!")