What is PDF and as it{he} can be fastened to web-applications means PHP

Presently the format of documents PDF gets the big popularity. He has been developed by company Adobe Systems Incorporated. As it is specified in the documentation, THE ADOBE PORTABLE DOCUMENT FORMAT (PDF) - a transferable{tolerable} format of documents, is "native" for software products of family Adobe Acrobat. Their purpose - to enable the user it is easy to exchange electronic documents and to look through them irrespective of that Wednesday in which these documents have been created. PDF leans{bases} on the graphic model, allowing to display a picture and the text without dependence from the devices established by a computer and the sanction. At documents of this format there are such objects, as hyperlinks and summaries that does{makes} their interactive.


On the other hand, web-applications frequently require display of dynamically made documents, such as reports, prajslisty, bills and many other things. It allows to personalize the application and to make his  more powerful on the functionalities. Besides PDF, there are also other decisions, but this format can be named one of the most successful as PDF the document without loss of formatting can be deduced{removed} on the printer or to convert in HTML or the text.


PHP as one of the most powerful and popular modern means of development of web-applications, copes with a problem  of generation PDF of documents "hurriedly". For this purpose additional tools are developed some. I shall not undertake to list them everything, but I shall name one of the most known - library PDFLib, ClibPDF and PHP class FPDF.


FPDF - only PHP


Named in the previous chapter{head} PDFLib and ClibPDF demand additional adjustment PHP while class FPDF is pure{clean} PHP a code and it is easily connected to scripts by include command () and others similar. To download a class and to familiarize with the detailed documentation it is possible on a site www.fpdf.org. Additional (at times deciding{solving}) argument for the benefit of this decision it is possible to consider{examine} it  besplatnost` for use as in personal, and commercial objectives. The citation from the license agreement:


" FPDF is Freeware (it is stated at the beginning of the source file). There is no usage restriction. You may embed it freely in your application (commercial or not), with or without modification ".


It is authorized to alter an initial code of a class also. Any restrictions.

The decision of a problem with cyrillics


At creation of Russian-speaking documents by means of foreign software products (libraries, applications and other) often there is a problem of correct display of cyrillic fonts. Not any foreign product correctly works (and even at all does not work) with cyrillics. Fortunately, class FPDF does not belong to their number and is easily adjusted to job with Russian.


If to be exact a class to adjust practically it is not necessary. The problem can arise with files of cyrillic fonts. I shall make a reservation, that I spent testing of a class on wintel to a platform (however, all resulted code worked and on commercial *nix a hosting). In windows one of the most basic formats of fonts (alongside with PostScript) is TTF (True Type Font). But one format of files is necessary for correct job of our scripts - AFM (a file of the metrics of a font) and more. As it is considered, AFM files are delivered together with TTF. In OS I AFM have not found out files.


Here to us to the aid there come useful utilities, in particular - ttf2pt1. One of problems{tasks} of the given utility - to generate a metric file for True Type or PFB. In other words, appears an opportunity to take from a directory/fonts (OS Windows) any .TTF a file of a font with support of cyrillics and to receive for him  the metrics by means of our magic utility. To download the utility it is possible on the following links: http://ttf2pt1.sourceforge.net and http: // fpdf.org/fr/dl.php? id=22 (for Windows).


After the utility is downloaded, she  is necessary for starting from the command line (in windows Start-up> To execute cmd command). The format of a call of the utility for the purpose necessary to us looks as follows:



ttf2pt1-A font.ttf font


For example, if you have put the downloaded copy ttf2pt1 directly on disk C:, and a file of a font times.ttf in C:CyrFonts it will be necessary for you to start the following command:



c:ttf2pt1-A c:CyrFontstimes.ttf times


Where c:ttf2pt1 - a call of the program,-A - the key specifying necessity to generate file AFM, c:CyrFontstimes.ttf is an address of file True Type of a font and, at last, times is a name of the future metric file. So, AFM the file is ready.


The following step is generation of a file of the description of a font. This file will have expansion familiar to us - PHP. Together with class FPDF the useful script for the decision of this problem  is delivered. It{he} can be found in a directory font/makefont/a class. To use it  it is simple. For this purpose we shall create RNR a file (we shall say, mf.php) and in him we shall specify:



<? php

require (' font/makefont/makefont.php ');

MakeFont (' times.ttf ', times.afm ', ' cp1251);

?>


Using require, we connect the necessary script. Understandably, that for this purpose near to our file there should be a folder font, containing in itself makefont/makefont.php. And function MakeFont () already is specific and by definition has the following format:



MakeFont (string fontfile, string afmfile [, string enc [, array patch [, string type]]])


Where fontfile - a way to TTF or PFB to a file, afmfile - a way to AFM to a file, enc - a name of the used coding (by default it cp1252), patch - opcional`noe change of the coding and type - type of a font (by default True Type). For a choice of the coding it is possible to use the following list:


* cp1250 (Central Europe)

* cp1251 (Cyrillic)

* cp1252 (Western Europe)

* cp1253 (Greek)

* cp1257 (Baltic)

* ISO-8859-1 (Western Europe)

* ISO-8859-2 (Central Europe)

* ISO-8859-4 (Baltic)

* ISO-8859-4 (Cyrillic)

* ISO-8859-7 (Greek)

* ISO-8859-15 (Western Europe)

* ISO-8859-16 (Central Europe)

* KOI8-R (Cyrillic)


The coding defines{determines} communication{connection} between a code (from 0 up to 255) and a symbol. For a choice of the cyrillic coding in Windows use cp1251. Usually codings with a prefix cp are used in Windows while Linux systems use ISO.


The script made by us mf.php is necessary for opening in a browser. He will prepare for our needs a necessary file with expansion php. So, what we have? We now have complete set from three files of a font - times.ttf, times.afm and times.php. Important two of them (times.ttf and times.php) to put in the necessary place. This place is the directory font, taking place in a folder of a class. However, you are free to specify a place of a directory which will store{keep} fonts. For this purpose it is necessary to define{determine} constant FPDF_FONTPATH ordinary for PHP in the way:


define (' FPDF_FONTPATH ',' font / ');


Now our system is ready to development web applications with dynamic generation Russian-speaking PDF the document.

We begin job


For evident illjustrirovanija opportunities FPDF of a class we shall try to create the real document - the price-list of the firm engaged in wholesale - retail of alcoholic drinks. The brief technical project the following:


* In a cap of the document there should be data: a trade mark, the name of firm, heading of the document;

* In a body of the document the data on the commodity positions, including the name of the goods, a retail price and a wholesale price should be resulted;


At once we shall break our job into three stages. The first stage - a conclusion of the static information. For simplicity of an example we shall attribute{relate} everything to the static information, except for the data on commodity positions. At the second stage we shall pay attention to a tabulared conclusion of commodity positions in a body of the document. We shall specify, that in this clause{article} we shall consider loading the data from file CSV where a separator is the semicolon. I have stopped on this decision for one reason - such file easily to receive from a format xls and, simultaneously, with it  it is easy to work from RNR applications in other purposes (for example to organize a conclusion in HTML). At the third stage we shall consider delivery PDF of a file to the end user.


Let's start practical acquaintance to class FPDF. For the beginning we shall create a file price.php which will carry out conclusion PDF of the document directly in a browser (other ways we we shall consider in chapter{head} 6). Near to this working file we shall put downloaded earlier fpdf.php (a file of a class) and a folder font with the files of cyrillic fonts enclosed in it{her} (see the previous chapter{head}). Now in a file price.php we shall connect class FPDF and we shall establish a way to a folder of fonts.



<? php

    define (' FPDF_FONTPATH ',' font / ');

    require (' fpdf.php ');

?>


It is necessary to specify, what a tag <? php should stand on the very first line of a file as in a consequence we shall independently send headings (headers), and the empty line, the text or marking HTML in the beginning of a file can prevent us.


For a conclusion of the static information (a trade mark, the name of firm, the name of the document) we shall use the following methods of class FPDF: cell () and image (). The method cell () deduces a cell (a rectangular figure) with opcional`noj installation of border, color zalivkoj and line of the text. A format of recording of a method the following:


Cell (float w [, float h [, string txt [, mixed border [, int ln [, string align [, int fill [, mixed link]]]]]]])


The method image () is responsible for a conclusion of graphic representation JPG or PNG. A format of a call of a method the following:


Image (string file, float x, float y, float w [, float h [, string type [, mixed link]]])


Certainly, before using methods of a class, all over again it is necessary to create a copy of this class. We shall lead our file to to the following kind:



<? php

define (' FPDF_FONTPATH ',' font / ');

require (' fpdf.php ');


// We shall create a copy of a class

$price = new FPDF ();

$price-> Open ();

?>


After creation of a copy of a class it will be necessary for us to specify used fonts. As cyrillic Times New Roman (considered in the previous chapter{head}) is not in class FPDF a font established by default, all over again it is necessary "to show" it  to a script. We shall make it by means of method AddFont ().



<? php

define (' FPDF_FONTPATH ',' font / ');

require (' fpdf.php ');


// We shall create a copy of a class

$price = new FPDF ();

$price-> Open ();

// We connect a cyrillic font

$price-> AddFont ('TimesNewRomanPSMT', ",'times.php ');

$price-> SetFont (' TimesNewRomanPSMT ', '', 12);

?>


The first argument of function we specify the name of a font. It{he} can be seen in generated RNR a file (value of a variable $name). The second argument - formatting of the text (B - Bold, I - Italic and mixed BI or IB). If argument empty, a font usual. For use B and I it is necessary to connect also corresponding types of fonts (for Times New Roman it there can be files timesI.ttf and timesBd.ttf). The third argument - RNR a file of the description (we have generated it  in the previous chapter{head}). Now the font can be applied in the given document. For use on page we shall establish his  size method SetFont (). This method can be caused some times in one script, while addition AddFont () is done{made} once for each font. A format of recording SetFont () the following:


SetFont (string family [, string style [, float size]])


At last it is possible to generate contents of page. At this stage we shall collide{face} increase in quantity{amount} of a code and consequently, in order to prevent mess, we shall expand class FPDF with the methods. Certainly, there is no necessity to make change in itself FPDF a class. We shall write the price.class.php, inherited from FPDF.


Listing 1



<? php

class Price extends FPDF {

    function PrintTitle ($title, $image, $company) {

        // We deduce{remove} a trade mark

        $this-> Image ($image, 6,6,40,20);

        // We establish{install} a font for the name of the company

        $this-> SetFont (' TimesNewRomanPSMT ', '', 20);

        // We deduce{remove} the name of the company

        $this-> Cell (210,4, $company, 0,0, ' C ');

        // We pass to the next line

        $this-> Ln ();

        // We pass to the next line

        $this-> Ln ();

        // We do{make} a space from a left edge (drawing a transparent cell)

        $this-> Cell (37);

        // We establish{install} color zalivki the following cells (R, G, B)

        $this-> SetFillColor (209,204,244);

        // We establish{install} a font for the name of the document

        $this-> SetFont (' TimesNewRomanPSMT ', '', 12);

        // We deduce{remove} the name of the document

        $this-> Cell (150,8, $title, 0,0, ' C ', 1);

        // We pass to the next line

        $this-> Ln ();

}

}   

?>


Listing 2



<? php

define (' FPDF_FONTPATH ',' font / ');

require (' fpdf.php ');

require (' price.class.php ');


$price = new Price ();

$price-> Open ();

$price-> AddFont ('TimesNewRomanPSMT', ",'times.php ');

// We add a page in the document

$price-> AddPage ();

// We deduce{remove} heading, using the method written by us in a file of a class // price.class.php

$price-> PrintTitle (' the Price-list ',' logo.jpg ',' the Company " ALKO SELL " ');

// We deduce{remove} the document in a browser

$price-> Output ();

?>


In this file we have collided{faced} several methods of class FPDF. It is necessary to notice, that the document all over again is created in the buffer and only then, by a call of method Output (), is deduced in a browser. Therefore the general circuit of job with the document following: we create in the buffer the document method Open (), then for job we add in this document a page method AddPage (), we form contents of the document various methods such as Cell () and, at last, we deduce{remove} it  from the buffer in a browser. If at you it is established adobe acrobat versions not below 5.0 at start price.php in a browser the document price.pdf (in Internet Explorer should open) or the document doc.pdf for uploading (in Opera) will be generated.


This document yet does not represent practical value, however on his  example we have disassembled bases of a conclusion of the static data in the document .PDF.

We connect a source of the data


Let's pass to the most interesting - to dynamic formation of contents of the document. By this opportunity for RNR the developer class FPDF also is valuable. I already spoke above, that here we shall consider a variant of data acquisition from CSV a file.


As it is specified in our short technical project, the body of the price-list should consist of three columns: the name of the goods, a retail price and a wholesale price. Accordingly, we shall prepare also a file of the data of the following kind:


Beer "Baltic"; 15.00; 13.45

Beer "Obolon`"; 14.00; 12.30

Vodka "Nemiroff", 1 l.; 100.00; 89.45


Let's save it  as price.csv. Certainly, in the real price-list of commodity positions and columns will be more.


Are possible{probable} as divisions on groups of the goods (for example "beer", "vodka", "wine"), but in the given concrete example we shall try to consider the simplified version (the quantity{amount} of recordings can be increased).


Before us there is a necessity to obtain the data dynamically and to present them as the ordinary table to three columns, with headings of columns (stolbcov). Before creation of a copy of object Price we shall add initialization of a file of headings (we shall collect all headings in a file):



$header = array ("Name", "JJ«º¡"., "Wholesale".);


Further we need to expand even more class Price (inherited from class FPDF) with methods LoadData () and ImprovedTable (). The first method should take the data from CSV a file in a file $data, and the second method is useful for otrisovki tables with the data from this file. We shall consider method LoadData () for class Price.



function LoadData ($file) {

    // We obtain the data in a file of lines

    $lines=file ($file);

    $data=array ();

    // We divide{share} stolbcy every line on a semicolon.

    foreach ($lines as $line)

    $data [] =explode ('; ', chop ($line));

    // We return a file with the data

    return $data;

}


Let's insert this code into a file of a class price.class.php. Now we shall pass to consideration of method ImprovedTable ().


His  code:



function ImprovedTable ($header, $data) {

    // We specify width stolbcov

    $w=array (100,40,40);

     

    // We deduce{remove} headings stolbcov

    for ($i=0; $i <count ($header); $i ++)

    $this-> Cell ($w [$i], 7, $header [$i], 1,0, ' C ');

    $this-> Ln ();

     

    // We deduce{remove} the data

    // All over again we shall establish a font for the data

    $this-> SetFont (' TimesNewRomanPSMT ', '', 8);

    foreach ($data as $row)

    {

/*Pervyj Parameter Cell () - the width of a column specified earlier in a file $w, the second parameter - height of a column, the third parameter - the line for a conclusion, LRBT - means a portrayal of borders from different directions cells (Left, Right, Bottom, Top). It is possible to specify also alignment in a cell by a right edge (' R ') */

             

        // We draw a cell of the name of the goods

        $this-> Cell ($w [0], 6, $row [0], ' LRBT ');

             

        // We draw a cell of a retail price

        $this-> Cell ($w [1], 6, number_format ($row [1]), ' LRBT ', 0, ' R ');

             

        // We draw a cell of a wholesale price

        $this-> Cell ($w [2], 6, number_format ($row [2]), ' LRBT ', 0, ' R ');

             

        // We pass to the next line

        $this-> Ln ();

}

    // Closure line

    $this-> Cell (array_sum ($w), 0, ",'T ');

}


Let's insert also this method into a code of class Price. Now, when we have acquired with two new methods, we shall try them to apply. We shall change a code of our main file (listing 3).


It is possible to look at intermediate result. It practically everything that we wanted to reach{achieve}.


Let's add only a small detail - numbers{rooms} of pages with the instruction{indication} of their general{common} number in the bottom part of each page. In fact our source of the data can consist not of three recordings, and, for example, from hundred.


For this purpose it is necessary to organize a conclusion of "cellar" (footer) on each page. With this purpose we shall write method Footer () our class Price. It is necessary to note, that methods Footer () and Header () are beforehand registered in class FPDF and caused automatically at performance of method AddPage () and Close ().


By default they empty, but they can be defined{determined} in the inherited classes, thus neither Footer () nor Header () it is not required to cause obviously from the application. We shall add in class Price () the following code of a method:



function Footer () {

    // Positioning in 1.5 sm from the bottom border

    $this-> SetY (-15);

    // TimesNewRomanPSMT italic 8

    $this-> SetFont (' TimesNewRomanPSMT ', '', 8);

    // Number{Room} of page

    $this-> Cell (0,10, ' Page '. $ this-> PageNo (). ' / {nb} ', 0,0, ' C ');

}


Listing 3



<? php

define (' FPDF_FONTPATH ',' font / ');

require (' fpdf.php ');

require (' price.class.php ');


$header = array (" the Name of the goods ", " Rozn. The price ", " Wholesale. The price ");

$price=new Price ();

$price-> Open ();


// We shall receive data file from a file in $data

$data = $price-> LoadData ("price.csv");

$price-> AddFont ('TimesNewRomanPSMT', ",'times.php ');

$price-> AddPage ();

$price-> SetFont (' TimesNewRomanPSMT ', '', 12);

$price-> PrintTitle (' the Price-list ',' logo.jpg ',' the Company " ALKO SELL " ');


// We shall draw the table. Arguments of a method are a file of names

// stolbcov and data file from a file price.csv

$price-> ImprovedTable ($header, $data);

$price-> Output ();

?>


Now this method will be automatically executed by a call of method AddPage (). Last stroke is necessary for correct job - a call from a file of the application (price.php) a method $price-> AliasNbPages () before $price-> AddPage ().


AliasNbPages ([string alias])


At a spelling of method Footer () we used also PageNo (), a method returning number{room} of the current page and parameter {nb} which will be by default replaced with figure of total of pages in the current document. The document is ready, and before us there is a necessity of his  conclusion for a browser.

Conclusion in a browser


On idea, exists only two variants of a conclusion of the document in a browser - opening (if it is established adobe acrobat) and uploading without direct opening. In class FPDF a conclusion of the document in a browser method Output () operates. In our example we used this method without additional arguments. However the documentation to FPDF results the following format of his  recording:


Output ([string file [, boolean download]])


The method is intended for preservation PDF of the document in a local file or for a direct conclusion in a browser (if PDF browser of files is established).


The argument file means a name of a file. If those is absent, attempt to open the document in a window of a browser is made. If the argument file is determined, the argument download specifies, that the file should be saved on the server (value false) or at the user (at installation true dialogue " is deduced To save as ").


Accordingly, it is possible to allocate three variants of a spelling of method Output () for our document. The first - Output () - tries to open the document in a window of a browser. The second variant of a spelling will deduce{remove} at the user a dialog box " To save as " and will suggest to download the document on his  disk - Output("AlkoPrice.pdf ", true). And, at last, the third variant will simply save the document on the local server for a script - Output ("AlkoPrice.pdf", false) or simply Output("AlkoPrice.pdf ") as by default the attribute download always matters false.


It is necessary to consider a compression of the received file separately. Attempt of it  "to press down" will be by default made by means Zlib. This expansion (extension) should be established in system. If installation has not been made, the document will turn out not compressed, and will weigh it is little bit more.


For the beginning, perhaps, all!