Моя концепція полягає в тому, що на веб-сайті є 10 файлів у форматі PDF. Користувач може вибрати деякі PDF-файли, а потім вибрати злиття, щоб створити єдиний PDF-файл, що містить вибрані сторінки. Як я можу це зробити за допомогою php?
Моя концепція полягає в тому, що на веб-сайті є 10 файлів у форматі PDF. Користувач може вибрати деякі PDF-файли, а потім вибрати злиття, щоб створити єдиний PDF-файл, що містить вибрані сторінки. Як я можу це зробити за допомогою php?
Відповіді:
Я робив це раніше. У мене був файл PDF, який я створив за допомогою fpdf, і мені потрібно було додати до нього змінну кількість PDF-файлів.
Отже, я вже створив об’єкт і сторінку fpdf (http://www.fpdf.org/) І використовував fpdi для імпорту файлів (http://www.setasign.de/products/pdf-php-solutions/ fpdi /) FDPI додається розширенням класу PDF:
class PDF extends FPDI
{
}
$pdffile = "Filename.pdf";
$pagecount = $pdf->setSourceFile($pdffile);
for($i=0; $i<$pagecount; $i++){
$pdf->AddPage();
$tplidx = $pdf->importPage($i+1, '/MediaBox');
$pdf->useTemplate($tplidx, 10, 10, 200);
}
Це в основному робить кожен pdf зображенням, щоб помістити в інший pdf. Це надзвичайно добре працювало для того, що мені потрібно.
Нижче наведена команда злиття php PDF.
$fileArray= array("name1.pdf","name2.pdf","name3.pdf","name4.pdf");
$datadir = "save_path/";
$outputName = $datadir."merged.pdf";
$cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=$outputName ";
//Add each pdf file to the end of the command
foreach($fileArray as $file) {
$cmd .= $file." ";
}
$result = shell_exec($cmd);
Я забув посилання з того місця, де його знайшов, але він працює нормально.
Примітка: Щоб це працювало, у вас повинен бути встановлений gs (на Linux і, мабуть, Mac), або Ghostscript (на Windows).
я пропоную PDFMerger з github.com , так просто, як ::
include 'PDFMerger.php';
$pdf = new PDFMerger;
$pdf->addPDF('samplepdfs/one.pdf', '1, 3, 4')
->addPDF('samplepdfs/two.pdf', '1-2')
->addPDF('samplepdfs/three.pdf', 'all')
->merge('file', 'samplepdfs/TEST2.pdf'); // REPLACE 'file' WITH 'browser', 'download', 'string', or 'file' for output options
$cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=".$new." ".implode(" ", $files);
shell_exec($cmd);
Спрощена версія відповіді Чаухана
Здається, і прийнята відповідь, і навіть домашня сторінка FDPI дають невдалі або неповні приклади. Ось мій, який працює і простий у реалізації. Як очікується, для цього потрібні бібліотеки fpdf та fpdi:
require('fpdf.php');
require('fpdi.php');
$files = ['doc1.pdf', 'doc2.pdf', 'doc3.pdf'];
$pdf = new FPDI();
// iterate over array of files and merge
foreach ($files as $file) {
$pageCount = $pdf->setSourceFile($file);
for ($i = 0; $i < $pageCount; $i++) {
$tpl = $pdf->importPage($i + 1, '/MediaBox');
$pdf->addPage();
$pdf->useTemplate($tpl);
}
}
// output the pdf as a file (http://www.fpdf.org/en/doc/output.htm)
$pdf->Output('F','merged.pdf');
У мене була подібна проблема в моєму програмному забезпеченні. Ми хотіли об’єднати кілька файлів PDF в один файл PDF і надіслати його зовнішній службі. Ми використовували рішення FPDI, як показано в рішенні Крісти .
Однак вхідні PDF-файли, які ми використовували, можуть бути у версії вище 1.7. Ми вирішили оцінити комерційну надбудову FPDI. Однак виявилося, що деякі документи, відскановані нашим офісним копіром, мають неправильно сформовані індекси, що призвело до збою комерційного надбудови FPDI. Тож ми вирішили використати рішення Ghostscript, як у відповіді Чаухана .
Але тоді ми отримали дивні метадані у вихідних властивостях PDF.
Нарешті, ми вирішили об’єднати два рішення для об’єднання та зниження версії PDF за допомогою Ghostscript, але метадані встановлюються FPDI. Ми поки не знаємо, як це могло б працювати з деякими розширеними відформатованими PDF-файлами, але для сканування, яке ми використовуємо, воно працює чудово. Ось наш уривок класу:
class MergedPDF extends \FPDI
{
private $documentsPaths = array();
public function Render()
{
$outputFileName = tempnam(sys_get_temp_dir(), 'merged');
// merge files and save resulting file as PDF version 1.4 for FPDI compatibility
$cmd = "/usr/bin/gs -q -dNOPAUSE -dBATCH -dCompatibilityLevel=1.4 -sDEVICE=pdfwrite -sOutputFile=$outputFileName";
foreach ($this->getDocumentsPaths() as $pdfpath) {
$cmd .= " $pdfpath ";
}
$result = shell_exec($cmd);
$this->SetCreator('Your Software Name');
$this->setPrintHeader(false);
$numPages = $this->setSourceFile($outputFileName);
for ($i = 1; $i <= $numPages; $i++) {
$tplIdx = $this->importPage($i);
$this->AddPage();
$this->useTemplate($tplIdx);
}
unlink($outputFileName);
$content = $this->Output(null, 'S');
return $content;
}
public function getDocumentsPaths()
{
return $this->documentsPaths;
}
public function setDocumentsPaths($documentsPaths)
{
$this->documentsPaths = $documentsPaths;
}
public function addDocumentPath($documentPath)
{
$this->documentsPaths[] = $documentPath;
}
}
Використання цього класу є таким:
$pdf = new MergedPDF();
$pdf->setTitle($pdfTitle);
$pdf->addDocumentPath($absolutePath1);
$pdf->addDocumentPath($absolutePath2);
$pdf->addDocumentPath($absolutePath3);
$tempFileName = tempnam(sys_get_temp_dir(), 'merged');
$content = $pdf->Render();
file_put_contents($tempFileName, $content);
$cmd = "\"C:\\Program Files\\gs\\gs9.20\\bin\\gswin64c.exe\" -q -dNOPAUSE -dBATCH -dCompatibilityLevel=1.4 -sDEVICE=pdfwrite -sOutputFile=[....your parameters...]" ;
Я спробував подібну проблему і працює чудово, спробуйте. Він може обробляти різні орієнтації між PDF-файлами.
// array to hold list of PDF files to be merged
$files = array("a.pdf", "b.pdf", "c.pdf");
$pageCount = 0;
// initiate FPDI
$pdf = new FPDI();
// iterate through the files
foreach ($files AS $file) {
// get the page count
$pageCount = $pdf->setSourceFile($file);
// iterate through all pages
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
// import a page
$templateId = $pdf->importPage($pageNo);
// get the size of the imported page
$size = $pdf->getTemplateSize($templateId);
// create a page (landscape or portrait depending on the imported page size)
if ($size['w'] > $size['h']) {
$pdf->AddPage('L', array($size['w'], $size['h']));
} else {
$pdf->AddPage('P', array($size['w'], $size['h']));
}
// use the imported page
$pdf->useTemplate($templateId);
$pdf->SetFont('Helvetica');
$pdf->SetXY(5, 5);
$pdf->Write(8, 'Generated by FPDI');
}
}
Undefined index: w
Я створив абстракційний шар над FPDI (може вмістити інші двигуни). Я опублікував його як пакет Symfony2 залежно від бібліотеки та як саму бібліотеку.
використання:
public function handlePdfChanges(Document $document, array $formRawData)
{
$oldPath = $document->getUploadRootDir($this->kernel) . $document->getOldPath();
$newTmpPath = $document->getFile()->getRealPath();
switch ($formRawData['insertOptions']['insertPosition']) {
case PdfInsertType::POSITION_BEGINNING:
// prepend
$newPdf = $this->pdfManager->insert($oldPath, $newTmpPath);
break;
case PdfInsertType::POSITION_END:
// Append
$newPdf = $this->pdfManager->append($oldPath, $newTmpPath);
break;
case PdfInsertType::POSITION_PAGE:
// insert at page n: PdfA={p1; p2; p3}, PdfB={pA; pB; pC}
// insert(PdfA, PdfB, 2) will render {p1; pA; pB; pC; p2; p3}
$newPdf = $this->pdfManager->insert(
$oldPath, $newTmpPath, $formRawData['insertOptions']['pageNumber']
);
break;
case PdfInsertType::POSITION_REPLACE:
// does nothing. overrides old file.
return;
break;
}
$pageCount = $newPdf->getPageCount();
$newPdf->renderFile($mergedPdfPath = "$newTmpPath.merged");
$document->setFile(new File($mergedPdfPath, true));
return $pageCount;
}
Це працювало для мене у Windows
додайте у свій php-код наступне, де $ file1 - це місце розташування та ім'я першого PDF-файлу, $ file2 - розташування та ім'я другого, а $ newfile - розташування та ім'я цільового файлу
$file1 = ' c:\\\www\\\folder1\\\folder2\\\file1.pdf';
$file2 = ' c:\\\www\\\folder1\\\folder2\\\file2.pdf';
$file3 = ' c:\\\www\\\folder1\\\folder2\\\file3.pdf';
$command = 'cmd /c C:\\\pdftk\\\bin\\\pdftk.exe '.$file1.$file2.$newfile;
$result = exec($command);
$command = "cmd /c C:\\pdftk\\bin\\pdftk.exe {$file1} {$file2} cat output {$new}";
Зверніть увагу на додатковий вихід кішки . Див. Приклади PDFtk
Рішення myokyawhtun найкраще мені підходило (за допомогою PHP 5.4)
Ви все одно отримаєте повідомлення про помилку - я вирішив, використовуючи таке:
Рядок 269 fpdf_tpl.php - змінено параметри функції на:
function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='',$align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0) {
Цю саму зміну я також вніс у рядок 898 з fpdf.php