필기노트

JAVA Apache POI로 Word 치환하기 본문

JAVA

JAVA Apache POI로 Word 치환하기

우퐁코기 2022. 12. 24. 09:41
반응형

1. Apache POI란?

Microsoft 형식 파일에 액세스하기 위한 Java API

 

2 HWPF vs XWPF

2.1 HWPF : 이 API는 이전 Word 6 및 Word 95 파일 형식, .doc문서용입니다.

2.2 XWPF : 이 API는 Word 2007 .docx문서용입니다.

 

3. gradle dependencies 추가

implementation 'org.apache.poi:poi-ooxml:5.2.2'

 

4. 고객정보를 이용해 워드파일로 만들어야 할 경우가 있다.

5. 미리 만들어 둔 템플릿에 고객정보들을 치환시키고 업데이트된 내용으로 새 파일을 만든다.

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UpdateDocument {

    public static void main(String[] args) throws IOException {

        Map<String, String> map = new HashMap<>();
        map.put("${JUMIN}", "123456-1234567");
        map.put("${NAME}", "홍길동");
        map.put("${ADDR}", "대한민국 서울");
        map.put("${PHONE}", "010-1111-2222");

        UpdateDocument obj = new UpdateDocument();

        obj.updateDocument(
                "/Users/gim-uhong/template2.docx",
                "/Users/gim-uhong/output2.docx",
                map);
    }

    private void updateDocument(String input, String output, Map<String, String> map)
            throws IOException {

        try (XWPFDocument doc = new XWPFDocument(
                Files.newInputStream(Paths.get(input)))
        ) {

            List<XWPFParagraph> xwpfParagraphList = doc.getParagraphs(); // 단락들을 반환

            for(String key : map.keySet()) {

                //Iterate over paragraph list and check for the replaceable text in each paragraph
                for (XWPFParagraph xwpfParagraph : xwpfParagraphList) { // 한 단락씩 꺼낸다
                    for (XWPFRun xwpfRun : xwpfParagraph.getRuns()) { // 꺼낸 단락의 단어별로 꺼낸다
                        String docText = xwpfRun.getText(0);
                        //replacement and setting position
                        docText = docText.replace(key, map.get(key));
                        xwpfRun.setText(docText, 0);
                    }
                }
            }


            // save the docs
            try (FileOutputStream out = new FileOutputStream(output)) {
                doc.write(out);
            }

        }

    }
}
XWPFDocument doc = new XWPFDocument

XWPFDocument: .docx 워드 파일을 생성/편집할 수 있는 높은 수준의 API를 제공

 

Files.newInputStream(Paths.get(input)))

Files, Paths: 레거시 File 클래스를 대체

 

 

6. 결과 - 전화번호가 치환되지 않았다... 왜?

워드파일로 템플릿을 만들어 줄 때 ${PHONE}을 입력하다가 '백스페이스' 키로 지웠다가 다시 입력하면 "${PHONE}"을 찾지 못한다.

그래서 해당 문제의 워드파일을 xml문서로 변경해서 보면 "${PHONE}"으로 저장되어 있어야 하는데  

"${</w:t></w:r><w:r><w:rPr><w:rFonts w:hint="eastAsia"/></w:rPr><w:t>PHONE}"

이렇게 "${"와 "PHONE}" 사이에 '백스페이스' 키를 입력하면서 생긴 흔적이 남으면서 온전한 "${PHONE}"을 찾지 못했다.

즉 치환해야 할 문자를 수정해야 할 땐 '백스페이스' 키보다 '실행취소' 키로 수정을 하던가 쭉 입력해야 한다.

 

7. 결과2

 


REFERENCE

https://mkyong.com/java/java-read-and-write-microsoft-word-with-apache-poi

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=3yong2ya&logNo=220959910391

https://www.baeldung.com/java-path-vs-file

반응형
Comments