HWP, HWPX 파일과 Markdown 간의 변환을 지원하는 Java 라이브러리입니다.
- Markdown → HWP: Markdown 문서를 한글(HWP) 파일로 변환
- Markdown → HWPX: Markdown 문서를 한글 XML(HWPX) 파일로 변환
- HWP → Markdown: HWP 파일을 Markdown으로 변환
- HWPX → Markdown: HWPX 파일을 Markdown으로 변환
- HWP ↔ HWPX: HWP와 HWPX 간 상호 변환
- 제목 (H1 ~ H6)
- 단락
- 굵은 글씨, 기울임 글씨
- 코드 블록 (언어 지정 가능)
- 인라인 코드
- 테이블 (GFM 테이블)
- 순서 있는 목록, 순서 없는 목록
- 인용문
- 링크, 이미지
- 수평선
- Java 21 이상
- Maven 3.6 이상
Repository 설정:
<repositories> <repository> <id>manty-releases</id> <url>https://nexus.manty.co.kr/repository/maven-releases/</url> </repository> </repositories>
Dependency 추가:
<dependency> <groupId>kr.co.manty</groupId> <artifactId>hwp-markdown-converter</artifactId> <version>0.9.0</version> </dependency>
가장 간단한 방법으로 문서를 변환할 수 있습니다.
import kr.co.manty.docconv.api.DocConv; import kr.co.manty.docconv.core.converter.ConversionResult; import java.nio.file.Path; String markdown = """ # 제목 이것은 **굵은 글씨**와 *기울임 글씨* 예제입니다. ## 목록 - 항목 1 - 항목 2 - 항목 3 ## 테이블 | 이름 | 나이 | |------|------| | 홍길동 | 30 | | 김철수 | 25 | """; ConversionResult<Path> result = DocConv.markdownToHwp(markdown, Path.of("output.hwp")); if (result.isSuccess()) { System.out.println("변환 성공: " + result.getResult()); } else { System.out.println("변환 실패: " + result.getErrorMessage()); }
ConversionResult<Path> result = DocConv.markdownToHwpx(markdown, Path.of("output.hwpx"));
ConversionResult<String> result = DocConv.hwpToMarkdown(Path.of("input.hwp")); if (result.isSuccess()) { String markdown = result.getResult(); System.out.println(markdown); }
ConversionResult<String> result = DocConv.hwpxToMarkdown(Path.of("input.hwpx"));
ConversionResult<Path> result = DocConv.hwpToHwpx( Path.of("input.hwp"), Path.of("output.hwpx") );
ConversionResult<Path> result = DocConv.hwpxToHwp( Path.of("input.hwpx"), Path.of("output.hwp") );
// Markdown 파일 → HWP 파일 ConversionResult<Path> result = DocConv.markdownFileToHwp( Path.of("input.md"), Path.of("output.hwp") ); // HWP 파일 → Markdown 파일 ConversionResult<Path> result = DocConv.hwpToMarkdownFile( Path.of("input.hwp"), Path.of("output.md") );
더 세밀한 제어가 필요한 경우 Builder API를 사용합니다.
import kr.co.manty.docconv.api.DocConv; // Markdown → HWP (Builder 사용) ConversionResult<Path> result = DocConv.convert() .fromMarkdown(markdown) .tableMergeStrategy(DocConv.TableMergeStrategy.FLATTEN) .toHwp(Path.of("output.hwp")); // HWP → Markdown (Builder 사용) ConversionResult<String> result = DocConv.convert() .fromHwp(Path.of("input.hwp")) .toMarkdown(); // HWPX → HWP (Builder 사용) ConversionResult<Path> result = DocConv.convert() .fromHwpx(Path.of("input.hwpx")) .toHwp(Path.of("output.hwp")); // InputStream에서 읽기 try (InputStream is = new FileInputStream("input.hwp")) { ConversionResult<String> result = DocConv.convert() .fromHwp(is) .toMarkdown(); }
저수준 API로 더 세밀한 제어가 필요한 경우:
import kr.co.manty.hwp.renderer.MarkdownHwpRenderer; import java.nio.file.Paths; MarkdownHwpRenderer renderer = new MarkdownHwpRenderer(); renderer.renderMarkdown("# Hello World\n\nThis is **bold** text."); renderer.saveToFile(Paths.get("output.hwp"));
모든 변환 메서드는 ConversionResult<T>를 반환합니다.
ConversionResult<Path> result = DocConv.markdownToHwp(markdown, outputPath); // 성공 여부 확인 if (result.isSuccess()) { Path outputFile = result.getResult(); System.out.println("파일 생성됨: " + outputFile); // 경고 확인 if (result.hasWarnings()) { System.out.println("경고:"); result.getWarnings().forEach(warning -> System.out.println(" - " + warning.type() + ": " + warning.message()) ); } } else { System.out.println("오류: " + result.getErrorMessage()); } // 또는 예외를 던지도록 처리 Path outputFile = result.getResultOrThrow(); // 실패 시 ConversionException 발생
| 메서드 | 설명 |
|---|---|
markdownToHwp(String, Path) |
Markdown 문자열을 HWP 파일로 변환 |
markdownToHwpx(String, Path) |
Markdown 문자열을 HWPX 파일로 변환 |
markdownFileToHwp(Path, Path) |
Markdown 파일을 HWP 파일로 변환 |
hwpToMarkdown(Path) |
HWP 파일을 Markdown 문자열로 변환 |
hwpToMarkdownFile(Path, Path) |
HWP 파일을 Markdown 파일로 변환 |
hwpxToMarkdown(Path) |
HWPX 파일을 Markdown 문자열로 변환 |
hwpxToMarkdownFile(Path, Path) |
HWPX 파일을 Markdown 파일로 변환 |
hwpToHwpx(Path, Path) |
HWP 파일을 HWPX 파일로 변환 |
hwpxToHwp(Path, Path) |
HWPX 파일을 HWP 파일로 변환 |
convert() |
Builder API 시작 |
| 메서드 | 설명 |
|---|---|
fromMarkdown(String) |
Markdown 문자열을 소스로 설정 |
fromMarkdownFile(Path) |
Markdown 파일을 소스로 설정 |
fromHwp(Path) |
HWP 파일을 소스로 설정 |
fromHwp(InputStream) |
HWP 스트림을 소스로 설정 |
fromHwpx(Path) |
HWPX 파일을 소스로 설정 |
tableMergeStrategy(TableMergeStrategy) |
테이블 병합 전략 설정 |
toMarkdown() |
Markdown 문자열로 변환 |
toMarkdownFile(Path) |
Markdown 파일로 변환 |
toHwp(Path) |
HWP 파일로 변환 |
toHwpx(Path) |
HWPX 파일로 변환 |
HWP/HWPX에서 Markdown으로 변환 시 병합된 셀을 처리하는 전략:
| 값 | 설명 |
|---|---|
FLATTEN |
병합된 셀의 내용을 첫 번째 셀에만 표시, 나머지는 빈 셀 |
REPEAT |
병합된 모든 셀에 동일한 내용 반복 |
SKIP |
병합된 셀이 있는 테이블 건너뛰기 |
- 이미지: 현재 이미지는 텍스트 링크로 변환됩니다 (이미지 임베딩 미지원)
- 복잡한 서식: 일부 복잡한 HWP 서식은 Markdown 변환 시 손실될 수 있습니다
- 셀 병합: Markdown은 셀 병합을 지원하지 않으므로 평탄화됩니다
- hwplib - HWP 바이너리 형식 처리
- hwpxlib - HWPX XML 형식 처리
- commonmark-java - Markdown 파싱
MIT License
버그 리포트, 기능 요청, Pull Request를 환영합니다.