bericht/class/berichtpdf.class.php
Eduard Wisch d40587845f
All checks were successful
Deploy bericht / deploy (push) Successful in 1s
PDF-Header mit Logo+Titel, Footer mit Seitenzahl, Hack-Font beschreibbar [deploy]
- Neue Klasse BerichtPdf / BerichtPdfFpdi (Trait-basiert):
  * Header: links Bericht-Titel (Bold) + Firmenname, rechts Firmen-Logo (max 40x18mm),
    Trennlinie. Top-Margin jetzt 30mm für den Header-Bereich.
  * Footer: zentriert "Seite X / Y" mit TCPDF-Aliases.
  * berichtInit(): kompiliert Hack-TTFs nach DOL_DATA_ROOT/bericht/tcpdf_fonts/
    (beschreibbar) und bindet sie per AddFont an die PDF-Instance.
    Vorher schlug addTTFfont still fehl weil K_PATH_FONTS read-only war —
    deshalb kam weder Titel noch Notiz in Hack.
- bericht_ensure_hack_font($pdf) zieht den Font-Key jetzt aus der Instance
  (BerichtPdfTrait), sonst Fallback helvetica.
- bericht_write_note_html() wrapped das CKEditor-HTML in
  <span style="font-family:hack...;"> damit writeHTMLCell den Hack-Font
  tatsächlich verwendet.
- Composite-Branch: $mT=30 / $mB=16 damit Bilder nicht unter dem Header
  sitzen.
- ajax/generate_pdf, ajax/preview_pdf, api/pdf, api/reports, bericht_batch:
  alle nutzen jetzt BerichtPdf(Fpdi), setzen SetMargins(10,30,10),
  setPrintHeader(true) und berichtInit() mit Titel, mysoc->name und Logo.
2026-04-09 15:39:42 +02:00

108 lines
4 KiB
PHP

<?php
/**
* BerichtPdf — TCPDF/FPDI-Subclass mit Header, Footer und Hack-Font-Setup
* für das Bericht-Modul.
*
* Header: links Bericht-Titel + Firmenname, rechts Firmen-Logo, Trennlinie.
* Footer: zentriert "Seite X / Y".
* Font: Hack-TTFs werden in ein beschreibbares DOL_DATA_ROOT/bericht/tcpdf_fonts/
* kompiliert und per AddFont an die PDF-Instance gebunden.
*/
trait BerichtPdfTrait
{
public $hack_font_key = 'helvetica';
public $bericht_title = '';
public $bericht_company = '';
public $bericht_logo = '';
/**
* Muss direkt nach der Konstruktion aufgerufen werden.
*/
public function berichtInit($title, $company, $logo_path)
{
$this->bericht_title = (string) $title;
$this->bericht_company = (string) $company;
$this->bericht_logo = (string) $logo_path;
// Hack-Font registrieren (Eddys Corporate-Font)
if (class_exists('TCPDF_FONTS') && defined('DOL_DATA_ROOT')) {
$fontdir = dirname(__DIR__).'/fonts/';
$outdir = DOL_DATA_ROOT.'/bericht/tcpdf_fonts/';
if (!is_dir($outdir)) @mkdir($outdir, 0755, true);
if (is_dir($outdir) && is_writable($outdir)) {
$map = array(
'' => 'Hack-Regular.ttf',
'B' => 'Hack-Bold.ttf',
'I' => 'Hack-Italic.ttf',
'BI' => 'Hack-BoldItalic.ttf',
);
$reg_key = null;
foreach ($map as $style => $fn) {
$src = $fontdir.$fn;
if (!file_exists($src)) continue;
try {
$k = TCPDF_FONTS::addTTFfont($src, 'TrueTypeUnicode', '', 32, $outdir);
if ($k) {
$ffile = $outdir.$k.'.php';
if (file_exists($ffile)) {
$this->AddFont($k, '', $ffile);
}
if ($style === '') $reg_key = $k;
}
} catch (Throwable $e) {
error_log('[BerichtPdf] Hack-Font '.$fn.' fehlgeschlagen: '.$e->getMessage());
}
}
if ($reg_key) $this->hack_font_key = $reg_key;
} else {
error_log('[BerichtPdf] Font-Outdir nicht schreibbar: '.$outdir);
}
}
}
public function Header()
{
$pageW = $this->getPageWidth();
$logo_w = 0;
if ($this->bericht_logo && file_exists($this->bericht_logo)) {
$info = @getimagesize($this->bericht_logo);
if ($info && $info[0] && $info[1]) {
$maxW = 40; $maxH = 18;
$ratio = min($maxW / $info[0], $maxH / $info[1]);
$w = $info[0] * $ratio;
$h = $info[1] * $ratio;
$this->Image($this->bericht_logo, $pageW - 10 - $w, 6, $w, $h);
$logo_w = $w;
}
}
$this->SetTextColor(40, 40, 40);
$this->SetFont($this->hack_font_key, 'B', 13);
$this->SetXY(10, 8);
$textW = $pageW - 20 - $logo_w - 4;
$this->Cell($textW, 6, $this->bericht_title, 0, 2, 'L');
if ($this->bericht_company) {
$this->SetFont($this->hack_font_key, '', 9);
$this->SetX(10);
$this->Cell($textW, 5, $this->bericht_company, 0, 2, 'L');
}
$this->SetDrawColor(180, 180, 180);
$this->SetLineWidth(0.2);
$this->Line(10, 27, $pageW - 10, 27);
}
public function Footer()
{
$this->SetY(-12);
$this->SetFont($this->hack_font_key, '', 9);
$this->SetTextColor(100, 100, 100);
$txt = 'Seite '.$this->getAliasNumPage().' / '.$this->getAliasNbPages();
$this->Cell(0, 8, $txt, 0, 0, 'C');
}
}
class BerichtPdf extends TCPDF { use BerichtPdfTrait; }
if (class_exists('\\setasign\\Fpdi\\Tcpdf\\Fpdi')) {
class BerichtPdfFpdi extends \setasign\Fpdi\Tcpdf\Fpdi { use BerichtPdfTrait; }
}