Web development, scripts, source code and IT stuff
Concatenate PDF in PHP
As requirement for one project we need it to concatenate PDF files to have just one file as input.
First download in your work space TCPDF and FPDI
Class to concatenate pdf, pdfConcat.php:
require_once("tcpdf/tcpdf.php"); require_once("fpdi/fpdi.php"); class concat_pdf extends FPDI { var $files = array(); function setFiles($files) { $this->files = $files; } function concat() { foreach($this->files AS $file) { $pagecount = $this->setSourceFile($file); for ($i = 1; $i <= $pagecount; $i++) { $tplidx = $this->ImportPage($i); $s = $this->getTemplatesize($tplidx); $this->AddPage(’P', array($s['w'], $s['h'])); $this->useTemplate($tplidx); } } } }
Usage:
include_once("pdfConcat.php"); $pdf =& new concat_pdf(); $pdf->setFiles(array("doc.pdf","pauta.pdf", "4bp.pdf", "5bp.pdf")); $pdf->concat(); $pdf->Output("newpdf.pdf", "I");
After this I recommend to you to keep the file already merged in the server, then you will not need to generate it another time. To do this you can use $pdf->Output(“newpdf.pdf”, “F”); instead.
First off, AWESOME!
Second, is there a way to check for a returned error? I’m using this on a form and I want to have the user return to the previous page to try again if the creation fails.
Thanks,
Jim
Thanks!
ufff, I’m sorry now I really can’t remember but I’m certain there’s a way :S
First of all, great script!
Second, I have a question:
When I concatenate pdf files I get one horizontal line on each page just above my header.
It is situated 2 or 3 mm from the top end of the paper.
Is it a feature or a bug, and if the first, is there a way I could hide it?
Thanks in advance and keep writing such great scripts.
No there’s nothing in my code that is doing that.
Regards and thanks!
Hi again.
Here is what I have done step by step:
Download TCPDF – Version: 4.8.031
Download FPDF_TPL-1.1.4
Download FPDI_1.3.2
Extract the archives in one dir in my localhost workspace.
Move ‘fpdf_tpl.php’ file to ‘FPDI_1.3.2′ dir in order it could be loaded properly.
Create an index.php file.
Copy the upper ‘concat_pdf’ class in it.
Copy the upper ‘Usage’ code.
Use a standart PDF file in the setFiles() method, downloaded from the web, not previously generated with TCPDF.
(By the way, If I use a file, which is generated by TCPDF, the result is the same)
Launch the script.
The output is the same as the source PDF file with one difference – on each page there is a line 2 or 3 mm below the top edge of the page. It starts from the ‘left_margin’ position and ends to the ‘right_margin’ position.
If we use TCPDF to build a page, the same result may be achieved by the following code used in the Header() method:
$this->Line($this->left_margin, 3, $this->getPageWidth() – $this->right_margin, 3);
I think you should go to the support forums of TCPDF, no?
I solved the problem by using FPDF and ignoring the ‘fpdi2tcpdf_bridge.php’ script, which is loaded by default if an already included TCPDF class is found.
Actually, the original example uses it, instead of TCPDF.
http://www.setasign.de/products/pdf-php-solutions/fpdi/demos/concatenate-fake/
Now the annoying line above the header is gone.
Alternative way to get rid of the annoying horizontal line in the header if you want to keep using TCPDF
Just add these lines after: $pdf =& new concat_pdf();
// remove default header/footer
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
thanks ;)
Thanks from me too :)
And thanks from me. :D
This has been driving me nuts for weeks.
Many thanky from Germany
Hi, I was working out your example on our server where we need this sort of thing & I’m having some trouble. The TCPDF examples from the install works fine, so I’m pretty sure TCPDF is working right, and I don’t know how to test the FPDI. The problem is that the concatenation builds a blank document, always no matter what I try. I’ve tried with a minimum of just a couple of documents, but I always get the same output: blank. I’m just wondering if you have any suggestions I can try, as FPDI doesn’t seem to have good support options, and I’m pretty sure TCPDF is working OK. Maybe some way to test if FPDI is working or some suggestions on debugging steps? Thanks if you have any time to help, this would be a great replacement for pdftk!
Hi Ryan, right now nothing come across my mind, but you can check in the FPDI web for examples of work, this code worked for me anyway ;)
regards
$pagecount = $pdf->setSourceFile($filepath);
will return the number of pages in a document and will confirm that FPDI is working.
HTH
Thanks for the suggestion adrianbj, that is returning the right number of pages (each PDF we want to concatenate is 1 page). The PDF that appears for either download or on the server has the right number of pages (one per file), it’s just that each page is completely blank. I setup a test environment to try to work on this located here: http://ryan.neoterichovercraft.com/pdf/ (the execution file is pdf.php)
I changed it to just try to concatenate the same file twice to see if that would help, but no go, here’s the PHP that I’m using:
files = $files;
}
function concat() {
foreach($this->files AS $file) {
$pagecount = $this->setSourceFile($file);
for ($i = 1; $i ImportPage($i);
$s = $this->getTemplatesize($tplidx);
$this->AddPage(‘P’, array($s['w'], $s['h']));
$this->useTemplate($tplidx);
}
}
}
}
$pdf =& new concat_pdf();
$pdf->setFiles(array(’1.pdf’, ’1.pdf’));
//$pdf->setFiles(array(’1.pdf’, ’2.pdf’, ’3.pdf’));
$pdf->concat();
$pdf->Output(“output.pdf”, “I”);
?>
I’m sure I’m missing obvious, but it’s eluding me.
Ryan,
A couple of thoughts:
Do you have FPDF_TPL on your server?
The basic free version of FPDI only supports PDF format up to 1.4 (v5): http://www.setasign.de/products/pdf-php-solutions/fpdi/downloads/ You can pay for a version that support more recent PDF file formats, or just make sure to save all the PDFs in this older version.
Something else to look at – are you pointing to the full server path of the PDFs (ie /var/www/pdfs/1.pdf etc)?
Also, is PHP logging any errors?
Thanks for the assistance, yes FPDF_TPL is on the server here: http://ryan.neoterichovercraft.com/pdf/fpdi/fpdf_tpl.php (my basic understanding is that tcpdf.php is included first, within my PHP, providing the TCPDF class, followed by fpdi.php which includes fpdf_tpl.php providing FPDF_TPL as an extension of FPDF that itself is defined as an extension of TCPDF via the file fpdi2tcpdf_bridge.php). Originally, I had not downloaded fpdf_tpl.php and the system generated an error.
I downloaded FPDF_TPL along with FPDI and inserted fpdf_tpl.php into the fpdi/ directory. I think that’s the right location? As a workaround, I did try to use FPDF directly based on a comment above (not using the bridge), but the result kept giving me an error the “D”/”I”/”F” was not a valid output parameter.
The PDFs would be newer PDFs generated by BullZip (1.5 I believe), so I used BullZip and converted the PDFs (originally Word documents) to 1.4 and then to 1.3, neither of those options seemed to make a difference, the final output was still blank.
No, the PDFs are located in the same directory as the testing structure I setup, so the array is just array(“1.pdf”, “1.pdf”). I can try full path to see if it makes a difference, and there are no errors on from the script itself, I’m not sure if PHP logs anywhere via syslog.
Hello,
this works just fine for small files. Is there any possibility to fix the memory-problem merging many files to one large one?
–> Fatal error: Allowed memory size of 33554432 bytes exhausted
I cannot adjust the memory_limit on the server. There should be a possibility to merge the file not completely in memory.
I tried the memory optimation add-on ( http://www.fpdf.de/downloads/addons/76/ ) but I think it cannot be used for concat_pdf. If anyone knows better – just let me know.
Thanks for the “remove horizontal line” tip. Works like a charm, and very fast.
Hej!
I have a problem implementing this function for concatenation. The problem is that first i am generating a pdf on the fly with data from a html form. And then, after the pdf has been generated, i am trying to add another pdf, which is already created. The problem is, that i do not know how to call the generated on the fly pdf, as it is not stored anywhere…
I hope somebody can help me with this issue…
Thanks in advance
just store it, do the concatenation and then erase it ;)
first, thank you very much for your response!!!!!
Yes, i was thinking about that, but i do not know how exactly to make this, the problem is that i am a bit new to the php programming…
Can you give me some tips on how to do this store-erase thing….
Thanks a lot!!!!!!
Hi, i’m italian, i’m sorry for my english.
First thank’s for the code, but i have a question.
I’m using this system to concatenate different pdf. The problem is the layout.
I have a pdf in Landscape layout and the system create a normal pdf (concatenate) so part of my file is invisible.
Is there a way to solve my problem?
Thank’s so much
Hello you can change that in the class $this->AddPage(’P’, array($s['w'], $s['h']));
Instead of P=portrait put L= landspcape ;)
Hello. I am using your script exactly as it is here. Your code works fine with “perfect” PDF-s(like those created with tcpdf library) but when trying to concatenate pdf-s from different sources(like scanned invoices) I get TCPDF ERROR: Unable to find pointer to xref table .Have you met this error?
I have the same experience with NZoli. I also get TCPDF ERROR. Why is it showing? Do you have now a solution?
David M.
Blog Writer
deskchairmat.net .
@David M
I solved the TCPDF ERROR thing in a simple way :) I had to switch to JAVA instead of PHP and use an API called iText or something like that. If you got a lot of time AND skill you could do the following in PHP: research the PDF file format and create the xref table by yourself(as I understand it’s a matrix of pointer offsets which tell the reader from where to take the info. PDF is a kind of RAR internally, very confusing)
Hello everybody, the script looks great, but I have a problem which is not documented here :
This is what the script says when I try to concat :
TCPDF ERROR: File is encrypted!
Do you have an idea of what do I have to do ?
Greetings
hello,
that’s because that PDF uses a password as far as I know.
regards
Hello
First of all thanx for the code for the concatenation of multiple files and its working fine but as per my requirement instead of passing the pdf files how can I merge the content of pdf files that are stored in the database to a single pdf file ?
Is there a way to solve my above problem using your same code ?
Greetings
Nice solution, thnx a lot!
But a little correction needed:
use
if ($s['w'] AddPage('P', array($s['w'], $s['h']));
} else {
$this -> AddPage('L', array($s['w'], $s['h']));
}
instead simple ‘P’ if pages in files have a different orientation.
Oops, sorry parser eat a code, I’ll try PRE tag
I mean
if ($s['w'] < $s['h']){...Hi, I write from Italy sorry for my bad English.
I have an application written in PHP using FPDF libraries FPDI + to concatenate PDF files but for some files I get the error ‘FPDF error: Unable to find xref table’, I saw in the files of the two libraries and found the function called function error ($ msg) that contains the following statement “die (‘ FPDF error: ‘. $ msg);” that causes the error message: how can I change this statement so that my application in case of ‘FPDF error: Unable to find xref table’ go ahead without crashing? I am new to php … Thanks to all
Take a look at:
http://www.vankouteren.eu/blog/2009/07/fpdf-error-unable-to-find-xref-table/
Also maybe try to ensure that the PDF is v1.4 or less
Nice work.
I am trying to use this, resolve some minor issues and copied the code as it is with test pdf files in the same location as other php files. However, I am getting the error – “TCPDF ERROR : Cannot open xxxxx.pdf”. I don’t think this has to do with permision to read the pdf file, but then I am not sure why the problem is there. The code crashes while at this line:
$pagecount = $this->setSourceFile($file);
I also get the warning call_user_func_array(): First argument is expected to be a valid callback, ‘concat_pdf::TCPDF::SetFont’
[...] you to the commenter, lexey111, on http://neo22s.com/concatenate-pdf-in-php/ for this solution. Share this:TwitterFacebookLike this:LikeBe the first to like this post. [...]