Merge commit '47296980495f8bbfc9493e93de85dd62de6fa6b9' as 'paste-framework'
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user