74 lines
2.7 KiB
Python
74 lines
2.7 KiB
Python
from openpyxl import load_workbook
|
||
from PIL import ImageFont
|
||
|
||
|
||
def get_font_width_ratio(font_path, point_size, char="0"):
|
||
"""
|
||
测量给定字体下指定字符的宽度比例(宽度 / 字体大小)
|
||
通过放大到 200pt 测量消除取整误差。
|
||
"""
|
||
measure_pt = 200 # 足够大,减少 hinting 影响
|
||
# Pillow 的 size 参数需要像素值,我们任选一个 DPI 但最终取比例,所以 DPI 可任意
|
||
dpi = 96
|
||
measure_px = int(measure_pt * dpi / 72)
|
||
font = ImageFont.truetype(font_path, measure_px)
|
||
bbox = font.getbbox(char)
|
||
width_px = bbox[2] - bbox[0]
|
||
ratio = width_px / measure_px # 无量纲比例
|
||
return ratio
|
||
|
||
|
||
def calc_chars_per_column(workbook_path, sheet_name, column_letter, target_char="中"):
|
||
"""
|
||
计算指定列能容纳多少个 target_char(默认汉字)
|
||
"""
|
||
wb = load_workbook(workbook_path)
|
||
ws = wb[sheet_name]
|
||
|
||
# 1. 获取默认字体(Normal 样式)
|
||
# default_font = wb._named_styles["Normal"].font
|
||
# default_font_name = default_font.name or "Calibri"
|
||
# default_font_size = default_font.size or 11 # 磅值
|
||
|
||
# 2. 获取默认字体下数字 '0' 的宽度比例
|
||
# 需要找到默认字体文件路径(简单方案:使用系统字体名,PIL 能自动查找)
|
||
zero_ratio = get_font_width_ratio(
|
||
"Calibri.ttf", 11, "0"
|
||
)
|
||
standard_char_width_pt = 11 * zero_ratio # 标准字符宽度(点)
|
||
|
||
# 3. 获取目标字体(宋体 8 号 = 5pt)下汉字的宽度比例
|
||
target_font_name = "simsun.ttc" # 宋体
|
||
target_font_size_pt = 8
|
||
han_ratio = get_font_width_ratio(target_font_name, target_font_size_pt, target_char)
|
||
han_width_pt = target_font_size_pt * han_ratio
|
||
|
||
# 4. 列宽(字符数)
|
||
col_width_chars = ws.column_dimensions[column_letter].width
|
||
print("列宽:", col_width_chars, "字符")
|
||
|
||
# 5. 左右内边距 + 右边框线的经验值(点)
|
||
# 根据实测,对于小列宽,固定边距约为 3pt(相当于 4~5 像素在 96DPI 下)
|
||
padding_pt = 0
|
||
|
||
total_width_pt = (
|
||
col_width_chars * standard_char_width_pt + padding_pt * 2 + 0.5
|
||
) # 右边框约 0.5pt
|
||
|
||
# 6. 计算可容纳汉字数
|
||
max_count = int(total_width_pt // han_width_pt)
|
||
|
||
# print(f"默认字体: {default_font_name} {default_font_size}pt")
|
||
print(f"标准字符宽度: {standard_char_width_pt:.3f} pt")
|
||
print(f"目标汉字宽度: {han_width_pt:.3f} pt")
|
||
print(f"列总宽度: {total_width_pt:.3f} pt")
|
||
print(f"可容纳汉字数: {max_count}")
|
||
|
||
return max_count
|
||
|
||
|
||
# 使用示例
|
||
if __name__ == "__main__":
|
||
# 替换为你的文件路径和工作表名
|
||
count = calc_chars_per_column("测试.xlsx", "Sheet1", "AA")
|