-
Notifications
You must be signed in to change notification settings - Fork 271
/
PDFMerger.php
215 lines (191 loc) · 5.13 KB
/
PDFMerger.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
<?php
/**
* @file
* PDFMerger created in December 2009
* @author Jarrod Nettles <[email protected]>
*
* Updated by Vasiliy Zaytsev February 2016
*
* @version 2.0
* This version (comparing to 1.0) supports PDF 1.5 and PDF 1.6.
*
* Class for easily merging PDFs (or specific pages of PDFs) together into one.
* Output to a file, browser, download, or return as a string. Unfortunately,
* this class does not preserve many of the enhancements your original PDF
* might contain. It treats your PDF page as an image and then concatenates
* them all together.
*
* Note that your PDFs are merged in the order that you provide them using the
* addPDF function, same as the pages. If you put pages 12-14 before 1-5 then
* 12-15 will be placed first in the output.
*
* @uses tcpdf 6.2.12 by Nicola Asuni
* @link https://github.com/tecnickcom/TCPDF/tree/master official clone of lib
* @uses tcpdi_parser 1.0 by Paul Nicholls, patched by own TCPdiParserException
* @link https://github.com/pauln/tcpdi_parser source of tcpdi_parser.php
* @uses TCPDI 1.0 by Paul Nicholls with FPDF_TPL extension 1.2.3 by Setasign
* @link https://github.com/pauln/tcpdi tcpdi.php
*
* All of these packages are free and open source software, bundled with this
* class for ease of use. PDFMerger has all the limitations of the FPDI package
* - essentially, it cannot import dynamic content such as form fields, links
* or page annotations (anything not a part of the page content stream).
*/
namespace PDFMerger;
class PDFMerger
{
private $_files; //['form.pdf'] ["1,2,4, 5-19"]
private $_fpdi;
/**
* Merge PDFs.
* @return void
*/
public function __construct()
{
require_once('tcpdf/tcpdf.php');
require_once('tcpdf/tcpdi.php');
}
/**
* Add a PDF for inclusion in the merge with a valid file path. Pages should be formatted: 1,3,6, 12-16.
* @param $filepath
* @param $pages
* @return void
*/
public function addPDF($filepath, $pages = 'all')
{
if(file_exists($filepath))
{
if(strtolower($pages) != 'all')
{
$pages = $this->_rewritepages($pages);
}
$this->_files[] = array($filepath, $pages);
}
else
{
throw new \exception("Could not locate PDF on '$filepath'");
}
return $this;
}
/**
* Merges your provided PDFs and outputs to specified location.
* @param $outputmode
* @param $outputname
* @return PDF
*/
public function merge($outputmode = 'browser', $outputpath = 'newfile.pdf')
{
if(!isset($this->_files) || !is_array($this->_files)): throw new exception("No PDFs to merge."); endif;
$fpdi = new \TCPDI;
$fpdi->SetPrintHeader(false);
$fpdi->SetPrintFooter(false);
//merger operations
foreach($this->_files as $file)
{
$filename = $file[0];
$filepages = $file[1];
$count = $fpdi->setSourceFile($filename);
//add the pages
if($filepages == 'all')
{
for($i=1; $i<=$count; $i++)
{
$template = $fpdi->importPage($i);
$size = $fpdi->getTemplateSize($template);
$orientation = ($size['h'] > $size['w']) ? 'P' : 'L';
$fpdi->AddPage($orientation, array($size['w'], $size['h']));
$fpdi->useTemplate($template);
}
}
else
{
foreach($filepages as $page)
{
if(!$template = $fpdi->importPage($page)): throw new exception("Could not load page '$page' in PDF '$filename'. Check that the page exists."); endif;
$size = $fpdi->getTemplateSize($template);
$orientation = ($size['h'] > $size['w']) ? 'P' : 'L';
$fpdi->AddPage($orientation, array($size['w'], $size['h']));
$fpdi->useTemplate($template);
}
}
}
//output operations
$mode = $this->_switchmode($outputmode);
if($mode == 'S')
{
return $fpdi->Output($outputpath, 'S');
}
else if($mode == 'F')
{
$fpdi->Output($outputpath, $mode);
return true;
}
else
{
if($fpdi->Output($outputpath, $mode) == '')
{
return true;
}
else
{
throw new exception("Error outputting PDF to '$outputmode'.");
return false;
}
}
}
/**
* FPDI uses single characters for specifying the output location. Change our more descriptive string into proper format.
* @param $mode
* @return Character
*/
private function _switchmode($mode)
{
switch(strtolower($mode))
{
case 'download':
return 'D';
break;
case 'browser':
return 'I';
break;
case 'file':
return 'F';
break;
case 'string':
return 'S';
break;
default:
return 'I';
break;
}
}
/**
* Takes our provided pages in the form of 1,3,4,16-50 and creates an array of all pages
* @param $pages
* @return unknown_type
*/
private function _rewritepages($pages)
{
$pages = str_replace(' ', '', $pages);
$part = explode(',', $pages);
//parse hyphens
foreach($part as $i)
{
$ind = explode('-', $i);
if(count($ind) == 2)
{
$x = $ind[0]; //start page
$y = $ind[1]; //end page
if($x > $y): throw new exception("Starting page, '$x' is greater than ending page '$y'."); return false; endif;
//add middle pages
while($x <= $y): $newpages[] = (int) $x; $x++; endwhile;
}
else
{
$newpages[] = (int) $ind[0];
}
}
return $newpages;
}
}