오늘은 PDF 파일에 있는 내용을 가져와서 브라우저에 텍스트로 뿌려 주는 것을 공부해 보겠습니다.
저희가 만든 웹앱에 식당 메뉴를 제공하려고 하는데요.
식당을 운영하는 회사에서 메뉴를 PDF 형식으로 그 회사 웹에서 제공하고 있어요.
그런데 회사사람들 대부분이 블랙베리 폰을 사용하고 있어서 구형 BB 에서는 PDF 형식을 보여주기가 힘들거든요.
그 회사랑 따로 EDI 시스템 개발해서 데이터 주고 받고 하는 번거로운일을 하지 않고 그냥 그 회사에서 제공하는 메뉴에서 우리가 필요한 데이터만 추출해서 서비스하는 방법을 고민중입니다.
일단 인터넷 서핑을 통해서 PDF 를 TEXT 로 바꿔주는 소스코드는 구했습니다.
이 소스코드를 한번 분석해 보고 어떤 방법이 있을지 없을지 알아보려구요.
메뉴는 이렇게 생긴 PDF 파일인데요.
왼쪽의 내용들은 필요 없고 오른쪽에 있는 요일별 메뉴들만 뽑고 싶거든요.
원본 pdf 파일과 이 내용을 text 로 바꿔주는 PHP 파일은 여기 있습니다.
|
이걸 돌리면 결과가 아래와 같이 나옵니다.
흠 다 텍스트로 나오긴 나왔는데 이거 가지고는 따로 메뉴만 추출해 내기 쉽지 않네요.
이렇게 모두 한줄로 나오는게 아니라 라인별로 따로 출력이 돼면 좀 더 낫지 않을까요?
일단 pdf2text.php 를 분석해 봐야 겠습니다.
pdf2text.php 파일 안에는 9개의 함수가 있습니다.
이 pdf2text.php 를 실행하면 제일 먼저 어떤게 실행될까요?
함수들은 어디서 호출을 해 줘야 실행되니까 다 그냥 건너뛰겠고...
$result = pdf2text ('original.pdf'); 가 제일 먼저 실행되겠죠?
이건 pdf2text($filename) 함수를 call 하는 겁니다. 거기서 처리된 값을 $result 변수에 담고 그 내용을 echo 함수로 브라우저에 뿌려주는게 이 프로그램이 하는일의 전부 다 입니다.
이제 그 중간의 처리 과정을 자세히 공부해 보겠습니다.
우선 pdf2text($filename) 함수는 아래와 같습니다.
function pdf2text($filename) {
// file_get_contents return the contents of a file as a string
$infile = @file_get_contents($filename, FILE_BINARY);
if (empty($infile))
return "";
$transformations = array();
$texts = array();
preg_match_all("#obj(.*)endobj#ismU", $infile, $objects);
$objects = @$objects[1];
for ($i = 0; $i < count($objects); $i++) {
$currentObject = $objects[$i];
//echo $currentObject . "<p> end";
if (preg_match("#stream(.*)endstream#ismU", $currentObject, $stream)) {
$stream = ltrim($stream[1]);
//echo $stream . "<p> end";
$options = getObjectOptions($currentObject);
if (!(empty($options["Length1"]) && empty($options["Type"]) && empty($options["Subtype"])))
continue;
$data = getDecodedStream($stream, $options);
if (strlen($data)) {
if (preg_match_all("#BT(.*)ET#ismU", $data, $textContainers)) {
$textContainers = @$textContainers[1];
getDirtyTexts($texts, $textContainers);
} else
getCharTransformations($transformations, $data);
}
}
}
return getTextUsingTransformations($texts, $transformations);
}
맨 처음으로는 해당 파일의 내용을 받아옵니다. 이것은 바이너리 형식이라서 사람이 읽을 수 있는건 아닙니다. ($infile = @file_get_contents($filename, FILE_BINARY);)
그 내용을 출력해 보면 아래와 같이 나옵니다.
이걸 보면 헤더정보만 사람이 읽을 수 있는 텍스트죠?
이 문서는 PDF 1.5 버전이라는 것을 알 수 있습니다.
그리고 이 헤더정보는 endobj 부분에서 끝나는 겁니다.
나머지는 사람이 읽을 수 없는 바이너리 형식입니다.
그 다음 if 문에서는 해당 파일이 비어있는건지 봅니다. 비어있으면 나머지 로직을 실행할 필요가 없겠죠? 괜히 시간만 낭비니까 그 cost 를 줄이기 위해 비어있으면 그냥 return 을 해 버립니다.
파일이 empty 가 아니면 그 다음을 실행할 텐데요.
(참고로 if 문의 {} 가 없습니다. 그 안에 내용이 단 1줄이면 {} 없이 사용할 수 있습니다.
그러면 바로 그 다음줄까지만 if 절 안에 포함돼 있는 겁니다.)
그 다음은 $transformations 라는 배열과 $texts 라는 배열을 만들어 줍니다.
오늘은 여기까지만 하고 다음에 계속 분석해 보겠습니다.
지금 토요일 아침 7시 40분인데요.
가족이랑 어디 가기로 해서 지금 나가봐야 되네요.
여행 다녀와서 계속 공부할텐데 그 내용도 여기 정리해 놓을께요.
'etc. > PHP' 카테고리의 다른 글
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 7 (0) | 2013.01.16 |
---|---|
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 6 (0) | 2013.01.16 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 5 (0) | 2013.01.15 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 4 (0) | 2013.01.08 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 3 (0) | 2013.01.08 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 2 (0) | 2013.01.08 |
PHP와 XSL 로 XML 변환하기 (0) | 2012.12.21 |
PHP로 XML , JSON 다루기 (2) | 2012.08.24 |
-PHP - Proxy 통해 원격 파일 존재 여부 파악하기 (0) | 2012.07.19 |