Skip to content

POI 렌더러 대신 LibreOffice+PDFBox로 교체 (좌표 틀어짐 수정) - #2

Open
CodeMakers-KR wants to merge 1 commit into
seccoding:masterfrom
CodeMakers-KR:libreoffice-based-conversion
Open

POI 렌더러 대신 LibreOffice+PDFBox로 교체 (좌표 틀어짐 수정)#2
CodeMakers-KR wants to merge 1 commit into
seccoding:masterfrom
CodeMakers-KR:libreoffice-based-conversion

Conversation

@CodeMakers-KR

Copy link
Copy Markdown
Contributor

문제

Converter.createImages()가 Apache POI의 자체 AWT 렌더러(Slide#draw)로 슬라이드를 직접 그리는데, 폰트 대체(변환 서버에 원본 폰트가 없을 때 AWT가 다른 폰트로 치환)와 그룹/회전 도형의 좌표 변환 계산 과정에서 오차가 누적되어 도형·이미지·화살표 위치가 조금씩 틀어집니다. README에도 이미 언급되어 있던 현상입니다.

변경 내용

렌더링 경로를 LibreOffice 기반으로 교체했습니다.

  1. soffice --headless --convert-to pdf로 pptx/ppt를 PDF로 변환 (SofficePdfConverter)
    • 동시 실행 시 프로필 잠금으로 멈추지 않도록, 매 변환마다 격리된 -env:UserInstallation 임시 프로필 사용
    • soffice 실행 경로는 -Dsoffice.path, SOFFICE_PATH 환경변수, OS별 기본 설치 경로 순으로 자동 탐색 (SofficeLocator) — Windows/Linux/macOS 모두 지원
  2. 생성된 PDF의 각 페이지를 PDFBox로 이미지 렌더링 (PdfPageRenderer)

LibreOffice는 실제 PowerPoint와 호환되는 레이아웃 엔진으로 렌더링하므로, POI 자체 렌더러보다 좌표가 훨씬 정확합니다.

호환성

  • Converter의 공개 API(convert(File, String, String), Result)는 그대로입니다. 해상도를 직접 지정하고 싶으면 convert(file, path, type, zoom) 오버로드를, soffice 경로를 직접 지정하고 싶으면 new Converter(destDir, sofficePath) 생성자를 사용하면 됩니다.
  • 더 이상 렌더링에 POI를 쓰지 않아 pom.xml의 POI 4종 의존성을 PDFBox 하나로 교체했고, 그에 따라 안 쓰이게 된 PPT.java/PPTX.java/SlideShowFactory.java를 제거했습니다.

필요 조건

변환이 실행되는 PC/서버에 LibreOffice가 설치되어 있어야 합니다. README에 설치 확인 방법과 경로 지정 방법을 추가했습니다.

테스트

  • mvn compile 성공 확인
  • ⚠️ 이 환경에는 LibreOffice가 없어서 실제 pptx → PDF → 이미지 변환까지의 end-to-end 실행은 확인하지 못했습니다. 머지 전에 LibreOffice가 설치된 환경에서 실제 변환 결과를 검증해 주세요.

Apache POI's own AWT-based slide renderer (Slide#draw) accumulates
positioning errors from font substitution and group/rotation transform
calculations, causing shapes, images, and arrows to drift from their
true positions. This is a known limitation of poi-4.0.1's rendering
engine rather than a bug in this project's own code.

Convert via LibreOffice headless (soffice --convert-to pdf) instead,
then rasterize each PDF page with PDFBox. LibreOffice uses a real
PowerPoint-compatible layout engine, so coordinates match the
original file far more closely.

- Add SofficeLocator: resolves the soffice binary across Windows/
  Linux/macOS, overridable via -Dsoffice.path or SOFFICE_PATH.
- Add SofficePdfConverter: runs soffice with an isolated user profile
  per conversion (avoids profile-lock hangs on concurrent runs).
- Add PdfPageRenderer: renders PDF pages to BufferedImage via PDFBox.
- Converter's public API (convert(...), Result) is unchanged; only
  the internals and the pom.xml dependency (poi -> pdfbox) changed.
- Remove PPT.java/PPTX.java/SlideShowFactory.java (POI SlideShow
  loading), now unused since rendering no longer goes through POI.

Requires LibreOffice installed on the machine running the conversion.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant