최근 회사에서 프로젝트를 진행하는 중 PDF 파일내에 있는 텍스트 및 이미지를 추출하여 화면에 표출할 일이 생겼다.
어떻게 할지 검색을 해보다가 pdfbox라는 자바 라이브러리를 사용하였고 화면에 표출하는데 성공하였다. 진행한 과정을 해당 포스팅에 기술 하였다.
pdfbox 다운로드
https://pdfbox.apache.org/download.html
해당 링크에서 pdfbox.2.0.27.jar 및 fontbox.2.0.27 jar파일을 다운로드 받았다. 원래는 pdfbox 파일만 받으려고 했지만 fontbox가 없어서 classNotFoundError가 발생하는 경우가 있었다. fontbox를 추가하니 에러가 사라졌다.
프로젝트 폴더 내 libs 폴더에 다운받은 jar파일은 넣은 후에 build.gradle 파일에 다음과 같이 추가해줬다.
일단 pdf파일을 불러와야 한다. 파일 객체를 생성 후 pdf파일을 불러온 뒤 document 변수에 저장한다.
PDDocument document
String fileName = pdf파일 이름
File file = new File(fileName)
document = PDDocument.load(file);
파일에서 텍스트를 추출하기 위해 다음과 같은 코드로 진행하였다. setStartPage, setEndPage 메소드로 텍스트를 추출할 페이지를 지정할 수 있다. 추출한 텍스트는 summaryText라는 변수에 저장하였다.
PDFTextStripperByArea stripper = new PDFTextStripperByArea();
stripper.setSortByPosition(true);
PDFTextStripper Tstripper = new PDFTextStripper()
Tstripper.setStartPage(2)
Tstripper.setEndPage(2)
String summaryText = Tstripper.getText(document)
이미지를 추출하기 위해 arrayList를 한개 만들었다.
getPage 메소드를 통해 이미지를 추출할 페이지를 지정할 수 있다. 해당 예시에서는 3번째 페이지에 있는 이미지들을 가져왔다.
List<PDImageXObject> imageList = new ArrayList<>()
PDPageTree pages = document.getPages()
PDPage page = pages.get(2)
Iterable<COSName> objectNames = page.getResources().getXObjectNames()
pdf파일에서 추출한 이미지를 화면에 표출하기 위하여 가져온 이미지들을 바이트 코드로 바꿔줬다. 그 다음 바이트 코드를 문자열로 저장하여 배열에 추가했다.
for (COSName imageObjectName : objectNames) {
if (page.getResources().isImageXObject(imageObjectName)) {
PDImageXObject imageInfo = (PDImageXObject) page.getResources().getXObject(imageObjectName)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(imageInfo.image, "png", baos);
byte[] bytesimage = baos.toByteArray();
String imageStr = Base64.getEncoder().encodeToString(bytesimage)
imageList.add(imageStr)
}
}
다음과 같은 방법으로 바이트 코드 문자열 형태의 이미지를 화면에 표출하였다.
<img class="plot-image" style="width: 45%; height: 45%" src="data:image/gif;base64,바이트코드" alt="MME plot">