Spaces:
Sleeping
Sleeping
Update invoice.py
Browse files- invoice.py +14 -8
invoice.py
CHANGED
|
@@ -5,6 +5,8 @@ from openpyxl.worksheet.worksheet import Worksheet
|
|
| 5 |
from openpyxl.drawing.image import Image as XLImage # FIX: needed for logo
|
| 6 |
from openpyxl.worksheet.page import PageMargins
|
| 7 |
from openpyxl.utils import get_column_letter
|
|
|
|
|
|
|
| 8 |
|
| 9 |
|
| 10 |
# Tune these to the template's designed page
|
|
@@ -239,11 +241,10 @@ def _clear_data(ws: Worksheet, start_row: int, col_first: int, col_last: int):
|
|
| 239 |
if c: c.value = None
|
| 240 |
|
| 241 |
def _apply_print_setup(ws: Worksheet):
|
| 242 |
-
#
|
| 243 |
try:
|
| 244 |
dn = ws.parent.defined_names.get('_xlnm.Print_Area') or ws.parent.defined_names.get('Print_Area')
|
| 245 |
if dn:
|
| 246 |
-
# Ensure the defined area is attached to this sheet
|
| 247 |
for title, ref in dn.destinations:
|
| 248 |
if title == ws.title:
|
| 249 |
ws.print_area = ref
|
|
@@ -251,22 +252,22 @@ def _apply_print_setup(ws: Worksheet):
|
|
| 251 |
except Exception:
|
| 252 |
pass
|
| 253 |
|
| 254 |
-
# If
|
| 255 |
if not ws.print_area:
|
| 256 |
-
|
| 257 |
-
ws.print_area = "A1:L110"
|
| 258 |
|
| 259 |
-
# Fit the
|
| 260 |
ws.sheet_properties.pageSetUpPr.fitToPage = True
|
| 261 |
ps = ws.page_setup
|
| 262 |
ps.orientation = "portrait"
|
| 263 |
ps.paperSize = ws.PAPERSIZE_A4
|
| 264 |
ps.fitToWidth = 1
|
| 265 |
-
ps.fitToHeight = 1
|
| 266 |
ps.scale = None
|
| 267 |
|
| 268 |
-
# Clean
|
| 269 |
ws.print_options.gridLines = False
|
|
|
|
| 270 |
ws.page_margins = PageMargins(left=0.3, right=0.3, top=0.5, bottom=0.5, header=0.25, footer=0.25)
|
| 271 |
|
| 272 |
# ---------- date / numbering ----------
|
|
@@ -495,6 +496,11 @@ def write_invoice_to_xlsx(template_path: str, out_path: str, payload: Dict[str,
|
|
| 495 |
_place_logo(ws)
|
| 496 |
_apply_print_setup(ws)
|
| 497 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 498 |
wb.save(out_path)
|
| 499 |
return out_path
|
| 500 |
|
|
|
|
| 5 |
from openpyxl.drawing.image import Image as XLImage # FIX: needed for logo
|
| 6 |
from openpyxl.worksheet.page import PageMargins
|
| 7 |
from openpyxl.utils import get_column_letter
|
| 8 |
+
# top of file
|
| 9 |
+
from openpyxl.styles import Font
|
| 10 |
|
| 11 |
|
| 12 |
# Tune these to the template's designed page
|
|
|
|
| 241 |
if c: c.value = None
|
| 242 |
|
| 243 |
def _apply_print_setup(ws: Worksheet):
|
| 244 |
+
# Respect template Print_Area if present
|
| 245 |
try:
|
| 246 |
dn = ws.parent.defined_names.get('_xlnm.Print_Area') or ws.parent.defined_names.get('Print_Area')
|
| 247 |
if dn:
|
|
|
|
| 248 |
for title, ref in dn.destinations:
|
| 249 |
if title == ws.title:
|
| 250 |
ws.print_area = ref
|
|
|
|
| 252 |
except Exception:
|
| 253 |
pass
|
| 254 |
|
| 255 |
+
# If not set by template, cover the whole layout explicitly
|
| 256 |
if not ws.print_area:
|
| 257 |
+
ws.print_area = "A1:L110" # <<< match the “L110” used above
|
|
|
|
| 258 |
|
| 259 |
+
# Fit the whole area on a single A4 page
|
| 260 |
ws.sheet_properties.pageSetUpPr.fitToPage = True
|
| 261 |
ps = ws.page_setup
|
| 262 |
ps.orientation = "portrait"
|
| 263 |
ps.paperSize = ws.PAPERSIZE_A4
|
| 264 |
ps.fitToWidth = 1
|
| 265 |
+
ps.fitToHeight = 1
|
| 266 |
ps.scale = None
|
| 267 |
|
| 268 |
+
# Clean output
|
| 269 |
ws.print_options.gridLines = False
|
| 270 |
+
ws.sheet_view.showGridLines = False
|
| 271 |
ws.page_margins = PageMargins(left=0.3, right=0.3, top=0.5, bottom=0.5, header=0.25, footer=0.25)
|
| 272 |
|
| 273 |
# ---------- date / numbering ----------
|
|
|
|
| 496 |
_place_logo(ws)
|
| 497 |
_apply_print_setup(ws)
|
| 498 |
|
| 499 |
+
# --- FORCE USED RANGE TO INCLUDE FULL TEMPLATE (so LO doesn't crop) ---
|
| 500 |
+
ws["L110"].value = "•" # any tiny char
|
| 501 |
+
ws["L110"].font = Font(color="FFFFFF", size=1) # invisible in print
|
| 502 |
+
# ----------------------------------------------------------------------
|
| 503 |
+
|
| 504 |
wb.save(out_path)
|
| 505 |
return out_path
|
| 506 |
|