exceltools/ok.py
2026-05-10 16:05:47 +08:00

74 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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")