여러 PDF 문서를 하나의 문서로 합치는 merge 기능을 PHP로 구현하는 방법입니다

개요

요즘은 회사 업무에서 파일을 전달할 때 PDF 문서를 활용하는 경우가 매우 많습니다.
그런데 이때 보내야 하는 PDF 문서가 여러개 일 경우 받는 쪽에서 각각의 파일을 일일이 열어봐야 해서 불편한 경우가 있습니다.
이럴때 여러 PDF 문서를 합쳐서 하나의 문서로 만들어 보내면 편리한 경우에 사용할 수 있는 PDF 문서 합치기 - merge 기능을 PHP로 구현하는 방법입니다.

라이브러리 설치

PDF 문서를 합쳐 주는 기능을 가진 라이브러리는 [ php pdf merger ]라고 검색해보면 여러가지 버전이 존재하는데 여기서는 Jurosh 라는 사람이 만든 것을 사용하겠습니다.
우선 composer 를 이용해서 라이브러리를 설치합니다.

~# composer require jurosh/pdf-merge

기본 사용법

아래 기본 사용법은 라이브러리 개발자가 GitHub에 올려둔 가이드에 있는 사용법입니다.

<?php

  require 'vendor/autoload.php';

  // and now we can use library
  $pdf = new \Jurosh\PDFMerge\PDFMerger;

  // add as many pdfs as you want
  $pdf->addPDF('path/to/source/file.pdf', 'all', 'vertical')
    ->addPDF('path/to/source/file1.pdf', 'all')
    ->addPDF('path/to/source/file2.pdf', 'all', 'horizontal');

  // call merge, output format `file`
  $pdf->merge('file', 'path/to/export/dir/file.pdf');
?>

응용 사용법

여기서는 파일 업로드 웹페이지를 통해 업로드 된 여러 파일들을 합쳐서 다운로드 받는 방식으로 구현해보겠습니다.

<? php

  require 'vendor/autoload.php';
  
  $pdf = new \Jurosh\PDFMerge\PDFMerger;


  $source_file_array = Array();
  $source_filename_array = Array();

  $source_file_array = $_FILES["pdf_file"];
  $source_filename_array = $source_file_array["name"];
  $upload_filename_array = $source_file_array["tmp_name"];

  $cnt_file = count($source_filename_array);

  for ($i = 0; $i < $cnt_file; $i++)
  {
    $pdf->addPDF($upload_filename_array[$i], 'all', 'vertical');    
  }

  $output_filename = $source_filename_array[0];

  $pdf->merge('download', $output_filename);
?>


업로드 된 파일명 배열에 저장

<? php

  $source_file_array = $_FILES["pdf_file"];
  $source_filename_array = $source_file_array["name"];
  $upload_filename_array = $source_file_array["tmp_name"];
?>


합칠 파일들 리스트에 추가

업로드 된 개수 만큼 파일들을 리스트에 추가합니다.
$pdf->addPDF의 파라미터에는 옵션으로 페이지와 문서방향이 들어갑니다.
$pdf->addPDF(파일경로, 페이지, 문서방향);

<? php

  $cnt_file = count($source_filename_array);
  for ($i = 0; $i < $cnt_file; $i++)
  {
    $pdf->addPDF($upload_filename_array[$i], 'all', 'vertical');    
  }

  /* 사용 예시
  $pdf->addPDF($upload_filename_array[$i], 'all', 'vertical');
  $pdf->addPDF($upload_filename_array[$i], '1,3,6', 'horizontal');
  $pdf->addPDF($upload_filename_array[$i], '12-16', 'vertical');
  */
?>


파일 합치기

합치기 옵션은 [download], [browser], [file], [string] 이렇게 4가지가 있습니다.
보통 로컬PC로 다운로드 받을 때는 [download], 서버에 저장할 때는 [file]를 선택하면 됩니다.

<? php

  $pdf->merge('download', $output_filename);
  $pdf->merge('browser', $output_filename);
  $pdf->merge('file', $output_filename);
  $pdf->merge('string', $output_filename);
?>


한글 깨짐 해결

PDF 파일을 합치면 문서 내의 텍스트는 한글이나 기타 UTF-8 문자들이 문제없이 잘나타납니다.
그런데 파일명은 UTF-8이 지원되지 않아 한글이 깨지는 현상이 나타납니다.

이를 해결하기 위해서는 여기서 사용한 pdf merger 소스 파일을 수정해야 합니다.
소스파일 위치는 ./vendor/jurosh/pdf-merge/src/Jurosh/PDFMerge/PDFMerger.php 입니다.

PDFMerger.php 파일에서 파일 합치기 함수 merge를 찾습니다.

<? php

  /* ./vendor/jurosh/pdf-merge/src/Jurosh/PDFMerge/PDFMerger.php */
  
  /*== 기존 ==*/ 
  public function merge($outputmode = 'browser', $outputpath = 'newfile.pdf') {

    /* ====*/
    /* 중략 */
    /* ====*/

    if ($mode == 'S') {
        return $fpdi->Output($outputpath, 'S');
    } else {
        if ($fpdi->Output($outputpath, $mode) == '') {
      return true;
        } else {
      throw new Exception("Error outputting PDF to '$outputmode'.");
      return false;
        }
    }
  }

  /*== 수정 ==*/ 
  public function merge($outputmode = 'browser', $outputpath = 'newfile.pdf') {

    /* ====*/
    /* 중략 */
    /* ====*/

    if ($mode == 'S') {
        return $fpdi->Output($outputpath, 'S', true);
    } else {
        if ($fpdi->Output($outputpath, $mode, true) == '') {
      return true;
        } else {
      throw new Exception("Error outputting PDF to '$outputmode'.");
      return false;
        }
    }
  }
?>


위에서 바뀐 부분은 Output 함수의 파라미터 하나입니다.

<? php
  // 기존
  $fpdi->Output($outputpath, 'S');
  $fpdi->Output($outputpath, $mode);
  
  // 수정
  $fpdi->Output($outputpath, 'S', true);
  $fpdi->Output($outputpath, $mode, true);
?>


왜 그런지 실제 Output 함수가 선언된 곳을 찾아가보겠습니다. 파일 위치는 ./vendor/setasign/fpdf/fpdf.php 입니다.
아래와 같이 Output 함수의 파라미터는 3개로 마지막이 UTF-8 여부를 설정하는 것이었습니다.
그러므로 마지막 파라미터를 true 로 설정만 해도 한글, UTF-8 문제가 해결됩니다.

<? php

  /* ./vendor/setasign/fpdf/fpdf.php */

  function Output($dest='', $name='', $isUTF8=false)
  {
	/* 중략 */
  }
?>

문서 속성 추가

또 하나의 문제가 제목, 작성자, 주제 등의 문서 속성 정보가 추가되지 않는다는 점입니다.
이 또한 파일 2개를 수정해야 합니다.

문서 합치기 파일 (ex: pdf_merge.php)

<? php
  // 문서 속성 정보를 추가합니다.
  $author = "써드아이시스템";
  $creator = "써드아이시스템";
  $title = "문서 제목";
  $subject = "문서 주제";
  $keywords = "키워드";

  // merge 함수에 문서 속성 옵션을 추가합니다.
  $pdf->merge('download', $output_filename, $author, $creator, $title, $subject, $keywords);
?>


merge 함수 정의 파일 (PDFMerger.php)

위치 : ./vendor/jurosh/pdf-merge/src/Jurosh/PDFMerge/PDFMerger.php

<? php

  /* ./vendor/jurosh/pdf-merge/src/Jurosh/PDFMerge/PDFMerger.php */

  // 파라미터 추가
  public function merge($outputmode = 'browser', $outputpath = 'newfile.pdf', $author = '3rdEYESYS', $creator = '3rdEYESYS', $title = 'title', $subject = 'subject', $keywords = 'keywords') {
    
    /* 중략 */

    // 속성 항목 설정
    $fpdi->SetAuthor($author, true);
    $fpdi->setCreator($creator, true);
    $fpdi->setTitle($title, true);
    $fpdi->setSubject($subject, true);
    $fpdi->setKeywords($keywords, true);
  }
?>

문서 속성을 저렇게 설정하면 되는 이유는 해당 함수가 정의된 곳을 찾아보면 알 수 있습니다.

파일 위치는 ./vendor/setasign/fpdf/fpdf.php 입니다.

<? php

  /* ./vendor/setasign/fpdf/fpdf.php */

  function SetTitle($title, $isUTF8=false)
  {
    // Title of document
    $this->metadata['Title'] = $isUTF8 ? $title : utf8_encode($title);
  }

  function SetAuthor($author, $isUTF8=false)
  {
    // Author of document
    $this->metadata['Author'] = $isUTF8 ? $author : utf8_encode($author);
  }

  function SetSubject($subject, $isUTF8=false)
  {
    // Subject of document
    $this->metadata['Subject'] = $isUTF8 ? $subject : utf8_encode($subject);
  }

  function SetKeywords($keywords, $isUTF8=false)
  {
    // Keywords of document
    $this->metadata['Keywords'] = $isUTF8 ? $keywords : utf8_encode($keywords);
  }

  function SetCreator($creator, $isUTF8=false)
  {
    // Creator of document
    $this->metadata['Creator'] = $isUTF8 ? $creator : utf8_encode($creator);
  }
?>

참고 URL

  1. PDF Merge GitHub Source and Download
Tags: php