Vue3에서 pdf 문서를 만들어봅시다!
이걸 만들면서 수없는 에러를 마주했다..
pdf 문서를 만드는 것 부터 만들면서 마주한 모든 에러를 기록해보려 한다!
# pdfmake란?
pdfmake는 자바스크립트에서 pdf 문서를 만들 수 있도록 도와주는 라이브러리 입니다!
- pdfmake 공식 사이트
- 공식 문서
https://pdfmake.github.io/docs/0.1/
- 공식 사이트에서 playground를 통해 테스트하기
http://pdfmake.org/playground.html
# pdfmake 설치하기
pdmake 사용을 위해 npm으로 설치했다!
npm i pdfmake
설치 후 import를 하자마자 빨간줄이 뜬다 ㅜ
에러는 다음과 같다.
could not find a declaration file for module 'pdfmake/build/pdfmake'.
Try `npm i --save-dev @types/pdfmake` if it exists or add a new declaration (.d.ts) file containing `declare module `pdfmake/build/pdfmake`;`
대충 읽어보면 pdfmake 찾을 수 없고, `npm i --save-dev @types/pdfmake` 시도해봐라~ 라고 말하는 것 같다..
바로 시도해본다 ㅎ
npm i --save-dev @types/pdfmake
혹시 설치 후에도 빨간줄이 사라지지 않는다면, vscode를 껐다 켜보자!
# pdf 문서 만들기
pdf 문서를 만드는 코드는 생각보다 정말 간단하다!
<template>
<div class="page">
<v-btn @click="openPDF">OPEN PDF</v-btn> // 버튼 클릭 시 openPDF 함수 실행
</div>
</template>
<script setup lang="ts">
import * as pdfMake from "pdfmake/build/pdfmake";
import * as pdfFonts from "pdfmake/build/vfs_fonts";
(<any>pdfMake).vfs = pdfFonts.pdfMake.vfs;
function openPDF() {
var docDefinition = {
content: [
{ text: "HYEPPY TISTORY", style: "header" }, // pdf에 들어갈 content 및 스타일 정의
{
text: "안녕하세요!! pdf 문서를 만들어봅시다~~~.",
style: "subheader",
margin: 30,
},
],
styles: {
header: {
fontSize: 40,
bold: true,
},
subheader: {
fontSize: 20,
bold: true,
},
},
};
pdfMake.createPdf(docDefinition).open(); // pdf 문서 열기
}
짠!!
매우 간단하지만 한글 불러오는건 어려운가보네,,ㅎㅎ
# 왜 한글이 깨지는걸까?
한글이 깨지는 문제가 발생했다. 왜일까?
문제를 해결하기 전에 중요한 한 가지를 먼저 알고 가는게 좋을 것 같다
공식문서에도 나와있듯이 vfs_font.js는 Roboto 폰트가 디폴트인데,
Roboto 폰트가 한글을 지원하지 않아서 이러한 문제가 생기는 것이다.
디폴트 폰트가 무엇인지 확인할 수 있는데
프로젝트 내 node_modules/pdfmake/build/ 경로 아래에 vfs_font.js가 존재한다.
vfs_font.js를 열어서 유심히보면
아래와 같은 형식으로 되어있을 것이다!
this.pdfMake = this.pdfMake || {}; this.pdfMake.vfs = {
"Roboto-Italic.ttf": "AAEAAAARAQAABAA~~",
"Roboto-MediumItalic.ttf": ARAQAABAA~~~",
"Roboto-Regular.ttf": ARAQAABAA~~~",
}
즉, vfs_font.js 내에 있는 폰트만 사용할 수 있다!
vfs_font.js 파일이 어디에 존재하고 어떠한 형식인지 알았다면 다음 단계로 넘어가도 좋다!!!
이것을 봐놓는것이 나중에 중요할 것이여,, 제가 헤맸거든여,,
# pdfmake 한글 깨짐 현상 해결하기(feat. Grunt)
한글이 깨지니 한글을 지원하는 폰트를 사용해야 한다.
pdfmake는 14개의 폰트를 지원하지만 나는 custom 폰트를 사용하려고 한다!
https://pdfmake.github.io/docs/0.1/fonts/standard-14-fonts/
내가 시도한 custom 폰트를 사용하는 방법은 다음과 같다.
1. 사용하려는 font를 다운받는다.(otf, ttf)
2. 다운받은 font를 vfs_font.js에 추가한다.
3. 다운받은 font를 정의하여 사용한다!
+ 결론부터 말하자면, 나는 otf를 다운받아 사용했는데, 문서가 열리지 않는 버그가 있었다.
ttf를 다운받아서 사용하니 문제가 사라졌다. 그러니 ttf로 따라해보고, 만약 otf가 잘 동작한다면 댓글로 공유해주세여><
1. 사용하려는 font를 다운받는다.(otf, ttf)
나는 네이버 글꼴 모음(https://hangeul.naver.com/font/nanum)에서 나눔고딕을 다운받았고,
src/examples/fonts 폴더 아래 다운받은 폰트를 넣었다.
2. 다운받은 font를 vfs_font.js에 추가한다.
이제 다운받은 font를 vfs_font.js에 추가해야한다.
이 부분이 제일 오래걸리고 어려웠다 ㅜ 하지만 지나고 나니 이것도 별거 아니였어.. 그니까 겁먹지말고 끝까지 따라해보세욧!!
이제 다운받은 font를 vfs_font.js에 추가하기 위해서는 Grunt를 설치해야 한다.
1. Grunt 란?
Grunt는 자바스크립트 태스크 러너인데, 나도 처음 들어봐서 블로그(https://ux.stories.pe.kr/71) 보고 아~ 이런거구나 했다.
2. Grunt 사용하기
먼저 Grunt를 설치하자!
npm install -g grunt-cli
npm install grunt --save-dev
Grunt를 설치하면 Gruntfile.js 파일 생성된다.
만약 생성되지 않았다면 프로젝트 상위 Gruntfile.js 파일을 만들자!
그리고 아래와 같이 Gruntfile.js 내 코드를 작성하자
/***** Gruntfile.js *****/
module.exports = function (grunt) {
/* ... */
grunt.initConfig({
dump_dir: {
fonts: {
options: {
pre: "this.pdfMake = this.pdfMake || {}; this.pdfMake.vfs = ",
rootPath: "./src/assets/examples/fonts/",
},
files: {
"./node_modules/pdfmake/build/vfs_fonts.js": ["./src/assets/examples/fonts/*"],
},
},
},
});
grunt.loadNpmTasks("grunt-dump-dir");
/* ... */
};
코드를 살펴보자!
나는 위에서 다운받은 font들을 "src/assets/example/fonts/" 에 두었다.
아래 코드는 "src/assets/example/fonts/" *(모든 폰트)를 "node_modules/pdfmake/build/vfs_fonts.js"에 생성하는 코드이다.
아까 위에서 언급한 것 처럼, vfs_fonts.js 파일이 어디에 존재하는지 알았으니 동일한 경로에 만들어준다.
files: {
"./node_modules/pdfmake/build/vfs_fonts.js": ["./src/assets/examples/fonts/*"],
},
아래 코드는 vfs_fonts.js를 작성할건데,
"this.pdfMake = this.pdfMake || {}; this.pdfMake.vfs = " 문자열을 가장 앞(pre)에 작성하는 코드이다!
아까 위에서 언급했듯이 vfs_fonts.js 파일의 형식이 this.pdfMake 어쩌구~~로 시작했기 떄문에 동일하게 작성한다!
options: {
pre: "this.pdfMake = this.pdfMake || {}; this.pdfMake.vfs = ",
rootPath: "./src/assets/examples/fonts/",
}
거의 다 왔다..
아래 명령어를 치면, 해당 경로에 vfs_fonts.js 파일이 생성될 것이다!
(테스트를 위해 files 경로를 바꿔서 해보세요!)
grunt dump_dir
3. Grunt 에러..
grunt dump_dir 명령어 실행하니 아래와 같은 에러가 났다.
Local Npm module "grunt-dump-dir" not found. Is it installed?
Warning: Task "dump_dir" not found. Use --force to continue.
1. 설치하라는 것 같아서 아래 명령어로 설치
npm install grunt-dump-dir --save-dev
또 에러다..
2. 버전 충돌인 것 같아 아래 명령어로 다시 설치
npm install grunt-dump-dir --save-dev --legacy-peer-deps
3. grunt dump_dir 명령어 다시 실행했더니 잘 생성되었다!
"node_modules/pdfmake/build/vfs_fonts.js" 에 "NanumGothic.ttf"가 추가된 것을 확인할 수 있다.
3. 다운받은 font를 정의하여 사용한다!
최종 코드는 아래와 같다!
<template>
<div class="page">
<v-btn @click="openPDF">OPEN PDF</v-btn>
</div>
</template>
<script setup lang="ts">
import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";
(<any>pdfMake).vfs = pdfFonts.pdfMake.vfs;
(<any>pdfMake).fonts = { // 추가
NanumGothic: {
normal: "NanumGothic.ttf",
bold: "NanumGothic.ttf",
},
};
function openPDF() {
var docDefinition = {
content: [
{ text: "HYEPPY TISTORY", style: "header" }, // pdf에 들어갈 content 및 스타일 정의
{
text: "안녕하세요!! pdf 문서를 만들어봅시다~~~.",
style: "subheader",
margin: 30,
},
],
styles: {
header: {
fontSize: 40,
bold: true,
},
subheader: {
fontSize: 20,
bold: true,
},
},
defaultStyle: {
font: "NanumGothic", // NanumGothic 폰트를 디폴트 스타일로 정의
},
};
pdfMake.createPdf(docDefinition).open();
}
</script>
결과 화면!!
한글이 출력되었다!! ㅎㅎ
제가 사용한 vfs_font.js 를 첨부했어요!
도움이 되었으면 좋겠슴다!!
'Vue' 카테고리의 다른 글
vuetify의 Navigation Drawers 컴포넌트 동작하지 않을 때(Vue3) (0) | 2023.10.26 |
---|---|
Vue3 페이지 레이아웃 구성하는 2가지 방법 (2) | 2023.10.23 |
Vuetify3 SASS Variables를 활용한 Style Custom (0) | 2023.10.06 |
Vue3 script setup 문법 (0) | 2023.09.22 |
(1) Vite를 이용한 Vuetify3 Project 만들기(+typescript) - 프로젝트 생성 (1) | 2023.09.22 |