import xlwt
import time
import os
from django.conf import settings
from datetime import datetime
from openpyxl import Workbook, styles
from openpyxl.drawing.image import Image
from openpyxl.utils import get_column_letter, column_index_from_string
from docxtpl import DocxTemplate


def export_docx(template_path: str, context_data: dict, file_name: str):
    """
    Word导出
    :param template_path: 模板路径
    :param context_data: 数据
    :param file_name: 保存的文件名
    :return:返回文件路径
    """
    docx = DocxTemplate(settings.BASE_DIR + template_path)
    docx.render(context_data)
    file_path = f'/media/temp/{file_name}'
    save_path = settings.BASE_DIR + file_path
    docx.save(save_path)
    return file_path


def len_byte(value):
    # 获取字符串长度，一个中文的长度为2
    length = len(value)
    utf8_length = len(value.encode('utf-8'))
    length = (utf8_length - length) / 2 + length
    return int(length)


def export_excel(field_data: list, data: list, FileName: str):
    """
    Excel导出
    :param data: 数据源
    :param field_data: 首行数据源（表头）
    :param file_path: 文件保存路径（默认保存在media路径）
    :param FileName: 文件保存名字
    :return:返回文件的下载url完整路径
    """
    wbk = xlwt.Workbook(encoding='utf-8')
    # 第二参数用于确认同一个cell单元是否可以重设值。
    sheet = wbk.add_sheet('Sheet1', cell_overwrite_ok=True)
    style = xlwt.XFStyle()  # 赋值style为XFStyle()，初始化样式
    # 设置居中
    wbk.set_colour_RGB(0x23, 0, 60, 139)
    xlwt.add_palette_colour("custom_colour_35", 0x23)
    tab_al = xlwt.Alignment()
    tab_al.horz = 0x02  # 设置水平居中
    tab_al.vert = 0x01  # 设置垂直居中
    # 设置表头单元格背景颜色
    tab_pattern = xlwt.Pattern()  # 创建一个模式
    tab_pattern.pattern = xlwt.Pattern.SOLID_PATTERN  # 设置其模式为实型
    tab_pattern.pattern_fore_colour = 55
    # 设置单元格内字体样式
    tab_fnt = xlwt.Font()  # 创建一个文本格式，包括字体、字号和颜色样式特性
    tab_fnt.height = 200
    default_width = 14
    tab_fnt.name = u'楷体'  # 设置其字体为微软雅黑
    tab_fnt.colour_index = 1  # 设置其字体颜色
    # 设置单元格下框线样式
    tab_borders = xlwt.Borders()
    tab_borders.left = xlwt.Borders.THIN
    tab_borders.right = xlwt.Borders.THIN
    tab_borders.top = xlwt.Borders.THIN
    tab_borders.bottom = xlwt.Borders.THIN
    tab_borders.left_colour = 23
    tab_borders.right_colour = 23
    tab_borders.bottom_colour = 23
    tab_borders.top_colour = 23
    # 把数据写入excel中
    # 所有表格单元格样式
    # 先生成表头
    style.alignment = tab_al  # 设置居中
    style.pattern = tab_pattern  # 设置表头单元格背景颜色
    style.font = tab_fnt  # 设置单元格内字体样式
    style.borders = tab_borders
    for index, ele in enumerate(field_data):
        # (列开始, 列结束, 行开始, 行结束, '数据内容')
        sheet.write_merge(0, 0, index, index, ele, style)

    # 确定栏位宽度
    col_width = []
    for index, ele in enumerate(data):
        for inx, values in enumerate(ele):
            if index == 0:
                col_width.append(len_byte(str(values)))
            else:
                if col_width[inx] < len_byte(str(values)):
                    col_width[inx] = len_byte(str(values))
    # 设置栏位宽度，栏位宽度小于10时候采用默认宽度
    for i in range(len(col_width)):
        if col_width[i] > 10:
            width = col_width[i] if col_width[i] < 36 else 36
            sheet.col(i).width = 256 * (width + 6)
        else:
            sheet.col(i).width = 256 * (default_width)

    row = 1
    # 内容背景颜色
    left_pattern = xlwt.Pattern()  # 创建一个模式
    left_pattern.pattern = xlwt.Pattern.SOLID_PATTERN  # 设置其模式为实型
    left_pattern.pattern_fore_colour = 1

    # 设置单元格内字体样式
    left_fnt = xlwt.Font()  # 创建一个文本格式，包括字体、字号和颜色样式特性
    left_fnt.height = 200
    left_fnt.name = u'楷体'  # 设置其字体为微软雅黑
    left_fnt.colour_index = 0  # 设置其字体颜色

    left_style = style
    left_style.pattern = left_pattern
    left_style.font = left_fnt

    for results in data:
        for index, values in enumerate(results):
            sheet.write(row, index, label=values, style=left_style)
        row += 1

    FileNameF = FileName + datetime.now().strftime('%Y%m%d%H%M%S') + '.xls'
    path = '/media/temp/'
    pathRoot = settings.BASE_DIR + path
    if not os.path.exists(pathRoot):
        os.makedirs(pathRoot)

    path_name = os.path.join(pathRoot, FileNameF)
    wbk.save(path_name)
    return path + FileNameF


def export_excel_img(field_data: list, data: list, FileName: str):
    """
    带有image的Excel导出
    :param data: 数据源
    :param field_data: 首行数据源（表头）{'name':'', 'type':''}
    :param img_field_indexs: 图片字段名index列表
    :param file_path: 文件保存路径（默认保存在media路径）
    :param FileName: 文件保存名字
    :return:返回文件的下载url完整路径
    """
    wb = Workbook()
    ws = wb.active
    imgs = []

    for index, value in enumerate(field_data):
        cell = ws.cell(column=index+1, row=1)
        cell.value = value['name']
        cell.font = styles.Font(bold=True)
        letter = get_column_letter(index+1)
        value['letter'] = letter
        ws.column_dimensions[letter].width = 10  # 修改列宽
        if value['type'] == 'img':
            ws.column_dimensions[letter].width = 15  # 修改列宽

    for i1, v1 in enumerate(data):
        for i2, v2 in enumerate(v1):
            cell = ws.cell(column=i2+1, row=i1+2)
            if v2 and field_data[i2]['type'] == 'img':
                ws.row_dimensions[i1+2].height = 70
                try:
                    img = Image(settings.BASE_DIR + v2)
                    img.width, img.height = (90, 90)
                    imgs.append((img, field_data[i2]['letter'] + str(i1+2)))
                except:  # 这里先不做处理
                    pass
            else:
                cell.value = v2

    for i in imgs:
        ws.add_image(i[0], i[1])

    FileNameF = FileName + datetime.now().strftime('%Y%m%d%H%M%S') + '.xlsx'
    path = '/media/temp/'
    pathRoot = settings.BASE_DIR + path
    if not os.path.exists(pathRoot):
        os.makedirs(pathRoot)

    path_name = os.path.join(pathRoot, FileNameF)
    wb.save(path_name)
    return path + FileNameF
