Overview
PDF파일을 읽어서 String을 추출해야할 일이 생겼다. Embedding도 그렇지만 PDF 파일을 읽어서 서버로 보내야되는? 일이 생긴것이다. PDF파일에 대한 상태, 위치에 대한 방법이 갈리며 그 이후 파일을 읽어서 추출한다.
Contents
- 사용방법
implementation 'org.apache.pdfbox:pdfbox'
//or
implementation 'org.apache.pdfbox:pdfbox:2.0.27'
BuildTool gradle 사용하여 가져온다.
또는 https://mvnrepository.com에서 원하는 Jar를 검색하여 bundle File을 다운받아 jar를 Build Path에 지정해준다.
너무 legacy 또는 기본,, 옛날등의 방식이지만,,,
- String 추출
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
private String extractTextFromPDF(File pdfFile) throws IOException {
try (PDDocument document = PDDocument.load(pdfFile)) {
PDFTextStripper stripper = new PDFTextStripper();
return stripper.getText(document);
}
}
File 타입의 파라미터로 넘겨주어 String을 추출한다. 또는 byte[],,
- PDF의 위치
PDF파일이 로컬에 또는 서버에 있을 수 있다.
- Resource
@Value("classpath:/doc/w1-2_02_docker_network.pdf") private Resource pdf; ... pdf.getFile()
Resource내에 디렉토리를 두어 해당 파일을 읽는다.\n 물론 resource buildPath설정되있겟지.
- File
File file = new File("절대경로");
절대경로로 파일을 읽어서 인자로 던진다.
- URL
String urlString = "https://docs.spring.io/spring-boot/docs/3.2.7/reference/pdf/spring-boot-reference.pdf"; URL url = new URL(urlString); // #1 window // c:\Users\09930255\AppData\Local\Temp 이하 경로에 해당 파일명, 확장자로 임시파일이 생성된다. Path tempFile = Files.createTempFile("spring-boot-reference", ".pdf"); try (InputStream in = url.openStream()) { Files.copy(in, tempFile, StandardCopyOption.REPLACE_EXISTING); } ... tempFile.toFile()
Files.createTempFile을 이용해 껍데기를 만들고 FileCopy로 복사하여 toFile()로 인자를 전달한다.
파일 시스템에 저장되므로 메모리 사용이 적기 때문에 큰파일을 처리하기에 적합하다.또는
String urlString = "https://docs.spring.io/spring-boot/docs/3.2.7/reference/pdf/spring-boot-reference.pdf"; try(InputStream in = new URL(urlString).openStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream()){ byte[] data = new byte[1024]; int nRead; while((nRead = in.read(data, 0, data.length)) != -1){ buffer.write(data, 0, nRead); } try (PDDocument document = PDDocument.load(buffer.toByteArray())) { PDFTextStripper stripper = new PDFTextStripper(); stripper.getText(document); // } }
byte[]로 전달하여 toByteArray()로 인자를 넘기면된다.
메모리에서 직접 처리하므로 속도에 장점이 있으나 큰파일을 처리하기엔 적합하지 않다.
- Resource
마치며
PDF 파일내 String을 추출하는 기능을 만들어보았다. 한가지 중요한점,, PDF파일내 텍스트가 긇어져야 읽어지는거 같다. Scan된 파일은 안되는듯,,, 뭐 지금도 문서보안 MarkAny쪽 암호화 걸린 파일을 읽다보니 Header doesn’t contain versioninfo 에러 메시지가 나오며, 디버그 해보니 Docuemnt 암호화가 바이너리 자체에 걸려있음을 확인하여 좌절하였다. 또 이 암호화된 문서를 풀려면 서버간 통신 및 정책,, 등등이 필요하겟찌…