
내 Excel이 신났어요
약 일주일 동안 PoI 라이브러리를 통해 Excel을 출력하는 작업을 해봤다.
내용만 기재하려다가 셀 생성/병합 등의 레이아웃 설정부터 Text의 폰트 스타일 등도 Java와 Spring-Poi 라이브러리로 다뤄봤다.
별문제 없이 요구사항을 다 구현하나 싶었던 때에, DB 내의 데이터들을 Query로 개행 압축시킨 뒤 내용을 기재한 Excel파일을 열어보니, 내 파일은 미친 듯이 신나있었다.

(계약서 내용 출처: https://blog.naver.com/aetangu/50164949002)
갖고 있는 계약서로 예를 들면 저런 식으로, 노래를 부르기엔 당황스러운 내용에 음표가 개행마다 붙어있었다
문제 추적하기
1. XSSFRichFont에 Font를 바꾸니까 나타났다
XSSFFont newFont = workbook.createFont();
newFont.setFontName("바탕체");
XSSFRichTextString richText = new XSSFRichTextString();
String newFontContent = "바탕체 적용 영역"
richText.append(newFontContent, newFont);
첫 번째로 파악한 건, 여러 번 테스트 끝에 '기본 글씨체'를 적용하면 해당 문제가 일어나지 않았고 위처럼 바탕체와 같이 다른 글씨체를 넣었을 때 음표가 나타나는 것을 알게 되었다.
'글씨체가 문제네'라고 넘기기엔 사유가 불충분하다
2. Query의 개행 압축 문제
'개행'.
아무리 생각해도 나의 개행 압축 처리에서 문제가 있을 것 같았다. 원본 데이터로는 없던 문제가 개행압축 후 일어났으니까.
기존의 개행처리 방식
OracleDB에 기입된 데이터를 보면 '어, 저기 개행 일어날 것 같은데?' 싶은 문장의 마지막마다 아래와 같은 문자가 표시되어 있다.

바로 \r(캐리지리턴, CR)과 \n(라인 피드, LF)에 대응하는 내 데이터베이스 관리 도구의 표기 방식이었다.
OracleDB에선 각각을 CHR(13), CHR(10)로 표현하는데, 나는 저 문자를 보고 \r인지 \n인지 구분할 방법은 없었다. (사실, '\r'만 존재한다면 표면적으로는 보이지도 않았다)
쿼리로 LIKE를 확인해 보면, 이 둘이 고루고루 조합되어 퍼져있는 듯했다.
따라서 나는 아래와 같이 쿼리로 개행을 압축시켰다.
REGEXP_REPLACE(
rept.RAW_CNTN, '(' || CHR(13) || CHR(10) || '|' || CHR(10) || '){2,}', CHAR(10))
)
2개 이상의 개행(\r\n, \n)이 존재하면 하나의 '\n'으로 치환해달라는 것이다.
여기서 나는, '\r(CHR(13)'가 존재할 경우를 빼먹었다.
3. 개선된 쿼리문
REGEXP_REPLACE(
rept.RAW_CNTN,
'(' || CHR(13) || CHR(10) || '|' || CHR(10) || '|' || CHR(13) || '){1,}', CHAR(10))
)
테스트 결과, 음표 문제는 없어졌다.
4. 글씨체를 바꾸면 나타나는 문제와 \r의 연관성
해결 방법을 미루어보아 나의 문제는 아래와 같이 정리된다.
Poi라이브러리를 통해 Excel내 폰트를 바꾼 채 '\r'이 기입되면 음표가 나타난다. ♪
Poi라이브러리, Excel의 폰트, 캐리지 리턴. 무슨 연관이 있는 걸까
Excel 폰트와 '\n'
사전적으로, CHR(13)와 CHR(10), 그리고 음표의 연관을 찾기 위해 정리하자면 다음과 같다.
명칭 | 아스키코드 | 유니코드 | |
\r | 캐리지 리턴(CR) | U+000D | 0x0D |
\n | 라인 피드(LF) | U+000A | 0x0A |
♪ | 음표 | U+266A |
뚜렷한 문제는 보이지 않는다.
그러나, 잘 알려진 원인으로 아래의 예가 대답해 준다.
'인코딩, 혹은 특정 글꼴의 가시적인 심볼로 표현을 당하고 있는 제어문자일 경우.'
즉, '\r'이 내가 바꾸려는 글꼴(바탕체)의 음표 심볼로 사용 중이었을 가능성이 높다.
근데 왜 누군가는 개행이 \r\n 혹은 \r이고, 누군가는 \n\n, \n인 걸까?
DB에는 여러 사용자가 사용한 데이터가 기입된다.
그런데 같은 화면에서 작성한 내용임에도 개행이 제각각으로 표기되고 있다.
이에 대해 가능성은 다음과 같이 정리할 수 있다.
1. Window, Unix, MacOS처럼 다양한 곳에서 데이터를 작성하고 있다
2. 다른 외부 파일에 작성된 내용을 복사 붙여넣기하여, 해당 개행 방식이 그대로 DB에 적재되었다.
사실, 찾아본바 현재 대부분의 대중적인 텍스트 에디터들은 다양한 운영체제에서 기입되는 개행을 통일시키고 있다. 그러나 현재 예상과 같이 개행의 일관성을 보장해 주지 않는 에디터를 사용한다면 서버 측에서 명시적으로 통일하는 로직이 요구될 수도 있다.