PDF-Export aller Artikel mit Inhaltsverzeichnis

You have a suggestion for a future version of phpMyFAQ? Then post it here!

Moderator: Thorsten

Post Reply
Mini
Posts: 63
Joined: Mon May 08, 2006 11:11 pm

PDF-Export aller Artikel mit Inhaltsverzeichnis

Post by Mini »

Feature: PDF-Export aller Artikel mit Inhaltsverzeichnis!
Beispiel: http://www1.file-upload.net/download_04 ... 4.pdf.html

Hi,

habe die export.main.php im Admin-Ordner wie folgt modifizert, um bei der exportierten PDF aller Artikel eine vernünftige Darstellung mit einem Inhaltsverzeichnis hinzubekommen (Achtung, habe die Sprache manuell gesetzt!!!!):

Code: Select all

<?
if (isset($submit[2])) {
	// Full PDF Export
	require (PMF_ROOT_DIR."/inc/pdf.php");
	$tree = new Category();
	$arrRubrik = array();
	$arrThema = array();
	$arrContent = array();
	$arrID = array();
	$arrSolutionID = array();

	//$result = $db->query('SELECT '.SQLPREFIX.'faqdata.id AS id, '.SQLPREFIX.'faqdata.lang AS lang, '.SQLPREFIX.'faqdata.solution_id AS solution_id, '.SQLPREFIX.'faqcategoryrelations.category_id AS category_id, '.SQLPREFIX.'faqdata.thema AS thema, '.SQLPREFIX.'faqdata.content AS content, '.SQLPREFIX.'faqdata.author AS author, '.SQLPREFIX.'faqdata.datum AS datum FROM '.SQLPREFIX.'faqdata LEFT JOIN '.SQLPREFIX.'faqcategoryrelations ON '.SQLPREFIX.'faqdata.id = '.SQLPREFIX.'faqcategoryrelations.record_id AND '.SQLPREFIX.'faqdata.lang = '.SQLPREFIX.'faqcategoryrelations.record_lang WHERE '.SQLPREFIX.'faqdata.active = \'yes\' GROUP BY thema ORDER BY '.SQLPREFIX.'faqcategoryrelations.category_id, '.SQLPREFIX.'faqdata.id');
	$result = $db->query('SELECT '.SQLPREFIX.'faqdata.id AS id, '.SQLPREFIX.'faqdata.lang AS lang, '.SQLPREFIX.'faqdata.solution_id AS solution_id, '.SQLPREFIX.'faqcategoryrelations.category_id AS category_id, '.SQLPREFIX.'faqdata.thema AS thema, '.SQLPREFIX.'faqdata.content AS content, '.SQLPREFIX.'faqdata.author AS author, '.SQLPREFIX.'faqdata.datum AS datum FROM '.SQLPREFIX.'faqdata LEFT JOIN '.SQLPREFIX.'faqcategoryrelations ON '.SQLPREFIX.'faqdata.id = '.SQLPREFIX.'faqcategoryrelations.record_id AND '.SQLPREFIX.'faqdata.lang = '.SQLPREFIX.'faqcategoryrelations.record_lang WHERE '.SQLPREFIX.'faqdata.active = \'yes\' GROUP BY thema ORDER BY thema');
	if ($db->num_rows($result) > 0) {
		$i = 0;
		while ($row = $db->fetch_object($result)) {
			$arrRubrik[$i] = $row->category_id;
			$arrThema[$i] = $row->thema;
			$arrContent[$i] = $row->content;
			$arrDatum[$i] = $row->datum;
			$arrAuthor[$i] = $row->author;
			$arrID[$i] = $row->id;
			$arrSolutionID[$i] = $row->solution_id;
			$i++;
		}
	}
	
	$num = $db->num_rows($result);
	if (($num+2) > 37) {
		$num = ceil(($num+2) / 37);
	}else{
		$num = 1;
	}
	
	$pdf = new PDF();
    $pdf->enableBookmarks = TRUE;
	$pdf->Open();
	$pdf->AliasNbPages();
	$pdf->SetAutoPageBreak(true,30);
	$pdf->SetDisplayMode("real");
	$pdf->SetLeftMargin(20);
	$writeMultiCategories = '';
	$tree->language = "de";
	
	$pdf->enableBookmarks = false;
	$pdf->AddPage();
	$pdf->SetFont("Arial", "", 32);
	$pdf->WriteHTML(unhtmlentities("<br /><br /><br /><br /><br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TITEL"));
	$pdf->SetFont("Arial", "", 22);
	$pdf->WriteHTML(unhtmlentities("<br /><br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- UNTERTITEL -"));
	$pdf->SetFont("Arial", "", 10);
	$pdf->Bookmark("Deckblatt");
	$pdf->enableBookmarks = true;
	
	for ($i = 1; $i <= $num; $i++) {
   		$pdf->thema = "Inhaltsverzeichnis";
		$pdf->SetFont('Arial', '', 11);
		$pdf->AddPage("P");
	}
	
	foreach ($arrContent as $key => $value) {
		$pdf->rubrik = $arrRubrik[$key];
		$pdf->thema = $arrThema[$key];
              
       	$multiCats = $tree->getCategoriesFromArticle($arrID[$key]);

       	$writeMultiCategories =   'Rubriken: ';
	    foreach ($multiCats as $multiCat) {
	        $writeMultiCategories .= $multiCat['name'].", ";
	    }
	    
	    $pdf->categories = substr($writeMultiCategories,0,-2);
        
		$date =  $arrDatum[$key];
		$author = $arrAuthor[$key];
		
		$info = substr($writeMultiCategories,0,-2)."\n";
		$info .= "Verfasser: ".$author."\n";
		$info .= "Letzte Änderung: ".makeDate($date)." Uhr\n";
		$info .= "Artikelnummer: ".$arrSolutionID[$key]."\n";
		
		$pdf->AddPage();
		$pdf->SetFont("Arial", "", 11);
    	$pdf->WriteHTML(unhtmlentities($value));
    	$pdf->Ln(15);
        $pdf->SetFillColor(247,247,247);
        $pdf->SetDrawColor(237,237,237);
        $pdf->SetTextColor(167,167,167);
        $pdf->SetFont("Arial", "", 10);
        $pdf->Rect($pdf->GetX(),$pdf->GetY(), $pdf->w-$pdf->rMargin-$pdf->x, 22.5,"FD");
    	$pdf->Image("../images/info.jpg",$pdf->GetX()+1,$pdf->GetY()+1);
    	$pdf->SetXY($pdf->GetX()+13,$pdf->GetY()+2.5);
    	$pdf->MultiCell($pdf->w-$pdf->rMargin-$pdf->x-10,4.5,$info);
    	$pdf->SetTextColor(0,0,0);

	}

	$last=$pdf->page;
	
	for ($i = 1; $i <= $num; $i++) {
	
		$pdf->page=$i + 1; 
		$pdf->SetY(42);
		$pdf->SetFont("Arial", "", 9);
		$pdf->SetFont("Arial", "", 11);
		$k = 0;
	        //Outline items
        foreach($pdf->outlines as $j=>$o) {
		   $k ++;
        	
		   if (($k >= (($i-1)*37)+1) && ($k <= ($i*37))) {
        	   // get pagewidth
		   $page_width = $pdf->get_max_page_width();
			
		   // caption
		   $caption = trim(str_replace(array('(',')','...'),"", $pdf->_textstring($o['t']))).' ';
		   $caption = trim(str_replace(' ...',"...", $caption)).' ';
		   $caption_width = $pdf->GetStringWidth($caption);
		   
		   // page no
		   $page_no = str_replace(array("(",")"),"",$pdf->_textstring($o['p']));
		   $page_no_width = $pdf->GetStringWidth(' '.$page_no);

		      // build link
   			$link = $pdf->AddLink();
   			$pdf->SetLink($link, 0, $page_no); 
		   
		   // width for dots
		   $dots_width = ($page_width - $caption_width - $page_no_width - 4);
		   
		   // calculate number of dots
		   $num_dots = $dots_width / $pdf->GetStringWidth('.');
		   $dots = str_repeat('.', $num_dots);
		   
		   $pdf->Cell($caption_width + 2, $pdf->FontSize+2, $caption, 0, 0, '', 0, $link);
		   $pdf->Cell($dots_width + 2, $pdf->FontSize+2, $dots, 0, 0, 'R');
		   $pdf->Cell($page_no_width + 2, $pdf->FontSize+2, $page_no, 0, 0, 'R', 0, $link);
		   $pdf->Ln($pdf->FontSize+2);
		   }
        }
	}
        
$pdf->page=$last; 

//$pdf->Footers();
	$pdfFile = PMF_ROOT_DIR."/pdf/faq.pdf";
	$pdf->Output($pdfFile);

	print "<p>".$PMF_LANG["ad_export_full_faq"]."<a href=\"../pdf/faq.pdf\" target=\"_blank\">".$PMF_CONF["title"]."</a></p>";
}
Dazu noch in der \admin\pdf.php die Funktionen footer() und header() angepasst:

Code: Select all

	/**
    * The footer of the PDF file
    *
    * @return   void
    * @access   private
    */
	function Footer() {
	    global $cat, $PMF_CONF, $PMF_LANG;
        $currentTextColor = $this->TextColor;
	    $this->SetFillColor(245,245,245);
	    $this->SetTextColor(0,0,0);
	    $this->SetDrawColor(0,0,0);
	    $this->SetY(-25);
	    $this->Rect(0,$this->GetY(), $this->w, 30,"F"); 
	    $this->SetFont("Arial", "I", 10);
	    $this->Cell(0, 10, $PMF_LANG["ad_gen_page"]." ".$this->PageNo()."/{nb}",0,0,"C");
	    $this->SetY(-20);
	    $this->SetFont("Arial", "B", 8);
	    $this->Cell(0, 10, "(c) ".date("Y")." ".$PMF_CONF["metaPublisher"]." <".$PMF_CONF["adminmail"].">",0,1,"C");
	    if ($this->enableBookmarks == false) {
	        $this->SetY(-15);
	        $this->SetFont("Arial", "", 8);
            $_url = "http".(isset($_SERVER["HTTPS"]) ? "s" : "")."://".$_SERVER["HTTP_HOST"].str_replace("pdf.php", "index.php?action=artikel&cat=".$this->categories[$this->rubrik]["id"]."&id=".$_REQUEST["id"]."&artlang=".$_REQUEST["lang"], $_SERVER["PHP_SELF"]);
	        $this->Cell(0, 10, "URL: ".$_url, 0, 1, "C", 0, $_url);
	    }
	    $this->SetY(-15);
	    $this->SetFont("Arial", "", 8);
	    $this->Cell(0, 10, "Stand: ".$this->timestamp." Uhr",0,1,"C");
        $this->TextColor = $currentTextColor;
	}
und

Code: Select all

    /**
    * The header of the PDF file
    *
    * @return   void
    * @access   private
    */
	function Header()
    {
        $temp= $this->w-$this->rMargin-$this->lMargin-$this->x;
        $this->SetFont("Arial", "I", 18);
        if ($this->WordWrap($this->thema,$temp) > 1) {
        	$tempY = 5;
        }else{
        	$tempY = 10;
        }
        $title = $this->thema;
        $currentTextColor = $this->TextColor;
        $this->SetTextColor(0,0,0);
        $this->SetFillColor(245,245,245);
        $this->Rect(0,0, $this->w, 27,"F");
        $this->SetFillColor(222,222,222);
        $this->Rect(0,27, $this->w, 5,"F");
        $this->SetFont("Arial", "I", 18);
        $this->SetY($tempY);
        $this->MultiCell(0, 9, $title, 0, "L",0);
		$this->cats = $this->categories;
		$this->SetY(32);
        $this->Ln(5);
        if ($this->enableBookmarks == true) {
            $this->Bookmark(makeShorterText($this->thema, 5));
        }
        $this->TextColor = $currentTextColor;
	}
Um festzustellen, ob der Titel ggf. Zweizeilig ist und damit die Ausgabe im Header angepackt werden muss, habe ich der /inc/php.pdf noch eine neue Funktion "WordWrap()" hinzugefügt:

Code: Select all

   function WordWrap(&$text, $maxwidth)
	{
	    $text = trim($text);
	    if ($text==='')
	        return 0;
	    $space = $this->GetStringWidth(' ');
	    $lines = explode("\n", $text);
	    $text = '';
	    $count = 0;
	
	    foreach ($lines as $line)
	    {
	        $words = preg_split('/ +/', $line);
	        $width = 0;
	
	        foreach ($words as $word)
	        {
	            $wordwidth = $this->GetStringWidth($word);
	            if ($width + $wordwidth <= $maxwidth)
	            {
	                $width += $wordwidth + $space;
	                $text .= $word.' ';
	            }
	            else
	            {
	                $width = $wordwidth + $space;
	                $text = rtrim($text)."\n".$word.' ';
	                $count++;
	            }
	        }
	        $text = rtrim($text)."\n";
	        $count++;
	    }
	    $text = rtrim($text);
	    return $count;
	}
Das verwendete Info-Image könnt Ihr Euch hier herunterladen: [img=http://img341.imageshack.us/img341/5200/info2bc.jpg]

Achtung:
Das Inhaltsverzeichnis wurde per Dirty-Code realisiert, da FPDF selbst offiziell keine Möglichkeit bietet, Seiten zu verschieben bzw. nachträglich mit Inhalt zu versehen.

Gruß

Mini

PS: Ich habe das Original-SQL-Statement angepasst, um eine alphabetisch sortierte Artikelliste zu erhalten und zu vermeiden, dass Artikel, die in mehreren Rubriken veröffentlicht werden, mehrfach auftauchen. Besser wäre sicherlich, wenn die Bookmarks auch verschachtelt angezeigt werden könnten. Hab ich aber im Moment nicht die Zeit mir darum Gedanken zu machen, zumal phpmyfaq eine propertiäre Funktion nutzt, um die Bookmarks zu erstellen und nicht die als Add-On zu FPDF angebotene TOC-Lösung. Damit wären Verschachtelungen möglich.
matteo
Posts: 572
Joined: Sun Nov 20, 2005 6:53 pm
Location: Italy

Post by matteo »

Hi,
excellent work! Really nice ToC and layout :wink:.

Thanks for sharing your efforts!
phpMyFAQ QA / Developer
Amazon.co.uk Wishlist
Mini
Posts: 63
Joined: Mon May 08, 2006 11:11 pm

Post by Mini »

Hi,

thx for feedback.

Hope it helps other users or next phpMyFAQ-Version!
psp-faq
Posts: 46
Joined: Fri Feb 09, 2007 10:02 am
Contact:

Post by psp-faq »

Hi,

ich habe mal probiert diese wirklich sehr nette Erweiterung einzubauen, aber bei mit kommt immer ein Fehler?!

Code: Select all

Fatal error: Call to undefined function: get_max_page_width() in /kunden/126657_89551/webseiten/psp-faq/admin/export.main.php on line 157
Da ich mich ein bisschen auskenne, seh ich das versucht wird eine Funktion aufzurufen die es anscheinend gar nicht gibt?

Diese Erweiterung wäre genau das was ich suche, aber ich bekomme sie leider nicht zum laufen...

Ich hoffe jemand kann mir da helfen?

Grüße
Bastian
roverman
Posts: 4
Joined: Fri May 04, 2007 3:00 pm

Post by roverman »

Für welche Version von phpMyFAQ ist diese Aenderung?

Ich finde in meiner phpMyFAQ 1.6.11 installation das file admin\pdf.php nicht :(

danke für info..

Remco
Thorsten
Posts: 15559
Joined: Tue Sep 25, 2001 11:14 am
Location: #phpmyfaq
Contact:

Post by Thorsten »

Hi,

ich denke, er meint die inc/pdf.php.

bye
Thorsten
phpMyFAQ Maintainer and Lead Developer
amazon.de Wishlist
roverman
Posts: 4
Joined: Fri May 04, 2007 3:00 pm

Post by roverman »

Danke Thorsten, da hätte ich auch selber draufkommen müssen

Was mir jetzt noch nicht klar ist was aufgerufen werden muss um alle Artikel exportieren zu können.

Danke

Remco
Mini
Posts: 63
Joined: Mon May 08, 2006 11:11 pm

Post by Mini »

Hi,

war lange nicht mehr aktiv.

Möchte gerne antworten...(vielleicht auch schon zu spät, aber besser spät als nie!):

@roverman
Die Funktion wurde in der Version phpMyFAQ 1.6.0 umgesetzt und funktioniert dort bis heute einwandfrei. ;o) Ich habe nie auf neuere Version aktualisiert.

Thorsten hat recht, ich meinte die inc/pdf.php!

Der Aufruf erfolgt ganz einfach über die Funktion "FAQ exportieren" im Admin-Menü. Mir war das aber zu mühselig, das bei jeder Artikel-Änderung oder -Neuanlage neu zu machen und bin daher hergegangen und habe die o.g. Export-Exportfunktion (ohne die äußere if-Bedingung) direkt in admin/record.add.php (direkt vor "<h3><strong><em><?php print $categorylist; ?></em>" und in admin/record.save.php (in der if-Bedingung "if ($db->query($query)) {
" direkt vor "print $PMF_LANG["ad_entry_savedsuc"];") eingefügt.


@psp-faq:
Mhm, vielleicht habe ich was vergessen zu posten. Meine inc/pdf.php enthält direkt nach der WordWrap-Funktion noch folgendes:

Code: Select all

	function get_max_page_width() {
	   // get pagewidth
	   $page_width = $this->w - $this->lMargin - $this->rMargin;
	   return($page_width);
	}
	
	function make_toc_entry(&$pdf, $caption, $page_no) {
	   // set font
	   $pdf->SetFont('Arial', '', DOC_FONT_SIZE);
	
	   // get pagewidth
	   $page_width = get_max_page_width($pdf);
	
	   // build link
	   $link = $pdf->AddLink();
	   $this->SetLink($link, 0, $page_no);
	   
	   // caption
	   $caption = $caption.' ';
	   $caption_width = $pdf->GetStringWidth($caption);
	   
	   // page no
	   $page_no_width = $pdf->GetStringWidth(' '.$page_no);
	   
	   // width for dots
	   $dots_width = ($page_width - $caption_width - $page_no_width - 4);
	   
	   // calculate number of dots
	   $num_dots = $dots_width / $pdf->GetStringWidth('.');
	   $dots = str_repeat('.', $num_dots);
	   
	   $pdf->Cell($caption_width + 2, $pdf->FontSize+2, $caption, 0, 0, '', 0, $link);
	   $pdf->Cell($dots_width + 2, $pdf->FontSize+2, $dots, 0, 0, 'R');
	   $pdf->Cell($page_no_width + 2, $pdf->FontSize+2, $page_no, 0, 0, 'R', 0, $link);
	   $pdf->Ln($pdf->FontSize+2);
	
	} 
Runers
Posts: 64
Joined: Fri Feb 23, 2007 9:17 pm
Location: Deutschland
Contact:

Post by Runers »

Hallo Thorsten

kann man diese tolle Funktion nicht gleich in MyFAQ einbinden?

Gruß
Dirk
Image
Thorsten
Posts: 15559
Joined: Tue Sep 25, 2001 11:14 am
Location: #phpmyfaq
Contact:

Post by Thorsten »

Hi,

ja, für die 2.5 können wir das einbauen. Einfach in dem betreffenden Thread im anderen Forum posten.

bye
Thorsten
phpMyFAQ Maintainer and Lead Developer
amazon.de Wishlist
genios
Posts: 3
Joined: Tue Dec 11, 2007 11:42 pm

Re: PDF-Export aller Artikel mit Inhaltsverzeichnis

Post by genios »

Hallo Mini,
habe die export.main.php im Admin-Ordner wie folgt modifizert, um bei der exportierten PDF aller Artikel eine vernünftige Darstellung mit einem Inhaltsverzeichnis hinzubekommen (Achtung, habe die Sprache manuell gesetzt!!!!):
Versuche gerade die PDF-Inhaltsdarstellung in die export.main.php (Ver. 2.0.5) einzubauen. Anwelcher Stelle fügst du das im Skript ein?

Gruß Olaf
Mini
Posts: 63
Joined: Mon May 08, 2006 11:11 pm

Post by Mini »

Sorry, tml, die Version 2.x habe ich nicht im Einsatz.

Vielleicht kann Thorsten helfen?
Thorsten
Posts: 15559
Joined: Tue Sep 25, 2001 11:14 am
Location: #phpmyfaq
Contact:

Post by Thorsten »

Hi,

für die 2.0er oder die kommende 2.5er ist das so nicht einsetzbar... :-(

bye
Thorsten
phpMyFAQ Maintainer and Lead Developer
amazon.de Wishlist
genios
Posts: 3
Joined: Tue Dec 11, 2007 11:42 pm

PDF Wunschliste

Post by genios »

Hallo Thorsten,
kannst du das etwas Spezifizieren wo ist der grundlegende Unterschied?

Ansonsten ist dies mit Sicherheit ein Fall für die Wunschliste.

also schön verpackt in 7 Tagen untern Baum :D

Gruß Olaf
Thorsten
Posts: 15559
Joined: Tue Sep 25, 2001 11:14 am
Location: #phpmyfaq
Contact:

Post by Thorsten »

Hi,

der grundlegende Unterschied sieht man schon an der Versionsnummer... die 2.x ist einfach komplett anders programmiert als die 1er

bye
Thorsten
phpMyFAQ Maintainer and Lead Developer
amazon.de Wishlist
Post Reply