| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- # -*- coding: utf-8 -*-
- import io
- import pandas as pd
- from typing import Any
- from openpyxl import Workbook
- from openpyxl.utils import get_column_letter
- from openpyxl.styles import Alignment, PatternFill
- from openpyxl.worksheet.datavalidation import DataValidation
- class ExcelUtil:
- """Excel文件处理工具类"""
-
- @classmethod
- def __mapping_list(cls, list_data: list[dict[str, Any]], mapping_dict: dict) -> list:
- """
- 工具方法:将列表数据中的字段名映射为对应的中文字段名。
- 参数:
- - list_data (list[dict[str, Any]]): 数据列表。
- - mapping_dict (dict): 字段名映射字典。
- 返回:
- - list: 映射后的数据列表。
- """
- mapping_data = [{mapping_dict.get(key): item.get(key) for key in mapping_dict} for item in list_data]
- return mapping_data
-
- @classmethod
- def get_excel_template(cls, header_list: list[str], selector_header_list: list[str], option_list: list[dict[str, list[str]]]) -> bytes:
- """
- 生成 Excel 模板文件。
- 参数:
- - header_list (list[str]): 表头列表。
- - selector_header_list (list[str]): 需要设置下拉选择的表头列表。
- - option_list (list[dict[str, list[str]]]): 下拉选项配置列表。
- 返回:
- - bytes: Excel 文件的二进制数据。
- """
- wb = Workbook()
- ws = wb.active
- if not ws:
- raise ValueError("不存在活动工作表")
- # 设置表头样式
- header_fill = PatternFill(start_color='ababab', end_color='ababab', fill_type='solid')
- # 写入表头
- for col_num, header in enumerate(header_list, 1):
- cell = ws.cell(row=1, column=col_num)
- cell.value = header
- cell.fill = header_fill
- # 设置水平居中对齐
- cell.alignment = Alignment(horizontal='center')
- # 设置列宽度为16
- ws.column_dimensions[get_column_letter(col_num)].width = 12
- # 设置下拉选择
- for selector_header in selector_header_list:
- col_idx = header_list.index(selector_header) + 1
-
- # 获取当前表头的选项列表
- header_options = next((opt.get(selector_header) for opt in option_list if selector_header in opt), [])
-
- if header_options:
- dv = DataValidation(type='list', formula1=f'"{",".join(header_options)}"')
- dv.add(f'{get_column_letter(col_idx)}2:{get_column_letter(col_idx)}1048576')
- ws.add_data_validation(dv)
- # 导出为二进制数据
- buffer = io.BytesIO()
- wb.save(buffer)
- buffer.seek(0)
- # 读取字节数据
- excel_data = buffer.getvalue()
- return excel_data
-
- @classmethod
- def export_list2excel(cls, list_data: list[dict[str, Any]], mapping_dict: dict) -> bytes:
- """
- 将列表数据导出为 Excel 文件。
- 参数:
- - list_data (list[dict[str, Any]]): 要导出的数据列表。
- - mapping_dict (dict): 字段名映射字典。
- 返回:
- - bytes: Excel 文件的二进制数据。
- """
- mapping_data = cls.__mapping_list(list_data, mapping_dict)
- df = pd.DataFrame(mapping_data)
- buffer = io.BytesIO()
- df.to_excel(buffer, index=False, engine='openpyxl')
- binary_data = buffer.getvalue()
- return binary_data
|