pdfMake는 다 좋은데 폰트 커스텀하는 거랑 이미지 넣는 게 힘들다. (개인 생각..) 특히 `pdfMake 한글깨짐` 관련 글을 찾아보면 grunt를 깐다, gulp을 쓴다 등등 여러 글들이 있는데 솔직히 나한텐 다 안 통했다 ㅠㅠ
근데 공식문서에서 보면 추가 라이브러리 설치 없이 그냥 커스텀 폰트 적용할 수 있더라??? 역시 사람은 공식문서를 읽어야 함.
근데... 공식문서가 참 이해 안되게 적혀있었다 ㅠㅠ https://pdfmake.github.io/docs/0.1/fonts/custom-fonts-client-side/vfs/ 이 링크 들어가면 커스텀 폰트를 쓰는 두 가지 방식이 있었는데, 그 중 2번 via URL protocol
은 쉽긴 쉬운데 ttf 파일을 지원하는 cdn을 무조건 써야 하는 방식이다. 근데 요즘 cdn 무료로 링크 지원하는 곳이 거의 없어서... 자체 cdn 서버 있거나 폰트 호스팅 서비스를 쓰지 않는 이상 거의 불가능함.
결국 1번 via Virtual file system (VFS)
쓰는 방식인데 말을 참 어렵게 써뒀음; Include your new build/vfs_fonts.js file in your code (in the same way you include pdfmake.js or pdfmake.min.js).
라는 문장이 있는데 이거 뭐... 내 코드 어디에 vfs_fonts.js를 포함시키라고?... in the same way you include pdfmake.js라니 난 pdfmake.js를 내 코드 안에 포함시킨 적이 없는데 뭘 하라고??.... 참나.......
어쨌든 하루종일 붙들고 늘어져서 해결하긴 해결했다. 진짜 마지막 시도 때 안 되면 다른 라이브러리로 갈아탈 생각이었는데 다행이도 성공함.
배경
윈도우 11 컴퓨터
react 18, typescript 사용.
pdfmake 0.2.18 버전. 문서에 따르면 0.1.72 이상의 버전만 via Virtual File system을 통해 폰트 커스텀이 가능하다고 한다.

한글 깨짐 문제 해결하는 방법 (by. 공식 문서)
- 내 프로젝트 폴더를 vscode로 켜주고 npm install pdfmake를 해서 pdfmake 설치하기
- vscode 사이드바에서 ./node_modules/pdfmake 폴더를 찾아낸다.
- 이 ./node_modules/pdfmake 폴더 안에 examples/fonts 폴더를 만든다. 그니까 ./node_modules/pdfmake/examples/fonts 폴더가 생성될 것. (이미 있으면 패스)
- 이 examples/fonts 폴더 안에 내가 원하는 폰트 ttf 확장자 파일을 집어넣는다. 난 나눔고딕체를 쓸 거라서 NanumGothic.ttf, NanumGothicBold.ttf.. 이런 ttf 파일들을 집어넣었다.
- 이제 윈도우 기준으로 컴퓨터 화면 밑에 검색창에
cmd
을 검색해서 명령 프롬프트 창을 킨다.

- cmd 창에서
cd 내 프로젝트 폴더경로/node_modules/pdfmake
명령어 쳐서 pdfmake 폴더로 이동한다. - 이제 여기서
node build-vfs.js "./examples/fonts"
라고 입력해준다. 아래 사진처럼 Builded .. 나오면 성공임.

8. 다시 vscode로 내 프로젝트 폴더 켜서 node_modules/pdfmake 폴더 안에 보면 build 라는 폴더가 있을텐데 여기 열면 vfs_fonts.js 라는 파일이 있다. 이걸 내 src 폴더 안에 뭐 assets/fonts 폴더라든가 하여간 내 원하는 위치에다 파일 붙여넣기한다 (이때!!! node_modules/pdfmake/build/vfs_fonts.js 파일을 잘라서 내 src폴더 안에 넣는거다 그니까 node_builds/pdfmake/build/ 폴더 안에는 vfs_fonts.js 파일이 있으면 안됨. 나중에 npm install 할 때 덮어써지면서 애써 커스텀 폰트 적용했던 게 다 날라갈 수 있으니 해당 파일은 npm install해도 영향 안 받게 우리 프로젝트 폴더로 꺼내오라는 거임.) 참고로 나는 src/assets/fonts 폴더 안에 뒀다.
9. src/assets/fonts 에 복붙한 vfs_fonts.js 파일을 보면 unexpected use of self
뭐 이딴 에러 뜨고 있을 거다 (안 뜨면 럭키비키임 그냥 공식 문서 2. assign pdfMake.addFonts(...) (or legacy pdfMake.fonts) in your javascript In your code, before calling pdf
여기 이후로 보면서 문서가 하란 대로 하면 됨) 아마 타입스크립트 써서 그런 거 같은데 나도 사실 잘은 모르겠다... 어쨌거나 이런 에러가 뜬다면 var vfs={...}
아래 코드는 다 삭제해주고 이 코드를 복붙해넣자.
var _global =
(typeof window !== "undefined" && window) ||
(typeof global !== "undefined" && global) ||
(typeof this !== "undefined" && this) ||
{};
// pdfMake에 가상 파일 시스템 추가
if (_global.pdfMake && _global.pdfMake.addVirtualFileSystem) {
_global.pdfMake.addVirtualFileSystem(vfs);
}
// CommonJS (Node.js) 환경 지원
if (typeof module !== "undefined" && module.exports) {
module.exports = vfs;
}
9. 이제 리액트 컴포넌트 내에다가 폰트 지정해줘야 한다. 나는 ReportPDF.tsx 라는 컴포넌트를 만들고 있었는데 (pdf 다운로드 버튼을 누르면 pdf가 다운받아지는 컴포넌트임.) 이 파일에 아래 코드를 추가해주자. 참고로 pdfMake.fonts 객체 안에 폰트 하나 설정할 때엔 normal, bold, italics, bolditalics 이 4개 모두 채워야 한다. 같은 ttf파일 대충 넣어도 되긴한데 어쨌든 4개 값 모두 넣어야 함. pdfmake에서 {text: "test text!", ...}
객체 넣을 때 fontWeight bold 글씨 넣고 싶다면 {text: "test text!", bold:true}
>> 이렇게 bold 속성에 값을 넣어야 하는데 만약 pdfMake.fonts 안 폰트의 bold속성에 ttf 파일 지정 안 해주면 에러 남.
import pdfMake from "pdfmake/build/pdfmake";
import vfs from "src/assets/fonts/vfs_fonts";
pdfMake.vfs = vfs;
pdfMake.fonts = {
NanumGothic: {
normal: "NanumGothic.ttf",
bold: "NanumGothic.ttf",
italics: "NanumGothic.ttf",
bolditalics: "NanumGothic.ttf", // << 4개 값들을 모두 채우자
},
};
...
const docDefinition = {
content: [
...
],
defaultStyle: {
font: "NanumGothic", //<< 이렇게 폰트 지정해주면 됨.
},
};
이제 실행해보면 다 된다! ㅠㅠ 이 간단한 거 하나때문에 몇 시간을 버린 건지ㅠㅠ