fix table
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 (8–20 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)
|
||||
|
||||
Reference in New Issue
Block a user