Revision [8713]
This is an old revision of WikkaToPDF made by JavaWoman on 2005-05-29 18:39:12.
Exporting Wiki content to PDF
See also: WikkaFilters
I'm opening this page for a prelilminary discussion on how to generate PDFs from Wiki content.
An appropriate implementation of this feature would probably be a /pdf handler allowing a user to generate a PDF from a given page.
(More generally, an /export handler could give the user the choice about the preferred WikkaFilters export format). There are several GPL-licensed Java and php solution for generating PDFs on the fly.
Some references
- PHP
- FPDF
a PHP class, which allows to generate PDF files without using the PDFlib library.
- PC4P
a PDF class for PHP.
- PDF-PHP
Create pdf documents using PHP, but without installing any modules. Comprises a base class which performs all the pdf creation, and an extension class (ezPdf) to allow simple document creation.
- R&OS pdf class
a PHP class which will allow the easy production of simple pdf documents.
- Java
- FOP (Formatting Objects Processor)
(GPL) is the world's first print formatter driven by XSL formatting objects (XSL-FO) and the world's first output independent formatter. It is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. Output formats currently supported include PDF, PCL, PS, SVG, XML (area tree representation), Print, AWT, MIF and TXT. The primary output target is PDF.
- XWiki PDF Export
An implementation of FOP for XWiki.
- Mike, I tried the R&OS pdf class and it is fairly easy to set up. The example in he readme file for database tables works straight out of the box. Just change the database settings and the SQL to query the database and your almost there. (A SQL query like select tag,body from main_wikka_pages where tag="HomePage" and latest="y"'; gives you output like this Of course, it shows that we need to handle the hyperlink formatting too. --JamesMcl .
Discussion
Hi James. Any progress on generating a PDF file output from wikka? -- Mike Bowen (GmBowen)- Sorry Mike, no progress as yet as I've got other things to do at the moment. My lack of programming skills doesn't help although I have had success using the class without wikka. It shouldn't be too difficult though. Basically you have a file which includes the FPDF Class and queries the database. The problem is restricting the results to the latest page and presumably reversing the wikka markup to show bold etc. I could e-mail you an example file if you would like, need your e-mail address though.
- Have a look at this example Mike.
As you can see it picks the Page Name and Content fromm the database alright. The script needs a little refinement to format the page layout correctly and as I said earlier to restrict the results set from the sl query. The code is below.
<?php define('FPDF_FONTPATH','font/'); require('mysql_table.php'); class PDF extends PDF_MySQL_Table { function Header() { //Title $this->SetFont('Arial','',18); $this->Cell(0,6,'Wikka Output To PDF',0,1,'C'); $this->Ln(10); //Ensure table header is output parent::Header(); } } //Connect to database mysql_connect('localhost','user','password'); mysql_select_db('dbname'); $pdf=new PDF(); $pdf->Open(); $pdf->AddPage(); //First table: put all columns automatically $pdf->Table('select tag,body from main_wikka_pages'); $pdf->AddPage(); //Second table: specify 2 columns, $pdf->AddCol('tag',50,'tag','C'); $pdf->AddCol('body',50,'body','C'); $prop=array('HeaderColor'=>array(255,150,100), 'color1'=>array(210,245,255), 'color2'=>array(255,255,210), 'padding'=>2); //$pdf->Table('select tag,body from main_wikka_pages order by tag limit 0,10',$prop); $pdf->Output(wikka,I); ?>
Thanks James. I've got an undergrad programmer hired for a few weeks in May....and I found the pdf generating code for wikini as well (which is now only in a google cache).....so I'm probably going to have him try and get pdf output working (using a handler). I found a "footnoting/endnoting" action for wikini too, so I'll get him working on that also. When either are working I'll post them up (um, I hope this is okay and you don't feel like your efforts are being hi-jacked.....some people are really touchy about such things, but I really do need PDF output from wikka.). Cheers. --GmBowen
- Mike, have a look at FPDF at http://www.fpdf.org. Download the class and one of the database examples from the examples page. I'm sure your undergrad will have it working in no time. For what it's worth, I would like to place a link on each page or footer that allowed for the content to be saved as a pdf file. A further option to e-mail the page to another wikka user would also be good. I hope to hear about your success with this, soon. Cheers Jim.
- make a concept for ExportToPdf
- I sure hope somebody grabbed this code as it's not there any more. If you have it, please let me know. I have a php coder working for me the next 2 months who may be able to adapt it for wikka. --GmBowen
- Looks like there is no code yet - as far as I can deduce from the wiki2pdf page the project is still in the conceptual stage? http://www.thierrybazzanella.com/ only redirects to another (Flash-only) site. --JavaWoman
- I've looked at the page but forgot to grab the code (I darkly remember the beeing of code on the page) --NilsLindenberg
I (gmb) found the wikini code in a cache. here it is.....
<?php
/*
raw.php
version : test2
SEE PRINTED NOTES
Copyright 2004 Thierry BAZZANELLA
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
define('FPDF_FONTPATH','/home/users/thierrybazzanella/html/font/');
require('fpdf.php');
// fonction hex2dec
// retourne un tableau associatif (clés : R,V,B) à
// partir d'un code html de couleur hexa (ex : #3FE5AA)
function hex2dec($couleur = "#000000"){
$R = substr($couleur, 1, 2);
$rouge = hexdec($R);
$V = substr($couleur, 3, 2);
$vert = hexdec($V);
$B = substr($couleur, 5, 2);
$bleu = hexdec($B);
$tbl_couleur = array();
$tbl_couleur['R']=$rouge;
$tbl_couleur['V']=$vert;
$tbl_couleur['B']=$bleu;
return $tbl_couleur;
}
//conversion pixel -> millimètre en 72 dpi
function px2mm($px){
return $px*25.4/72;
}
function txtentities($html){
$trans = get_html_translation_table(HTML_ENTITIES);
$trans = array_flip($trans);
return strtr($html, $trans);
}
// Surcharge de la CLASSE FPDF :
class PDF extends FPDF
{
var $B;
var $I;
var $U;
var $HREF;
var $fontList;
var $issetfont;
var $issetcolor;
var $WIKIPAGE;
function PDF($orientation='P',$unit='mm',$format='A4')
{
//Appel au constructeur parent
$this->FPDF($orientation,$unit,$format);
//Initialisation
$this->B=0;
$this->I=0;
$this->U=0;
$this->HREF='';
$this->fontlist=array("arial","times","courier","helvetica","symbol");
$this->issetfont=false;
$this->issetcolor=false;
}
function setWikiPage($page) {
$this->WIKIPAGE=$page;
}
function getWikiPage() {
return $this->WIKIPAGE;
}
function WriteHTML($html)
{
//Parseur HTML
$html=strip_tags($html,"<b><u><i><a><img><p><br><strong><em><font><tr><blockquote>"); //supprime tous les tags sauf ceux reconnus
$html=str_replace("\n",' ',$html); //remplace retour à la ligne par un espace
$a=preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE); //éclate la chaîne avec les balises
foreach($a as $i=>$e)
{
if($i%2==0)
{
//Texte
if($this->HREF)
$this->PutLink($this->HREF,$e);
else
$this->Write(5,stripslashes(txtentities($e)));
}
else
{
//Balise
if($e{0}=='/')
$this->CloseTag(strtoupper(substr($e,1)));
else
{
//Extraction des attributs
$a2=explode(' ',$e);
$tag=strtoupper(array_shift($a2));
$attr=array();
foreach($a2 as $v)
if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
$attr[strtoupper($a3[1])]=$a3[2];
$this->OpenTag($tag,$attr);
}
}
}
}
function OpenTag($tag,$attr) //Balise ouvrante
{
switch($tag){
case 'STRONG':
$this->SetStyle('B',true);
break;
case 'EM':
$this->SetStyle('I',true);
break;
case 'B':
case 'I':
case 'U':
$this->SetStyle($tag,true);
break;
case 'A':
$this->HREF=$attr['HREF'];
break;
case 'IMG':
if(isset($attr['SRC']) and (isset($attr['WIDTH']) or isset($attr['HEIGHT']))) {
if(!isset($attr['WIDTH']))
$attr['WIDTH'] = 0;
if(!isset($attr['HEIGHT']))
$attr['HEIGHT'] = 0;
$this->Image($attr['SRC'], $this->GetX(), $this->GetY(), px2mm($attr['WIDTH']), px2mm($attr['HEIGHT']));
}
break;
case 'TR':
case 'BLOCKQUOTE':
case 'BR':
$this->Ln(5);
break;
case 'P':
$this->Ln(10);
break;
case 'FONT':
if (isset($attr['COLOR']) and $attr['COLOR']!='') {
$coul=hex2dec($attr['COLOR']);
$this->SetTextColor($coul['R'],$coul['V'],$coul['B']);
$this->issetcolor=true;
}
if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist)) {
$this->SetFont(strtolower($attr['FACE']));
$this->issetfont=true;
}
break;
}
}
function CloseTag($tag) //Balise fermante
{
if($tag=='STRONG')
$tag='B';
if($tag=='EM')
$tag='I';
if($tag=='B' or $tag=='I' or $tag=='U')
$this->SetStyle($tag,false);
if($tag=='A')
$this->HREF='';
if($tag=='FONT'){
if ($this->issetcolor==true) {
$this->SetTextColor(0);
}
if ($this->issetfont) {
$this->SetFont('arial');
$this->issetfont=false;
}
}
}
function SetStyle($tag,$enable)
{
//Modifie le style et sélectionne la police correspondante
$this->$tag+=($enable ? 1 : -1);
$style='';
foreach(array('B','I','U') as $s)
if($this->$s>0)
$style.=$s;
$this->SetFont('',$style);
}
function PutLink($URL,$txt)
{
//Place un hyperlien
$this->SetTextColor(0,0,255);
$this->SetStyle('U',true);
$this->Write(5,$txt,$URL);
$this->SetStyle('U',false);
$this->SetTextColor(0);
}
//En-tête
function Header()
{
//Positionnement à 0,1 cm du haut
$this->SetY(1);
//Police Arial italique 8
$this->SetFont('Arial','I',8);
//Numéro de page
$this->Cell(0,10,$this->getWikiPage().' - Page '.$this->PageNo().'/{nb}',0,0,'C');
$this->SetY(14);
}
//Pied de page
function Footer()
{
//Positionnement à 1,5 cm du bas
$this->SetY(-15);
//Police Arial italique 8
$this->SetFont('Arial','I',8);
//Numéro de page
$this->Cell(0,10,'http://www.thierrybazzanella.com - Page '.$this->PageNo().'/{nb}',0,0,'C');
}
//Chargement des données
function LoadData($file)
{
//Lecture des lignes du fichier
$lines=file($file);
$data=array();
foreach($lines as $line)
$data[]=explode(';',chop($line));
return $data;
}
//Tableau simple
function BasicTable($header,$data)
{
//En-tête
foreach($header as $col)
$this->Cell(40,7,$col,1);
$this->Ln();
//Données
foreach($data as $row)
{
foreach($row as $col)
$this->Cell(40,6,$col,1);
$this->Ln();
}
}
//Tableau amélioré
function ImprovedTable($header,$data)
{
//Largeurs des colonnes
$w=array(40,35,45,40);
//En-tête
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C');
$this->Ln();
//Données
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR');
$this->Cell($w[1],6,$row[1],'LR');
$this->Cell($w[2],6,number_format($row[2],0,',',' '),'LR',0,'R');
$this->Cell($w[3],6,number_format($row[3],0,',',' '),'LR',0,'R');
$this->Ln();
}
//Trait de terminaison
$this->Cell(array_sum($w),0,'','T');
}
//Tableau coloré
function FancyTable($header,$data)
{
//Couleurs, épaisseur du trait et police grasse
$this->SetFillColor(255,255,0);
$this->SetTextColor(255);
$this->SetDrawColor(128,0,0);
$this->SetLineWidth(.3);
$this->SetFont('','B');
//En-tête
$w=array(40,35,45,40);
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C',1);
$this->Ln();
//Restauration des couleurs et de la police
$this->SetFillColor(224,235,255);
$this->SetTextColor(0);
$this->SetFont('');
//Données
$fill=0;
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR',0,'L',$fill);
$this->Cell($w[1],6,$row[1],'LR',0,'L',$fill);
$this->Cell($w[2],6,number_format($row[2],0,',',' '),'LR',0,'R',$fill);
$this->Cell($w[3],6,number_format($row[3],0,',',' '),'LR',0,'R',$fill);
$this->Ln();
$fill=!$fill;
}
$this->Cell(array_sum($w),0,'','T');
}
}
//vérification de sécurité
if (!eregi("wakka.php", $_SERVER['PHP_SELF'])) {
die ("accès direct interdit");
}
if ($this->HasAccess("read"))
{
if (!$this->page)
{
return;
}
else
{
if ($_GET["save"]) {
header("Content-type: text/plain");
// display raw page
echo $this->page["body"];
$filename = "setup/doc/".$this->GetPageTag().".txt";
if (!$fp = fopen($filename, 'w')) {
echo $this->Format("//Impossible de créer le fichier ($filename)//");
exit;
}
if (!fwrite($fp, $this->page["body"])) {
echo $this->Format("//Impossible d'écrire dans le fichier ($filename)//");
exit;
}
fclose($fp);
}
if ($_GET["pdf"]) {
//Instanciation de la classe dérivée
$pdf=new PDF();
$pdf->AliasNbPages();
$pdf->SetMargins(10, 10, 10);
$pdf->setWikiPage ($this->GetPageTag());
$pdf->AddPage();
$pdf->WriteHTML($this->Format($this->page["body"], "wakka"));
$pdf->Output();
}
}
}
else
{
return;
}
?>
/*
raw.php
version : test2
SEE PRINTED NOTES
Copyright 2004 Thierry BAZZANELLA
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
define('FPDF_FONTPATH','/home/users/thierrybazzanella/html/font/');
require('fpdf.php');
// fonction hex2dec
// retourne un tableau associatif (clés : R,V,B) à
// partir d'un code html de couleur hexa (ex : #3FE5AA)
function hex2dec($couleur = "#000000"){
$R = substr($couleur, 1, 2);
$rouge = hexdec($R);
$V = substr($couleur, 3, 2);
$vert = hexdec($V);
$B = substr($couleur, 5, 2);
$bleu = hexdec($B);
$tbl_couleur = array();
$tbl_couleur['R']=$rouge;
$tbl_couleur['V']=$vert;
$tbl_couleur['B']=$bleu;
return $tbl_couleur;
}
//conversion pixel -> millimètre en 72 dpi
function px2mm($px){
return $px*25.4/72;
}
function txtentities($html){
$trans = get_html_translation_table(HTML_ENTITIES);
$trans = array_flip($trans);
return strtr($html, $trans);
}
// Surcharge de la CLASSE FPDF :
class PDF extends FPDF
{
var $B;
var $I;
var $U;
var $HREF;
var $fontList;
var $issetfont;
var $issetcolor;
var $WIKIPAGE;
function PDF($orientation='P',$unit='mm',$format='A4')
{
//Appel au constructeur parent
$this->FPDF($orientation,$unit,$format);
//Initialisation
$this->B=0;
$this->I=0;
$this->U=0;
$this->HREF='';
$this->fontlist=array("arial","times","courier","helvetica","symbol");
$this->issetfont=false;
$this->issetcolor=false;
}
function setWikiPage($page) {
$this->WIKIPAGE=$page;
}
function getWikiPage() {
return $this->WIKIPAGE;
}
function WriteHTML($html)
{
//Parseur HTML
$html=strip_tags($html,"<b><u><i><a><img><p><br><strong><em><font><tr><blockquote>"); //supprime tous les tags sauf ceux reconnus
$html=str_replace("\n",' ',$html); //remplace retour à la ligne par un espace
$a=preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE); //éclate la chaîne avec les balises
foreach($a as $i=>$e)
{
if($i%2==0)
{
//Texte
if($this->HREF)
$this->PutLink($this->HREF,$e);
else
$this->Write(5,stripslashes(txtentities($e)));
}
else
{
//Balise
if($e{0}=='/')
$this->CloseTag(strtoupper(substr($e,1)));
else
{
//Extraction des attributs
$a2=explode(' ',$e);
$tag=strtoupper(array_shift($a2));
$attr=array();
foreach($a2 as $v)
if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
$attr[strtoupper($a3[1])]=$a3[2];
$this->OpenTag($tag,$attr);
}
}
}
}
function OpenTag($tag,$attr) //Balise ouvrante
{
switch($tag){
case 'STRONG':
$this->SetStyle('B',true);
break;
case 'EM':
$this->SetStyle('I',true);
break;
case 'B':
case 'I':
case 'U':
$this->SetStyle($tag,true);
break;
case 'A':
$this->HREF=$attr['HREF'];
break;
case 'IMG':
if(isset($attr['SRC']) and (isset($attr['WIDTH']) or isset($attr['HEIGHT']))) {
if(!isset($attr['WIDTH']))
$attr['WIDTH'] = 0;
if(!isset($attr['HEIGHT']))
$attr['HEIGHT'] = 0;
$this->Image($attr['SRC'], $this->GetX(), $this->GetY(), px2mm($attr['WIDTH']), px2mm($attr['HEIGHT']));
}
break;
case 'TR':
case 'BLOCKQUOTE':
case 'BR':
$this->Ln(5);
break;
case 'P':
$this->Ln(10);
break;
case 'FONT':
if (isset($attr['COLOR']) and $attr['COLOR']!='') {
$coul=hex2dec($attr['COLOR']);
$this->SetTextColor($coul['R'],$coul['V'],$coul['B']);
$this->issetcolor=true;
}
if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist)) {
$this->SetFont(strtolower($attr['FACE']));
$this->issetfont=true;
}
break;
}
}
function CloseTag($tag) //Balise fermante
{
if($tag=='STRONG')
$tag='B';
if($tag=='EM')
$tag='I';
if($tag=='B' or $tag=='I' or $tag=='U')
$this->SetStyle($tag,false);
if($tag=='A')
$this->HREF='';
if($tag=='FONT'){
if ($this->issetcolor==true) {
$this->SetTextColor(0);
}
if ($this->issetfont) {
$this->SetFont('arial');
$this->issetfont=false;
}
}
}
function SetStyle($tag,$enable)
{
//Modifie le style et sélectionne la police correspondante
$this->$tag+=($enable ? 1 : -1);
$style='';
foreach(array('B','I','U') as $s)
if($this->$s>0)
$style.=$s;
$this->SetFont('',$style);
}
function PutLink($URL,$txt)
{
//Place un hyperlien
$this->SetTextColor(0,0,255);
$this->SetStyle('U',true);
$this->Write(5,$txt,$URL);
$this->SetStyle('U',false);
$this->SetTextColor(0);
}
//En-tête
function Header()
{
//Positionnement à 0,1 cm du haut
$this->SetY(1);
//Police Arial italique 8
$this->SetFont('Arial','I',8);
//Numéro de page
$this->Cell(0,10,$this->getWikiPage().' - Page '.$this->PageNo().'/{nb}',0,0,'C');
$this->SetY(14);
}
//Pied de page
function Footer()
{
//Positionnement à 1,5 cm du bas
$this->SetY(-15);
//Police Arial italique 8
$this->SetFont('Arial','I',8);
//Numéro de page
$this->Cell(0,10,'http://www.thierrybazzanella.com - Page '.$this->PageNo().'/{nb}',0,0,'C');
}
//Chargement des données
function LoadData($file)
{
//Lecture des lignes du fichier
$lines=file($file);
$data=array();
foreach($lines as $line)
$data[]=explode(';',chop($line));
return $data;
}
//Tableau simple
function BasicTable($header,$data)
{
//En-tête
foreach($header as $col)
$this->Cell(40,7,$col,1);
$this->Ln();
//Données
foreach($data as $row)
{
foreach($row as $col)
$this->Cell(40,6,$col,1);
$this->Ln();
}
}
//Tableau amélioré
function ImprovedTable($header,$data)
{
//Largeurs des colonnes
$w=array(40,35,45,40);
//En-tête
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C');
$this->Ln();
//Données
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR');
$this->Cell($w[1],6,$row[1],'LR');
$this->Cell($w[2],6,number_format($row[2],0,',',' '),'LR',0,'R');
$this->Cell($w[3],6,number_format($row[3],0,',',' '),'LR',0,'R');
$this->Ln();
}
//Trait de terminaison
$this->Cell(array_sum($w),0,'','T');
}
//Tableau coloré
function FancyTable($header,$data)
{
//Couleurs, épaisseur du trait et police grasse
$this->SetFillColor(255,255,0);
$this->SetTextColor(255);
$this->SetDrawColor(128,0,0);
$this->SetLineWidth(.3);
$this->SetFont('','B');
//En-tête
$w=array(40,35,45,40);
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C',1);
$this->Ln();
//Restauration des couleurs et de la police
$this->SetFillColor(224,235,255);
$this->SetTextColor(0);
$this->SetFont('');
//Données
$fill=0;
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR',0,'L',$fill);
$this->Cell($w[1],6,$row[1],'LR',0,'L',$fill);
$this->Cell($w[2],6,number_format($row[2],0,',',' '),'LR',0,'R',$fill);
$this->Cell($w[3],6,number_format($row[3],0,',',' '),'LR',0,'R',$fill);
$this->Ln();
$fill=!$fill;
}
$this->Cell(array_sum($w),0,'','T');
}
}
//vérification de sécurité
if (!eregi("wakka.php", $_SERVER['PHP_SELF'])) {
die ("accès direct interdit");
}
if ($this->HasAccess("read"))
{
if (!$this->page)
{
return;
}
else
{
if ($_GET["save"]) {
header("Content-type: text/plain");
// display raw page
echo $this->page["body"];
$filename = "setup/doc/".$this->GetPageTag().".txt";
if (!$fp = fopen($filename, 'w')) {
echo $this->Format("//Impossible de créer le fichier ($filename)//");
exit;
}
if (!fwrite($fp, $this->page["body"])) {
echo $this->Format("//Impossible d'écrire dans le fichier ($filename)//");
exit;
}
fclose($fp);
}
if ($_GET["pdf"]) {
//Instanciation de la classe dérivée
$pdf=new PDF();
$pdf->AliasNbPages();
$pdf->SetMargins(10, 10, 10);
$pdf->setWikiPage ($this->GetPageTag());
$pdf->AddPage();
$pdf->WriteHTML($this->Format($this->page["body"], "wakka"));
$pdf->Output();
}
}
}
else
{
return;
}
?>
And the handler was called using the line....
http://www.thierrybazzanella.com/wakka.php?wiki=Accueil/raw&pdf=1
and here are the instructions....
"Elle est téléchargeable vers http://www.fpdf.org
INSTALLATION:
Téléchargez la librairie fpdf et dézippez-là dans un dossier.
Mettez le fichier fpdf.php et le dossier font à la racine de votre wiki.
Téléchargez le fichier handlers/page/raw.php livré ICI,éditez le, et définissez en absolu le chemin du dossier font de votre arborescence fichier.
Ligne 25 : define('FPDF_FONTPATH','/home/www/users/thierrybazzanella/www/html/font/');
Remplacer ce fichier par le vôtre en lieu et place. "
that were there.
- Thanks, Mike. That looks nicely implemented - though I don't see where the page is turned into HTML first; my guess is you need to run it through the formatter first (it looks like it's transforming HTML tags - not Wiki-markup tags - for printing as PDF). But it shouldn't be too hard to make it work. --JavaWoman
- Mike, I just tried the R & OS pdf class. It works well straight out of the box. Change the database settings and the SQL query to something like select tag,body from wikka_pages where tag="HomePage" and latest="y" and you get this. Obviously, the hyperlink formatting will need to be addressed too. --JamesMcl
- Having a second look, some of the text seems to be missing from the page, I don't know why yet, may be something to do with the page layout --JamesMcl
- Maybe it's expecting an HTML document? It looks like lots of text is just cut off - but it's unformatted wiki source, so there really is no "page layout" - just a stream of plain text. I'd try running the wiki page through the formatter before feeding it to the PDF converter. BTW, what does "R & OS" stand for? --JavaWoman
- JavaWoman, I am not sure how you run a wiki page through the formatter. I don't know what "R & OS" stands for as the site that the class is on, http://www.ros.co.nz/ doesn't say on the web page. By the way DarTar, the PDF-PHP class is the same as the "R & OS" class. One is on the SourceForge site, the other on http://www.ros.co.nz/--JamesMcl
- Looking at the readme file on the http://www.ros.co.nz/ site it seems it does not expect any HTML at all, you need to do all the formatting yourself from raw data. Not so easy to do if what you need is a PDP equivalent of a rendered HTML page... Looks like FPDF is easier to implement. That said, you can run a wiki page (or any bit of code) through the formatter by just passing the code as a parameter to the formatter:
$output = $this->Format($input);--JavaWoman
Installing Fpdf
1. download the fpdf-package and put it's content into 3rdparty/plugins/fpdf
2. save the following code as handlers/page/pdf.php
<?php
/*
Copyright 2004 Thierry BAZZANELLA
@license GNU GPL
@author Thierry BAZZANELLA
@author Nils Lindenberg (changes for wikka, marked with NL)
*/
//(NL) changed for wikka
define('FPDF_FONTPATH','font/');
require_once('3rdparty/plugins/fpdf/fpdf.php');
// fonction hex2dec
// retourne un tableau associatif (clés : R,V,B) à
// partir d'un code html de couleur hexa (ex : #3FE5AA)
function hex2dec($couleur = "#000000"){
$R = substr($couleur, 1, 2);
$rouge = hexdec($R);
$V = substr($couleur, 3, 2);
$vert = hexdec($V);
$B = substr($couleur, 5, 2);
$bleu = hexdec($B);
$tbl_couleur = array();
$tbl_couleur['R']=$rouge;
$tbl_couleur['V']=$vert;
$tbl_couleur['B']=$bleu;
return $tbl_couleur;
}
//conversion pixel -> millimètre en 72 dpi
function px2mm($px){
return $px*25.4/72;
}
function txtentities($html){
$trans = get_html_translation_table(HTML_ENTITIES);
$trans = array_flip($trans);
return strtr($html, $trans);
}
// Surcharge de la CLASSE FPDF :
class PDF extends FPDF
{
var $B;
var $I;
var $U;
var $HREF;
var $fontList;
var $issetfont;
var $issetcolor;
var $WIKIPAGE;
function PDF($orientation='P',$unit='mm',$format='A4')
{
//Appel au constructeur parent
$this->FPDF($orientation,$unit,$format);
//Initialisation
$this->B=0;
$this->I=0;
$this->U=0;
$this->HREF='';
$this->fontlist=array("arial","times","courier","helvetica","symbol");
$this->issetfont=false;
$this->issetcolor=false;
}
function setWikiPage($page) {
$this->WIKIPAGE=$page;
}
function getWikiPage() {
return $this->WIKIPAGE;
}
function WriteHTML($html)
{
//Parseur HTML
$html=strip_tags($html,"<b><u><i><a><img><p><br><strong><em><font><tr><blockquote>"); //supprime tous les tags sauf ceux reconnus
$html=str_replace("\n",' ',$html); //remplace retour à la ligne par un espace
$a=preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE); //éclate la chaîne avec les balises
foreach($a as $i=>$e)
{
if($i%2==0)
{
//Texte
if($this->HREF)
$this->PutLink($this->HREF,$e);
else
$this->Write(5,stripslashes(txtentities($e)));
}
else
{
//Balise
if($e{0}=='/')
$this->CloseTag(strtoupper(substr($e,1)));
else
{
//Extraction des attributs
$a2=explode(' ',$e);
$tag=strtoupper(array_shift($a2));
$attr=array();
foreach($a2 as $v)
if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
$attr[strtoupper($a3[1])]=$a3[2];
$this->OpenTag($tag,$attr);
}
}
}
}
function OpenTag($tag,$attr) //Balise ouvrante
{
switch($tag){
case 'STRONG':
$this->SetStyle('B',true);
break;
case 'EM':
$this->SetStyle('I',true);
break;
case 'B':
case 'I':
case 'U':
$this->SetStyle($tag,true);
break;
case 'A':
$this->HREF=$attr['HREF'];
break;
case 'IMG':
if(isset($attr['SRC']) and (isset($attr['WIDTH']) or isset($attr['HEIGHT']))) {
if(!isset($attr['WIDTH']))
$attr['WIDTH'] = 0;
if(!isset($attr['HEIGHT']))
$attr['HEIGHT'] = 0;
$this->Image($attr['SRC'], $this->GetX(), $this->GetY(), px2mm($attr['WIDTH']), px2mm($attr['HEIGHT']));
}
break;
case 'TR':
case 'BLOCKQUOTE':
case 'BR':
$this->Ln(5);
break;
case 'P':
$this->Ln(10);
break;
case 'FONT':
if (isset($attr['COLOR']) and $attr['COLOR']!='') {
$coul=hex2dec($attr['COLOR']);
$this->SetTextColor($coul['R'],$coul['V'],$coul['B']);
$this->issetcolor=true;
}
if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist)) {
$this->SetFont(strtolower($attr['FACE']));
$this->issetfont=true;
}
break;
}
}
function CloseTag($tag) //Balise fermante
{
if($tag=='STRONG')
$tag='B';
if($tag=='EM')
$tag='I';
if($tag=='B' or $tag=='I' or $tag=='U')
$this->SetStyle($tag,false);
if($tag=='A')
$this->HREF='';
if($tag=='FONT'){
if ($this->issetcolor==true) {
$this->SetTextColor(0);
}
if ($this->issetfont) {
$this->SetFont('arial');
$this->issetfont=false;
}
}
}
function SetStyle($tag,$enable)
{
//Modifie le style et sélectionne la police correspondante
$this->$tag+=($enable ? 1 : -1);
$style='';
foreach(array('B','I','U') as $s)
if($this->$s>0)
$style.=$s;
$this->SetFont('',$style);
}
function PutLink($URL,$txt)
{
//Place un hyperlien
$this->SetTextColor(0,0,255);
$this->SetStyle('U',true);
$this->Write(5,$txt,$URL);
$this->SetStyle('U',false);
$this->SetTextColor(0);
}
//En-tête
function Header()
{
//Positionnement à 0,1 cm du haut
$this->SetY(1);
//Police Arial italique 8
$this->SetFont('Arial','I',8);
//Numéro de page
$this->Cell(0,10,$this->getWikiPage().' - Page '.$this->PageNo().'/{nb}',0,0,'C');
$this->SetY(14);
}
//Pied de page
function Footer()
{
//Positionnement à 1,5 cm du bas
$this->SetY(-15);
//Police Arial italique 8
$this->SetFont('Arial','I',8);
//Numéro de page
$this->Cell(0,10,'http://www.thierrybazzanella.com - Page '.$this->PageNo().'/{nb}',0,0,'C');
}
//Chargement des données
function LoadData($file)
{
//Lecture des lignes du fichier
$lines=file($file);
$data=array();
foreach($lines as $line)
$data[]=explode(';',chop($line));
return $data;
}
//Tableau simple
function BasicTable($header,$data)
{
//En-tête
foreach($header as $col)
$this->Cell(40,7,$col,1);
$this->Ln();
//Données
foreach($data as $row)
{
foreach($row as $col)
$this->Cell(40,6,$col,1);
$this->Ln();
}
}
//Tableau amélioré
function ImprovedTable($header,$data)
{
//Largeurs des colonnes
$w=array(40,35,45,40);
//En-tête
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C');
$this->Ln();
//Données
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR');
$this->Cell($w[1],6,$row[1],'LR');
$this->Cell($w[2],6,number_format($row[2],0,',',' '),'LR',0,'R');
$this->Cell($w[3],6,number_format($row[3],0,',',' '),'LR',0,'R');
$this->Ln();
}
//Trait de terminaison
$this->Cell(array_sum($w),0,'','T');
}
//Tableau coloré
function FancyTable($header,$data)
{
//Couleurs, épaisseur du trait et police grasse
$this->SetFillColor(255,255,0);
$this->SetTextColor(255);
$this->SetDrawColor(128,0,0);
$this->SetLineWidth(.3);
$this->SetFont('','B');
//En-tête
$w=array(40,35,45,40);
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C',1);
$this->Ln();
//Restauration des couleurs et de la police
$this->SetFillColor(224,235,255);
$this->SetTextColor(0);
$this->SetFont('');
//Données
$fill=0;
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR',0,'L',$fill);
$this->Cell($w[1],6,$row[1],'LR',0,'L',$fill);
$this->Cell($w[2],6,number_format($row[2],0,',',' '),'LR',0,'R',$fill);
$this->Cell($w[3],6,number_format($row[3],0,',',' '),'LR',0,'R',$fill);
$this->Ln();
$fill=!$fill;
}
$this->Cell(array_sum($w),0,'','T');
}
}
/* (NL) does not work with wikka
//vérification de sécurité
if (!eregi("wakka.php", $_SERVER['PHP_SELF'])) {
die ("accès direct interdit");
}
*/
if ($this->HasAccess("read"))
{
/* (NL) we want pdf -eport - *.txt would be another handler
if (!$this->page)
{
return;
}
else
{
if ($_GET["save"]) {
header("Content-type: text/plain");
// display raw page
echo $this->page["body"];
$filename = "setup/doc/".$this->GetPageTag().".txt";
if (!$fp = fopen($filename, 'w')) {
echo $this->Format("//Impossible de créer le fichier ($filename)//");
exit;
}
if (!fwrite($fp, $this->page["body"])) {
echo $this->Format("//Impossible d'écrire dans le fichier ($filename)//");
exit;
}
fclose($fp);
}
if ($_GET["pdf"]) { */
//Instanciation de la classe dérivée
$pdf=new PDF();
$pdf->AliasNbPages();
$pdf->SetMargins(10, 10, 10);
$pdf->setWikiPage ($this->GetPageTag());
$pdf->AddPage();
$pdf->WriteHTML($this->Format($this->page["body"], "wakka"));
$pdf->Output();
//}
//}
}
else
{
return;
}
?>
/*
Copyright 2004 Thierry BAZZANELLA
@license GNU GPL
@author Thierry BAZZANELLA
@author Nils Lindenberg (changes for wikka, marked with NL)
*/
//(NL) changed for wikka
define('FPDF_FONTPATH','font/');
require_once('3rdparty/plugins/fpdf/fpdf.php');
// fonction hex2dec
// retourne un tableau associatif (clés : R,V,B) à
// partir d'un code html de couleur hexa (ex : #3FE5AA)
function hex2dec($couleur = "#000000"){
$R = substr($couleur, 1, 2);
$rouge = hexdec($R);
$V = substr($couleur, 3, 2);
$vert = hexdec($V);
$B = substr($couleur, 5, 2);
$bleu = hexdec($B);
$tbl_couleur = array();
$tbl_couleur['R']=$rouge;
$tbl_couleur['V']=$vert;
$tbl_couleur['B']=$bleu;
return $tbl_couleur;
}
//conversion pixel -> millimètre en 72 dpi
function px2mm($px){
return $px*25.4/72;
}
function txtentities($html){
$trans = get_html_translation_table(HTML_ENTITIES);
$trans = array_flip($trans);
return strtr($html, $trans);
}
// Surcharge de la CLASSE FPDF :
class PDF extends FPDF
{
var $B;
var $I;
var $U;
var $HREF;
var $fontList;
var $issetfont;
var $issetcolor;
var $WIKIPAGE;
function PDF($orientation='P',$unit='mm',$format='A4')
{
//Appel au constructeur parent
$this->FPDF($orientation,$unit,$format);
//Initialisation
$this->B=0;
$this->I=0;
$this->U=0;
$this->HREF='';
$this->fontlist=array("arial","times","courier","helvetica","symbol");
$this->issetfont=false;
$this->issetcolor=false;
}
function setWikiPage($page) {
$this->WIKIPAGE=$page;
}
function getWikiPage() {
return $this->WIKIPAGE;
}
function WriteHTML($html)
{
//Parseur HTML
$html=strip_tags($html,"<b><u><i><a><img><p><br><strong><em><font><tr><blockquote>"); //supprime tous les tags sauf ceux reconnus
$html=str_replace("\n",' ',$html); //remplace retour à la ligne par un espace
$a=preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE); //éclate la chaîne avec les balises
foreach($a as $i=>$e)
{
if($i%2==0)
{
//Texte
if($this->HREF)
$this->PutLink($this->HREF,$e);
else
$this->Write(5,stripslashes(txtentities($e)));
}
else
{
//Balise
if($e{0}=='/')
$this->CloseTag(strtoupper(substr($e,1)));
else
{
//Extraction des attributs
$a2=explode(' ',$e);
$tag=strtoupper(array_shift($a2));
$attr=array();
foreach($a2 as $v)
if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
$attr[strtoupper($a3[1])]=$a3[2];
$this->OpenTag($tag,$attr);
}
}
}
}
function OpenTag($tag,$attr) //Balise ouvrante
{
switch($tag){
case 'STRONG':
$this->SetStyle('B',true);
break;
case 'EM':
$this->SetStyle('I',true);
break;
case 'B':
case 'I':
case 'U':
$this->SetStyle($tag,true);
break;
case 'A':
$this->HREF=$attr['HREF'];
break;
case 'IMG':
if(isset($attr['SRC']) and (isset($attr['WIDTH']) or isset($attr['HEIGHT']))) {
if(!isset($attr['WIDTH']))
$attr['WIDTH'] = 0;
if(!isset($attr['HEIGHT']))
$attr['HEIGHT'] = 0;
$this->Image($attr['SRC'], $this->GetX(), $this->GetY(), px2mm($attr['WIDTH']), px2mm($attr['HEIGHT']));
}
break;
case 'TR':
case 'BLOCKQUOTE':
case 'BR':
$this->Ln(5);
break;
case 'P':
$this->Ln(10);
break;
case 'FONT':
if (isset($attr['COLOR']) and $attr['COLOR']!='') {
$coul=hex2dec($attr['COLOR']);
$this->SetTextColor($coul['R'],$coul['V'],$coul['B']);
$this->issetcolor=true;
}
if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist)) {
$this->SetFont(strtolower($attr['FACE']));
$this->issetfont=true;
}
break;
}
}
function CloseTag($tag) //Balise fermante
{
if($tag=='STRONG')
$tag='B';
if($tag=='EM')
$tag='I';
if($tag=='B' or $tag=='I' or $tag=='U')
$this->SetStyle($tag,false);
if($tag=='A')
$this->HREF='';
if($tag=='FONT'){
if ($this->issetcolor==true) {
$this->SetTextColor(0);
}
if ($this->issetfont) {
$this->SetFont('arial');
$this->issetfont=false;
}
}
}
function SetStyle($tag,$enable)
{
//Modifie le style et sélectionne la police correspondante
$this->$tag+=($enable ? 1 : -1);
$style='';
foreach(array('B','I','U') as $s)
if($this->$s>0)
$style.=$s;
$this->SetFont('',$style);
}
function PutLink($URL,$txt)
{
//Place un hyperlien
$this->SetTextColor(0,0,255);
$this->SetStyle('U',true);
$this->Write(5,$txt,$URL);
$this->SetStyle('U',false);
$this->SetTextColor(0);
}
//En-tête
function Header()
{
//Positionnement à 0,1 cm du haut
$this->SetY(1);
//Police Arial italique 8
$this->SetFont('Arial','I',8);
//Numéro de page
$this->Cell(0,10,$this->getWikiPage().' - Page '.$this->PageNo().'/{nb}',0,0,'C');
$this->SetY(14);
}
//Pied de page
function Footer()
{
//Positionnement à 1,5 cm du bas
$this->SetY(-15);
//Police Arial italique 8
$this->SetFont('Arial','I',8);
//Numéro de page
$this->Cell(0,10,'http://www.thierrybazzanella.com - Page '.$this->PageNo().'/{nb}',0,0,'C');
}
//Chargement des données
function LoadData($file)
{
//Lecture des lignes du fichier
$lines=file($file);
$data=array();
foreach($lines as $line)
$data[]=explode(';',chop($line));
return $data;
}
//Tableau simple
function BasicTable($header,$data)
{
//En-tête
foreach($header as $col)
$this->Cell(40,7,$col,1);
$this->Ln();
//Données
foreach($data as $row)
{
foreach($row as $col)
$this->Cell(40,6,$col,1);
$this->Ln();
}
}
//Tableau amélioré
function ImprovedTable($header,$data)
{
//Largeurs des colonnes
$w=array(40,35,45,40);
//En-tête
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C');
$this->Ln();
//Données
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR');
$this->Cell($w[1],6,$row[1],'LR');
$this->Cell($w[2],6,number_format($row[2],0,',',' '),'LR',0,'R');
$this->Cell($w[3],6,number_format($row[3],0,',',' '),'LR',0,'R');
$this->Ln();
}
//Trait de terminaison
$this->Cell(array_sum($w),0,'','T');
}
//Tableau coloré
function FancyTable($header,$data)
{
//Couleurs, épaisseur du trait et police grasse
$this->SetFillColor(255,255,0);
$this->SetTextColor(255);
$this->SetDrawColor(128,0,0);
$this->SetLineWidth(.3);
$this->SetFont('','B');
//En-tête
$w=array(40,35,45,40);
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C',1);
$this->Ln();
//Restauration des couleurs et de la police
$this->SetFillColor(224,235,255);
$this->SetTextColor(0);
$this->SetFont('');
//Données
$fill=0;
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR',0,'L',$fill);
$this->Cell($w[1],6,$row[1],'LR',0,'L',$fill);
$this->Cell($w[2],6,number_format($row[2],0,',',' '),'LR',0,'R',$fill);
$this->Cell($w[3],6,number_format($row[3],0,',',' '),'LR',0,'R',$fill);
$this->Ln();
$fill=!$fill;
}
$this->Cell(array_sum($w),0,'','T');
}
}
/* (NL) does not work with wikka
//vérification de sécurité
if (!eregi("wakka.php", $_SERVER['PHP_SELF'])) {
die ("accès direct interdit");
}
*/
if ($this->HasAccess("read"))
{
/* (NL) we want pdf -eport - *.txt would be another handler
if (!$this->page)
{
return;
}
else
{
if ($_GET["save"]) {
header("Content-type: text/plain");
// display raw page
echo $this->page["body"];
$filename = "setup/doc/".$this->GetPageTag().".txt";
if (!$fp = fopen($filename, 'w')) {
echo $this->Format("//Impossible de créer le fichier ($filename)//");
exit;
}
if (!fwrite($fp, $this->page["body"])) {
echo $this->Format("//Impossible d'écrire dans le fichier ($filename)//");
exit;
}
fclose($fp);
}
if ($_GET["pdf"]) { */
//Instanciation de la classe dérivée
$pdf=new PDF();
$pdf->AliasNbPages();
$pdf->SetMargins(10, 10, 10);
$pdf->setWikiPage ($this->GetPageTag());
$pdf->AddPage();
$pdf->WriteHTML($this->Format($this->page["body"], "wakka"));
$pdf->Output();
//}
//}
}
else
{
return;
}
?>
3. Change the following two things in wikka.php
a) no computing time (near the bottom of the file):
change
to
b) we want no header and footer (a little bit above)
add after:
// raw page handler
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
//page to pdf - handler
elseif ($this->method == "pdf")
{
print($this->Method($this->method));
}
elseif ($this->method == "pdf")
{
print($this->Method($this->method));
}
4. Notice that the real work has only begun ;)
CategoryDevelopmentHandlers CategoryDevelopmentArchitecture