fix(translators): ameliorer le respect des formats de fichiers pour Excel, PowerPoint et PDF
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m33s

- Excel: elargissement intelligent des colonnes pour le texte etendu et alignement RTL des cellules

- PowerPoint: retour a la ligne et auto-fit anti-debordement, colonnes de tableaux en RTL

- PDF: protection multi-colonnes pour eviter les chevauchements et formatage hebreu

- Tests: validation de non-regression pour tous les formats
This commit is contained in:
2026-09-02 21:35:31 +02:00
parent cae09fc512
commit 6f5b6acbdc
6 changed files with 257 additions and 16 deletions

View File

@@ -355,17 +355,16 @@ class ExcelTranslator:
except Exception as e:
_log_error("excel_sheet_images_failed", sheet_name=sheet_name, error=str(e))
# Normalize the sheet reading direction to the TARGET language.
# RTL targets: flip every sheet so column A renders rightmost.
# Latin targets: restore left-to-right on sheets inherited from
# an RTL source (Persian → French must not keep the RTL view).
# Content and formatting are untouched — only the direction.
# Chartsheets have no `sheet_view` and must never break the
# save: each sheet is guarded individually.
# Normalize sheet reading direction, column widths, and cell alignment
rtl_target = is_rtl(target_language)
flipped = 0
for sheet_name in workbook.sheetnames:
ws = workbook[sheet_name]
try:
self._adjust_column_widths_and_alignments(ws, rtl_target=rtl_target)
except Exception as e:
_log_error("excel_adjust_columns_failed", sheet=sheet_name, error=str(e))
try:
if getattr(ws, "sheet_view", None) is None:
continue
@@ -466,6 +465,53 @@ class ExcelTranslator:
},
)
def _adjust_column_widths_and_alignments(
self, worksheet: Worksheet, rtl_target: bool
) -> None:
"""Intelligently widen columns when translated text has expanded,
and normalize explicit cell text alignment for RTL/LTR."""
import copy
from openpyxl.utils import get_column_letter
if not hasattr(worksheet, "iter_cols"):
return
try:
for col in worksheet.iter_cols():
if not col:
continue
first_cell = col[0]
col_letter = get_column_letter(first_cell.column)
dim = worksheet.column_dimensions.get(col_letter)
current_width = dim.width if (dim and dim.width) else 10.0
max_len = 0
for cell in col:
val = cell.value
if isinstance(val, str) and val.strip():
lines = val.split("\n")
cell_max = max(len(l) for l in lines)
if cell_max > max_len:
max_len = cell_max
# Normalize explicit horizontal alignment if present
if cell.alignment and isinstance(val, str):
if rtl_target and cell.alignment.horizontal == "left":
new_align = copy.copy(cell.alignment)
new_align.horizontal = "right"
cell.alignment = new_align
elif not rtl_target and cell.alignment.horizontal == "right":
new_align = copy.copy(cell.alignment)
new_align.horizontal = "left"
cell.alignment = new_align
if max_len > 0:
ideal_width = min(max_len + 3.0, 50.0)
if ideal_width > current_width:
worksheet.column_dimensions[col_letter].width = ideal_width
except Exception as e:
_log_error("excel_adjust_columns_failed", sheet=getattr(worksheet, "title", ""), error=str(e))
def _sanitize_sheet_name(self, name: str) -> str:
"""
Sanitize a sheet name to be valid for Excel.