Translations of this page?:

Download as PDF

pdfdownload plugin by Werner Flamme
extracting the content of a page as PDF

Last updated on 2006-07-03.
Compatible with DokuWiki 2006-11-06 and later.

Similar to pdfex.

Tagged with export, pdf.

Sometimes you want to save the actual page of DokuWiki as a PDF File, but you have no PDF printer installed. So it may be an alternative to create a PDF file by the server. :-)

I chose a way to convert the content only, so it does not look like the page you get when you use the print button of your browser. Nevertheless, the text appears ;-)

As a conversion tool I use HTML2FPDF, since there is no need to install any additional tools. It doesn't do conversions conversions as other tools, but when you have webspace only for your domain, you are not able to install any tools on the web server in most cases.

Inside DokuWiki

At first, I had to look into the template's main.php (I use the ACH template), where the content is displayed. I found <?php tpl_content(); ?> and decided to use this as the point to get the content of the page. The content is completely parsed and ready for output here. I modified the code and now have a variable to keep the content in:

<?php
  ob_start();
  tpl_content();
  $myhtml = ob_get_contents();
  ob_end_clean();
  // some manipulation of $myhtml here,
  // e.g. I change the quotation marks
  echo $myhtml;
?>

Then I looked for a position in the template to show a link to the created PDF file. It must be underneath the line that was modified. I want the link in the footer, so I searched for this position and entered the following code:

<?php
  // modify "local" URLs
  $myhtml = utf8_decode($myhtml);
  $repl_link = array('href', 'src', 'action');
  foreach ($repl_link as $to_replace) {
     $repl_searchfor = '/' . $to_replace . '="\/(.*?)"/';
      $repl_replwith  = $to_replace . '="http://' . $_SERVER['SERVER_NAME'] . '/$1"';
      $myhtml = preg_replace($repl_searchfor, $repl_replwith, $myhtml);
    } // foreach ($repl_link as $to_replace)
 
    // convert content -> PDF file
    include(DOKU_TPLINC . 'html2fpdf/cPDF.php');
    $destdir = DOKU_INC . 'tmp';
    if (! @is_dir("$destdir/")) @mkdir($destdir);
    // intermezzo: delete over-aged files
    $leaveTime = 60 * 60 * 24;
    if (@is_dir($destdir)) {
      if ($dh = @opendir($destdir)) {
        while (($file = @readdir($dh)) !== false) {
          if (time() - @filemtime($file) > $leaveTime) @unlink($file);
        } // while (($file = @readdir($dh)) !== false)
        @closedir($dh);
      } // if ($dh = @opendir($destdir))
    } // if (@is_dir($destdir))
    // end of intermezzo
    $tempf1 = @tempnam($destdir, 'PDF_');
    $tempf2 = strtolower($tempf1 . '.pdf');
    $linkname = DOKU_BASE . 'tmp/' . basename($tempf2);
    @link($tempf1, $tempf2);
    @unlink($tempf1);
    @chmod($tempf2, 0664);
    $mycss = dirname(__FILE__) . '/print.css';
    $myPDFsize = HTMLzuPDF($myhtml, $tempf2, $mycss);    
  ?>
    <p class="text"><a href="<?php print $myLinkTo; ?>"><?php print $lang['txt_domepdf']; ?></a></p>

As you see, I had to create a /tmp directory under DokuWiki's root dir in order to use the filenames given here. Besides, I had to download and copy HTML2FPDF – I chose the html2fpdf directory under the template's directory for this. And I wrote a function HTMLzuPDF() that is written in html2fpdf/cPDF.php (sorry for the german comments in this file, but I am german and created this code for my coworkers who are – like me – better in german than in english ;-)).

In the last step, I entered $lang['txt_domepdf'] = 'download as PDF'; in the en/lang.php file of my template.

In the second approach I added a routine to delete over-aged files – older than one day. When the website is highly frequented, this should be reduced to smaller times – 15 minutes will do, I guess :-)

Outside DokuWiki

As I said, I created a directory html2fpdf under the template's directory and inside a file cPDF.php, that contains the following function (and a lot of comments in german language):

// file cPDF.php
function HTMLzuPDF($Data, $filename = 'default.pdf', $css = 'webdev.css', 
                   $orientation = 'P', $unit = 'mm', $format = 'A4')
{
  define('FPDF_FONTPATH', (dirname(__FILE__) . '/font/') );
 
  if (!class_exists('HTML2FPDF')) {
    require_once(dirname(__FILE__) . '/html2fpdf.class.php');
  } // if (!class_exists('HTML2FPDF'))
 
  // look for output file
  $wrkfilnam = strtolower($filename);
  if (substr($filename, -4) != '.pdf') $wrkfilnam .= '.pdf';
  if ($wrkfilnam == 'default.pdf') $wrkfilnam = tempnam(DOKU_INC . '/tmp', "PDF_");
 
  // look for CSS data
  $myCSSfile = ($css == 'webdev.css') ? (dirname(__FILE__) . '/webdev.css') : $css;
  $myCSSdata = @file_get_contents($myCSSfile);
  $myCSSsize = strlen($myCSSdata);
  if ($myCSSsize == 0) {
    $myCSSfile = dirname(__FILE__) . '/webdev.css';
    $myCSSdata = @file_get_contents($myCSSfile);
  } // if ($myCSSsize == 0)
  $regexp = '|<style.*?</style>|si';
  $Data   = preg_replace($regexp, '', $Data);
  $Data   = $myCSSdata . $Data;
 
  // make PDF
  $myPDF = new HTML2FPDF($orientation, $unit, $format);
  $myPDF->Open();
  $myPDF->AddPage();
  $myPDF->ShowNOIMG_GIF(true);
  $myPDF->WriteHTML($Data);
  $dummy = $myPDF->Output("$wrkfilnam", 'F');
 
  $fillen = @filesize("$wrkfilnam");
  return $fillen;
} // function HTMLzuPDF

All files I needed are available for download (about 72 kByte). This is the file cPDF.php (content above), a dummy-like css file called webdev.css, and the unmodified sources of HTML2FPDF.

Annotations

HTML2FPDF does not have outstanding qualities in interpreting CSS data – for example, display: none; is not recognized and so the PDF file is sometimes looking a bit strange…

Before and after each picture (e. g. a smiley) there is a line break in the PDF file. There is not always a line break, when the picture is not found and the noimg.gif is used instead.

You can see the code in real life ;-) on my website http://www.wernerflamme.name – all in german, as you can see here, my english is not so good ;-)

I like to get some feedback – at least when it's positive ;-)Werner Flamme 2006-07-03

Discussion

I've installed it on my website here - http://www.curufea.com/hero/ but so far it generates pdfs in the tmp file only and does not let the user access the file. — Peter Cobcroft 2006-09-21 01:21

Some notes:

  • take a look at action and the TPL_CONTENT_DISPLAY event. This gets you a string of the xhtml of the wiki page before it is output. You can determine if you have a wiki page by checking the action ($ACT) and other DokuWiki globals.
  • action plugins can also be used to handle $ACT earlier in DokuWiki's processing. This could allow you to recognise a particular custom action, store it for future reference and change the action to show to get DokuWiki to render page output normally for use as described above.
  • be careful of characters not normally part of ASCII or ISO-8859-1 in your page.

Christopher Smith 2006-09-21 14:39

Christopher, thank you for putting my nose on the action and on the TPL_CONTENT_DISPLAY event! I had a little time and wrote my first action plugin called pdfex. It is neither nice nor good, but I hope I will have enough brains sometimes to continue the code… A big problem is the translation of HTML into PDF by means of PHP only. At the moment, I can't get pictures inside the PDF, always read errors – but the picture in the title is well integrated… — Werner Flamme 2006-09-22 22:50

Unlike the other PDF exporting plugins and mods I've seen on this wiki, it doesn't use actions, but the PHP streaming output capture commands, and going to a page automatically generates the PDF file. The link just accesses the now randomly named file in the tmp directory, deleting older ones. However- I've fixed it so it links I just changed the “$myLinkTo;” in the main.php footer to “$linkname” - however I want a button at the top and so will try making this version more like the action version elsewhere in this wiki — Peter Cobcroft 2006-09-22 01:21

Peter, maybe you look at pdfex – I just wrote it. It still creates a PDF file, but you can predict the file name: $pdfresultfile = DOKU_PDFEXDIR . 'PDF_' . str_replace(':', '_', $ID) . '.pdf';, where DOKU_PDFEXDIR is per default data/pdefex. Of course you are free to fix my faults ;-)Werner Flamme 2006-09-22 23:45

Pictures? The PDF-Code works on my Server, but if I've a Picture on my Wikipage it's not in the created PDF-File. Is that normal?

Hi 217.7.246.143, what is “normal”? ;-) Well, it's very often that the pictures are not converted. This is a limitation of the underlying PHP and HTML2FPDF. The methods that are used by HTML2FPDF sometimes do not work. I did not figure out a safe way to get around this. On my homepage, it worked fine – until one day, it didn't work at all. There were no changes to the code, but the PHP version was updated by my hoster… Sometimes the Smilies appear, sometimes not. :-(
I'm sorry, but I can not be of help here :-(Werner Flamme 2008-05-27 15:18 CEST

Pictures? Okay… I think that the PDF-Plugin is fine, but without pictures it makes lower sence to use it on a blog, which is full of graphical Features. But thanks for your answer.

 
plugin/pdfdownload.txt · Last modified: 2008/11/19 17:30 by wernerflamme
 

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Noncommercial-Share Alike 3.0 Unported

Imprint Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
WikiForumIRCBugsTranslate