We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 21560
    • 145 Posts
    As it is actually something on my wishlist, I’m looking into a nice way to generate HTML into PDF while still keeping support for PDF import

    It’s the combination that’s nagging at me at the moment. But I’m sure I’ll figure it out.
      [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com
    • Any luck on figuring that out ... combining CSS-styled XHTML on top of a PDF" template page" would be awesome.

      For that matter, have you figured out how to use a different template for the first page, or the first page of each section for longer sections?
        Ryan Thrash, MODX Co-Founder
        Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
        • 21560
        • 145 Posts
        Making a different first page would be easy, as is making a different in-between-page for every section.

        I’m very dissapointed by DOMPDF though. BEsides it’s speed (hellishly slow) it’s also not working above HTML pages over 280 kilobyte it seems. I’m going to test more, but at the moment, it will only convert until chapter 53. Which will not do.

        Otherwise, PDF’s look a lot nicer with CSS styling.

        Still looking at all the angles though.
          [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com
        • I’ll try to get Brian to chime in on our experience with PDF libraries and what we’re doing to use XHTML/CSS to control styling. We don’t have the ability to use PDFs with vector logos/images as templates OR multiple background templates though, so that would be the icing on the cake for us.
            Ryan Thrash, MODX Co-Founder
            Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
            • 1932
            • 137 Posts
            Great stuff, thanks for sharing Nimja. As Ryan mentioned, we have done some custom PDF generation before using custom snippets. I’ve tried most of the freely available PHP/Perl PDF conversion libraries and found that the most reliably accurate, albeit CPU intensive, method for conversion is using html2pdf PHP. http://tufat.com/s_html2ps_html2pdf.htm

            Html2pdf PHP includes a number of classes for parsing the XHTML and CSS that you might find interesting. It’s not a trivial matter to say the least, but I bet it wouldn’t be too hard to get custom fonts/CSS selectors working depending on how easy it is to embed fonts. Interestingly enough, I believe both the FPDI library you are using and the html2pdf PHP library rely on FPDF by default for the actual PDF generation.

            Definitely keep us posted as this progresses; feel free to post questions or problems, I’m more than happy to try and answer them.
              • 21560
              • 145 Posts
              I’ve looked into HTML2PDF and it has one tiny problem for me.

              It’s derived from the normal FPDF class, but NOT the FPDI class.

              But it’s definitely on my list to try out as well, as I’m quite happy with FPDF as a base to work with anyway. DOMPDF, besides it’s beautiful output when it DOES work, is too slow, too cumbersome and too unstable to use for a long story like mine.

              I mean, it can hardly render a THIRD of my story. While FPDI can render it completely, in much less time.

              Anyway, I’ll keep you guys posted when I know more.
                [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com
                • 21560
                • 145 Posts
                Bad news everyone (imagine Futurama here for a moment):

                HTML2PDF, based on FPDF does not use CSS well. After HEAVY testing I’ve finally given up on that one.

                And I’m talking BASIC CSS, like the margins of a <p> or a line beneath a <div>

                DOMPDF, based on another engine, renders very well, but has two major problems.
                1) It’s INSANELY SLOW. Rendering 50 ’chapters’ of my PDF in about 5 times the time FPDI needs to render 150. (so about 15 times slower probably even more).
                2) It can’t handle long pages and there is NO WAY to input content in ’pieces’

                HTML_TOPDF, is simply not an option, as it is based around the html2ps library, not a PHP library I might add.

                Please note that none of the above support PDF importing. So they’re not useful for pretty company documents.

                So... In the end I had to rewrite my whole function to make pretty styling and stay with FPDI

                Let me know if you guys consider it ’worthy’ to share. It’s basically a tutorial on really good FPDF use by now. Oh, and I can STILL include the PDF
                View the file via, the obvious link on the right side. - http://nimja.com/frozen-youth
                Please do not link it here directly.
                  [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com
                • Very cool stuff! Now for a few questions if you don’t mind smiley

                  [*] Can it support some of the CSS-3 properties like forced pagebreaks at the beginning of each chapter?
                  [*] Could you have a cover with a different PDF template appended at the front of the file?
                  [*] Could you have it generate a table of contents linked to the page numbers?
                  [*] Could you have it do an introduction with page numbers in the format of i, ii, iii, etc. then restart the page numbers at chapter 1?

                  Great work Nimja! I’d love to see the html/css and pdf controlling the output. Definitely worthy of sharing for sure. smiley
                    Ryan Thrash, MODX Co-Founder
                    Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
                    • 2327
                    • 214 Posts
                    Thank you very much, Nimja, for this very important question and your attention.

                    Have you take a look about the other CMS, like joomla, can make a pdf on real time ? Perhaps it’s a way..?

                    Thanks more for this very important question !
                      • 21560
                      • 145 Posts
                      * Can it support some of the CSS-3 properties like forced pagebreaks at the beginning of each chapter?
                      It doesn’t use HTML2PDF. I’m using my own written snippet that uses the FPDF styling to do this. so Yes, I can make a force pagebreak. In fact, every 10 chapters it does that.

                      * Could you have a cover with a different PDF template appended at the front of the file?
                      YES! Thats the reason I use FPDI, it can import PDF files. A cover or a template makes no difference wink
                      Back cover would be no problem.
                      * Could you have it generate a table of contents linked to the page numbers?
                      Yes/No. In fact I’m not sure. I do think it’s easy enough to have auto-generated PDF ’chapters’, with their internal link system. Good point though. Looking into that.

                      * Could you have it do an introduction with page numbers in the format of i, ii, iii, etc. then restart the page numbers at chapter 1?
                      Good question, I probably can. It’s relatively easy to do dynamic formatting in the document. You can even do a manual numbering.

                      And finally the other question...
                      Have you take a look about the other CMS, like joomla, can make a pdf on real time ? Perhaps it’s a way..?
                      Joomla sucks for what I do. I’m serious. I’m not saying it’s a bad CMS, it’s just... not appropriate for this kind of stuff. Even Wordpress would be more suitable. But at the moment there is no faster way to export a PDF than the way I do. So, this is already as real-time as it gets, baby!

                      ON a more serious note, I’m trying to report my findings here as well, so people can learn from them.

                      My current snippet:
                      Please note, this is NOT completely dynamic, author etc. are hard-coded. Easily changed obviously. Also, it’s purely made for a simple page and it only works with <i> tags at the moment. But it should give you a decent step up for a lot of things.

                      <?php
                      //Parent HAS to be given, we can't do anything without a parent.
                      if (isset($parent)) {
                      
                      	
                      	// &sortBY, field to sort by, defaults to pub_date.
                      	$sortBy = (!empty($sortBy) ) ? $sortBy : 'pub_date';
                      	
                      	// &sortHow, sort direction, defaults to ASC(ending).
                      	//	Options are: ASC, DESC
                      	$sortHow = (!empty($sortHow) ) ? $sortHow : 'ASC';
                      	
                      	//Fields we use.
                      	$fields = 'longtitle,introtext,content';
                      	
                      	$basepath = $modx->config['base_path']."assets/snippets/makepdf/";
                      	$classpath = $basepath.'class/';
                      	//Use nice MODX function to get children.
                      	$pages = $modx->getActiveChildren($parent, $sortBy, $sortHow, $fields);
                      
                      	require_once($classpath.'fpdi.php');
                      
                      /* ------------------------------------------
                      			Header and Footer to class
                      ------------------------------------------- */
                      	class PDF extends FPDI {
                      		function Header()
                      		{
                      		    $this->SetFont('Arial','I',11);
                      		    //Position at 1.5 cm from bottom
                      		    $this->SetY(5);
                      		    //Page number
                      		    $this->Cell(0,10,'Frozen Youth',0,1,'R');
                      		}
                      		function Footer()
                      		{
                      		    $this->SetFont('Arial','I',8);
                      		    //Position at 1.5 cm from bottom
                      		    $this->SetY(-15);
                      		    //Page number
                      		    $this->Cell(0,10,'Copyright 2007-2008 - Nimja.com',0,0,'L');
                      		    //Position at 1.5 cm from bottom
                      		    $this->SetY(-15);
                      		    //Page number
                      		    $this->Cell(0,10,$this->PageNo(),0,0,'R');
                      		}
                      	}	
                      
                      /* ------------------------------------------
                      			Start PDF and set the settings.
                      ------------------------------------------- */
                      
                      	// initiate FPDI 
                      	$pdf =& new PDF(); 
                      	// add a page 
                      	$pdf->AddPage(); 
                      	// set the sourcefile 
                      	$pdf->setSourceFile($basepath.'Page.pdf'); 
                      	$pdf->SetAuthor('Nimja');
                      	$pdf->SetCreator('Nimja');
                      	$pdf->SetTitle('Frozen Youth');
                      	
                      	// import page 1 
                      	$templatePage = $pdf->importPage(1); 
                      	// use the imported page and place it
                      	$pdf->useTemplate($templatePage); 
                      	$pdf->setTemplate($templatePage); 
                      
                      	$pdf->SetFont('Arial'); 
                      	$pdf->SetTextColor(0,0,0); 
                      	$pdf->SetLineWidth(.25);
                      	$pdf->SetDrawColor(0,0,0);
                      	$pdf->SetMargins(10,10);
                      	
                      	$newpage = false;
                      
                      	$remove = Array("\r", '<b>', '</b>');
                      	$clean = Array('<i>', '</i>');
                      
                      
                      /* ------------------------------------------
                      			Start content.
                      ------------------------------------------- */
                      	$c = 0;
                      	$italic = false;
                      	foreach ($pages as $page) {
                      		//echo $page['longtitle'].' - '.$page['introtext'].'<br />';
                      		$chapter = $page['longtitle'];
                      		$title = $page['introtext'];
                      		$content = str_replace($remove, '', $page['content']);
                      
                      		if ($c > 9) {
                      			$pdf->AddPage();
                      			$c=0;
                      		}
                      
                      		$pdf->SetX(10);
                      		$pdf->SetFont('Arial','',18);
                      		$pdf->Cell(0,7,$chapter.' - '.$title,'B',1,'L');
                      
                      		$pdf->Ln(3);
                      		$content = split("\n", $content);
                      		
                      		foreach ($content as $par) {
                      			$line = trim($par);
                      			if (empty($line) ) {
                      				$pdf->Ln(3);
                      				
                      			} else {
                      				if (strpos($line, '<i>') > -1) $italic = true;
                      				if ($italic) {
                      					$pdf->SetFont('Arial','i',11);
                      				} else {
                      					$pdf->SetFont('Arial','',11);
                      				}
                      				if (strpos($line, '</i>')) $italic = false;
                      				
                      				$line = str_replace($clean, '', $line);
                      				$pdf->MultiCell(0,4.5,$line,0,1,'L');
                      			}
                      		}
                      		$pdf->Ln(10);
                      		$italic = false;
                      		$c++;
                      	}
                      
                      	$pdf->Output('Frozen_Youth.pdf', 'd'); 
                      
                      } else {
                      	//Output error message because of missing parent ID
                      	echo 'Parent ID missing!';
                      }
                      ?>


                      ps. I should probably add more comments, but this is very much a work-in-progress.
                        [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com