Converter a largura da coluna do Excel entre a unidade de caracteres e os pixels (pontos)
assim ColumnWidth
no Excel é medido como um número de "0" caracteres que se encaixa numa coluna. Como é que este valor pode ser convertido em pixels e vice-versa?
1 answers
Como já mencionado ColumnWidth
o valor no Excel depende do tipo de letra predefinido de um livro que pode ser obtido via Workbook.Styles("Normal").Font
. Também depende do PPP do ecrã actual.
Como pode ser visto na imagem a função para {[3] } é diferente da maior parte da o mapa das linhas. É calculado como um número de pixels em uma coluna / Número de pixels necessários para caber um "0" caráter em uma coluna.
Agora vamos ver em que consiste uma típica largura celular.-
A
- " 0 " Largura de caracteres no estilo Normal -
B
- enchimento esquerdo e direito -
C
- 1px margem direita
A
pode ser calculado com a função GetTextExtentPoint32 da API do Windows, mas o tamanho da letra deve ser um pouco maior. Por experiência eu escolhi + 0.3 pt que trabalhou para mim para diferentes fontes com tamanho de base 8-48pt. B
é (A + 1) / 4
arredondado às unidades usando "round half up" . Também serão necessários DPI no ecrã (ver implementação em Python 3 abaixo)
Aqui estão as equações para a conversão de caracteres-pixels e a sua implementação em Python 3:
import win32print, win32gui
from math import floor
def get_screen_dpi():
dc = win32gui.GetDC(0)
LOGPIXELSX, LOGPIXELSY = 88, 90
dpi = [win32print.GetDeviceCaps(dc, i) for i in (LOGPIXELSX,
LOGPIXELSY)]
win32gui.ReleaseDC(0, dc)
return dpi
def get_text_metrics(fontname, fontsize):
"Measures '0' char size for the specified font name and size in pt"
dc = win32gui.GetDC(0)
font = win32gui.LOGFONT()
font.lfFaceName = fontname
font.lfHeight = -fontsize * dpi[1] / 72
hfont = win32gui.CreateFontIndirect(font)
win32gui.SelectObject(dc, hfont)
metrics = win32gui.GetTextExtentPoint32(dc, "0")
win32gui.ReleaseDC(0, dc)
return metrics
def ch_px(v, unit="ch"):
"""
Convert between Excel character width and pixel width.
`unit` - unit to convert from: 'ch' (default) or 'px'
"""
rd = lambda x: floor(x + 0.5) # round half up
# pad = left cell padding + right cell padding + cell border(1)
pad = rd((z + 1) / 4) * 2 + 1
z_p = z + pad # space (px) for "0" character with padding
if unit == "ch":
return v * z_p if v < 1 else v * z + pad
else:
return v / z_p if v < z_p else (v - pad) / z
font = "Calibri", 11
dpi = get_screen_dpi()
z = get_text_metrics(font[0], font[1] + 0.3)[0] # "0" char width in px
px = ch_px(30, "ch")
ch = ch_px(px, "px")
print("Characters:", ch, "Pixels:", px, "for", font)