I use TCPDF (see http://www.tcpdf.org/) for this: its pretty capable and not too painful to get setup. I will say that depending on your data source you may have some issues. In my case my data is sourced from a SOAP interface to my accounting system and use CodeIgniter for my app, and I can do this:
$address = $extraclient->get_company_address();
// generate the PDF invoice
$this->load->library('pdfinvoice');
// set document information
$this->pdfinvoice->SetSubject("Invoice " . $data_invoice['code_invoice']);
// add a page
$this->pdfinvoice->AddPage();
$this->pdfinvoice->StartPageOffset();
// write the client's details out
$width = $this->pdfinvoice->GetPageWidth()/2;
$margins = $this->pdfinvoice->getMargins();
$this->pdfinvoice->SetFont('times', 'b', $this->pdfinvoice->bigFont );
$this->_row($width, array("From:", "To:"));
$this->pdfinvoice->SetFont('times', 'i', $this->pdfinvoice->smallFont );
$this->_row($width, array("MY NAME", $customer['name_contact']));
$this->_row($width, array($address['phone'], $customer['name_customer']));
$this->_row($width, array($address['street'], $customer['address1_street']));
$this->_row($width, array($address['city']. ", ".$address['state']." ".$address['zipcode'],
$customer['address1_city']. ", ".$customer['address1_state']." ".$customer['address1_zip
The full code is quite frankly too long to insert here, but you should get the idea, and you get fairly precise layout control.