내 개념은-웹 사이트에 10 개의 pdf 파일이 있습니다. 사용자는 일부 pdf 파일을 선택한 다음 병합을 선택하여 선택한 페이지를 포함하는 단일 pdf 파일을 만들 수 있습니다. PHP로 어떻게 할 수 있습니까?
내 개념은-웹 사이트에 10 개의 pdf 파일이 있습니다. 사용자는 일부 pdf 파일을 선택한 다음 병합을 선택하여 선택한 페이지를 포함하는 단일 pdf 파일을 만들 수 있습니다. PHP로 어떻게 할 수 있습니까?
답변:
나는 전에 이것을했다. fpdf로 생성 한 pdf가 있었고 여기에 다양한 양의 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 merge 명령입니다.
$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)가 설치되어 있어야합니다.
나는 github.com 에서 PDFMerger 를 제안합니다.
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);
Chauhan의 대답의 단순화 된 버전
받아 들여지는 대답과 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 파일로 병합하여 외부 서비스에 제출하려고했습니다. 우리는 Christa 의 솔루션에 표시된 것처럼 FPDI 솔루션을 사용하고 있습니다.
그러나 우리가 사용하고있는 입력 PDF는 1.7보다 높은 버전 일 수 있습니다. 우리는 FPDI 상용 애드온을 평가하기로 결정했습니다. 그러나 사무실 복사기로 스캔 한 문서 중 일부에 잘못된 색인이 포함되어있어 상업용 FPDI 추가 기능이 중단되었습니다. 그래서 우리는 Chauhan 의 대답 과 같이 Ghostscript 솔루션 을 사용하기로 결정했습니다 .
그러나 출력 PDF 속성에 이상한 메타 데이터가 있습니다.
마지막으로 우리는 Ghostscript에 의해 PDF를 병합하고 다운 그레이드하기 위해 두 가지 솔루션을 결합하기로 결정했지만 메타 데이터는 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}";
추가 cat 출력을 확인하십시오 . 참조 PDFtk 예
myokyawhtun의 솔루션이 나에게 가장 적합했습니다 (PHP 5.4 사용)
그래도 오류가 발생합니다. 다음을 사용하여 해결했습니다.
fpdf_tpl.php의 269 행-함수 매개 변수를 다음과 같이 변경했습니다.
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) {
또한 fpdf.php의 898 행에서도 이와 동일한 변경을 수행했습니다.