from typing import Union, List, Optional, Dict, Any import pandas as pd from paste.util import ufont def cm_to_excel_units(cm): """ 厘米转Excel列宽单位。 :param cm: 厘米单位 """ return cm / 2.54 * 7 # 1英寸=2.54厘米, 1Excel单位=1/7英寸 def auto_width_cm(series: pd.Series, font_name='Microsoft YaHei', font_size=11, min_cm=1.5, max_cm=20): """ 自动列宽计算方法(区分中英文)。 :param series: pandas Series (数据列) :param font_name: 字体名称 :param font_size: 字号 :param min_cm: 最小列宽(厘米) :param max_cm: 最大列宽(厘米) :return: 建议的列宽(厘米) """ # 获取精确字体度量 en_width_cm, cn_width_cm = ufont.get_font_metrics(font_name, font_size) def calculate_text_width(text): """计算文本总宽度""" cn_count = 0 en_count = 0 for char in str(text): if '\u4e00' <= char <= '\u9fff': cn_count += 1 else: en_count += 1 _total_width = (cn_count * cn_width_cm) + (en_count * en_width_cm) return _total_width # 计算列标题宽度 title_width = calculate_text_width(series.name) # 计算数据内容最大宽度 content_width = series.astype(str).apply(calculate_text_width).max() # 取最大值并增加边距,15%额外边距 total_width = max(title_width, content_width) * 1.2 return max(min(total_width, max_cm), min_cm) def auto_column_width(df, worksheet): """ 根据内容自动设置列的宽度。 :param df: pandas DataFrame :param worksheet: 工作表 """ _font_name_set = ufont.get_fonts() for col_num, col_name in enumerate(df.columns): # 计算列宽 width_cm = auto_width_cm(df[col_name], font_name=_font_name_set[0], font_size=11) # 设置列宽 worksheet.set_column(col_num, col_num, cm_to_excel_units(width_cm)) def apply_header_style(df, worksheet, workbook, **kwargs): """ 应用表头样式。 :param df: 原始 DataFrame :param worksheet: xlsxwriter worksheet对象 :param workbook: xlsxwriter workbook对象 :param kwargs: 样式参数 :return: 无 """ _style_sheet = { 'font_size': 12, 'bg_color': '#F2F2F2', 'border': 1, 'bold': True, } _header_style = workbook.add_format({**_style_sheet, **kwargs}) for col_num, value in enumerate(df.columns.values): worksheet.write(0, col_num, value, _header_style) def apply_data_style(df, worksheet, workbook, **kwargs): """ 应用数据单元格样式。 :param df: 原始 DataFrame :param worksheet: xlsxwriter worksheet对象 :param workbook: xlsxwriter workbook对象 :param kwargs: 样式参数 :return: 无 """ _style_sheet = { 'font_size': 12, 'border': 1, } _cell_style = workbook.add_format({**_style_sheet, **kwargs}) for row in range(1, len(df) + 1): for col in range(0, len(df.columns)): worksheet.write(row, col, df.iloc[row - 1, col], _cell_style) def insert_text_to_column( worksheet, workbook, column: int, start_row: int, texts: Union[str, List[str]], text_format: Optional[Dict[str, Any]] = None ) -> None: """ 向Excel表格的指定列插入文本。 :param worksheet: xlsxwriter worksheet :param workbook: xlsxwriter workbook :param column: 列号 :param start_row: 开始插入的行号(1-based) :param texts: 要插入的文本(字符串或字符串列表) :param text_format: 格式字典,None则使用默认格式 :return: None """ # 设置默认格式 default_format = { 'font_size': 12, } # 合并用户自定义格式 fmt = workbook.add_format({**default_format, **(text_format or {})}) # 转换列号为数字索引(1-based) if isinstance(column, str): col_idx = ord(column.upper()) - ord('A') + 1 else: col_idx = column # 确保texts是列表形式 if isinstance(texts, str): texts = [texts] # 处理每行数据 for i, text in enumerate(texts): row_num = start_row + i worksheet.write(row_num, col_idx, text, fmt)