fix table

This commit is contained in:
2026-09-02 15:53:52 +03:00
parent 22c7ab7140
commit f51b60a839
2 changed files with 54 additions and 19 deletions
+4 -3
View File
@@ -14,7 +14,7 @@ from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
from app.core.config import get_settings
from app.services.pdf_gost_frame import draw_gost_frame
from app.services.pdf_gost_frame import TABLE_LEFT, draw_gost_frame
_font_registered = False
FONT_NAME = "GOST_A"
@@ -231,7 +231,8 @@ def _draw_rotated_header(
line = lines[0] if lines else text
line = _elide(c, line, font, size, h - mm)
tw = c.stringWidth(line, font, size)
c.drawString((h - tw) / 2, (w - size * 0.35) / 2, line)
# Текст растёт внутрь таблицы (+x после поворота), не влево в поле подшивки
c.drawString(max(0, (h - tw) / 2), (w - size * 0.35) / 2, line)
c.restoreState()
@@ -344,7 +345,7 @@ def _draw_table_page(
font = _ensure_font()
c.setLineWidth(LINE_WIDTH)
table_x = layout.margin_left_mm * mm
table_x = TABLE_LEFT
table_top = page_h - layout.margin_top_mm * mm
row_h = layout.row_height_mm * mm
header_h = layout.header_height_mm * mm
+50 -16
View File
@@ -10,6 +10,10 @@ M_LEFT = 20 * mm
M_TOP = 5 * mm
M_RIGHT = 5 * mm
M_BOTTOM = 5 * mm
BINDING_WIDTH = 12 * mm
# Поле подшивки: 8–20 мм от левого края листа; таблица начинается ровно на inner.left (20 мм).
TABLE_LEFT = M_LEFT
BINDING_LEFT = TABLE_LEFT - BINDING_WIDTH
DOC_TYPES = {
"perechen": 1,
@@ -45,6 +49,22 @@ def _set_frame_pen(c: canvas.Canvas) -> None:
c.setStrokeColorRGB(0, 0, 0)
def _elide(c: canvas.Canvas, text: str, font: str, size: float, max_w: float) -> str:
if not text:
return text
if c.stringWidth(text, font, size) <= max_w:
return text
ell = ""
lo, hi = 0, len(text)
while lo < hi:
mid = (lo + hi + 1) // 2
if c.stringWidth(text[:mid] + ell, font, size) <= max_w:
lo = mid
else:
hi = mid - 1
return text[:lo] + ell if lo else ell
def _txt(
c: canvas.Canvas,
x: float,
@@ -60,6 +80,7 @@ def _txt(
if not text:
return
c.setFont(font, size)
text = _elide(c, text, font, size, w - mm)
tw = c.stringWidth(text, font, size)
if align == "center":
tx = x + (w - tw) / 2
@@ -116,26 +137,38 @@ def _draw_inner_border(c: canvas.Canvas, inner: Inner) -> None:
c.rect(inner.left, inner.bottom, inner.right - inner.left, inner.top - inner.bottom)
def _clip_binding_zone(c: canvas.Canvas, inner: Inner) -> None:
"""Ограничить рисование полосы подшивки: 8–20 мм, не заходить в таблицу."""
p = c.beginPath()
p.rect(BINDING_LEFT, inner.bottom, BINDING_WIDTH, inner.top - inner.bottom)
c.clipPath(p, stroke=0, fill=0)
def _draw_left_binding_strip(c: canvas.Canvas, inner: Inner) -> tuple[float, float, float, float]:
"""Left vertical strip (12×145 mm) at bottom-left of inner area."""
w = 12 * mm
"""Left vertical strip (12×145 mm) — strictly left of the table (820 mm)."""
w = BINDING_WIDTH
h = 145 * mm
x = inner.left - w
x = BINDING_LEFT
y = inner.bottom
c.saveState()
_set_frame_pen(c)
_clip_binding_zone(c, inner)
c.rect(x, y, w, h)
# horizontal dividers (from bottom): 25, 35, 25, 25, 35 mm sections
offsets = [25, 60, 85, 110, 145]
for off in offsets:
yy = y + off * mm
c.line(x, yy, inner.left, yy)
c.line(x + w + 5 * mm, y, x + w + 5 * mm, y + h)
c.line(x, yy, TABLE_LEFT, yy)
c.restoreState()
return x, y, w, h
def _draw_left_binding_text(c: canvas.Canvas, strip_x: float, strip_y: float, inscriptions: dict[int, str], font: str) -> None:
def _draw_left_binding_text(
c: canvas.Canvas, inner: Inner, strip_x: float, strip_y: float, inscriptions: dict[int, str], font: str
) -> None:
size = 12
c.saveState()
c.translate(strip_x + 12 * mm, strip_y + 145 * mm)
_clip_binding_zone(c, inner)
c.translate(strip_x + BINDING_WIDTH, strip_y + 145 * mm)
c.rotate(-90)
labels = [
(0, 25, "Инв. № подл"),
@@ -153,16 +186,17 @@ def _draw_left_binding_text(c: canvas.Canvas, strip_x: float, strip_y: float, in
def _draw_top_left_strip(c: canvas.Canvas, inner: Inner, inscriptions: dict[int, str], doc_type: int, font: str) -> None:
w = 12 * mm
w = BINDING_WIDTH
h = 120 * mm
x = inner.left - w
x = BINDING_LEFT
y = inner.top - h
c.rect(x, y, w, h)
c.line(x + w + 5 * mm, y, x + w + 5 * mm, y + h)
c.line(x, y + 60 * mm, inner.left, y + 60 * mm)
c.saveState()
c.translate(x + w, y)
_set_frame_pen(c)
_clip_binding_zone(c, inner)
c.rect(x, y, w, h)
c.line(x, y + 60 * mm, TABLE_LEFT, y + 60 * mm)
c.translate(TABLE_LEFT, y)
c.rotate(-90)
_txt(c, 0, 0, 60 * mm, 5 * mm, "Справ. №", font, 12)
_txt(c, 60 * mm, 0, 60 * mm, 5 * mm, "Перв. примен.", font, 12)
@@ -333,7 +367,7 @@ def draw_gost_frame(
inner = Inner(page_w, page_h)
_draw_inner_border(c, inner)
sx, sy, sw, sh = _draw_left_binding_strip(c, inner)
_draw_left_binding_text(c, sx, sy, inscriptions, font)
_draw_left_binding_text(c, inner, sx, sy, inscriptions, font)
if page == 1:
_draw_top_left_strip(c, inner, inscriptions, doc_type, font)