A2B 라고 적는건 아주 센스가 있어보여서 좋다.
여러 문서를 다루는 회사 프로젝트를 진행하다보니, 문서를 import/export 하는 과정이 많아졌다.
그런 중 WYSIWYG Editor 도 지원을 했는데,
그러다보니 당연하게도 보이는걸 출력도 할 수 있게 해달라고 요청을 해왔다.
출력물을 관리할 필요는 없다고 판단, Front-End 에서 다운로드 받을 수 있게 해봤다.
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
export type Html2PDFProps = {
elementId: string;
classId?: string;
filename?: string;
element?: any;
whiteSpace?: number;
isSave?: boolean;
extraClass?: string;
extraId ?: string;
};
interface FinalHtml2PDFProps extends Html2PDFProps {}
export const Html2PdfComponent = async (
props: FinalHtml2PDFProps
): Promise<any | null> => {
var el = document.getElementById(props.elementId);
if (props.classId && props.classId.length > 0) {
let el_list = document.getElementsByClassName(props.classId);
if (el_list.length > 0) el = el_list[0] as HTMLElement;
}
if (props.element) el = props.element;
let res = await new Promise((r) => {
if (el) {
// Style, Class, Id 등등 canvas 에 그리기전에 미리 세팅
el.setAttribute(
"style",
"width:1080px; margin:0; line-height: 160%"
);
el.setAttribute("id", props.extraId ? props.extraId : "");
if (props.extraClass) el.classList.add(props.extraClass);
//
html2canvas(el, {
width: 1080,
height: el.scrollHeight,
useCORS: true, // 외부 url 로드하는 Image 등이 껴있을경우를 위해
}).then((canvas) => {
const imgData = canvas.toDataURL("image/png", 1.0);
// A4 기준 비율 스크린이 딱 맞게 하기위해
var imgWidth = 210;
var pageHeight = imgWidth * 1.414;
//
var imgHeight = (canvas.height * imgWidth) / canvas.width;
var heightLeft = imgHeight;
const pdf = new jsPDF("p", "mm", "a4", 1);
const widthSpace = props.whiteSpace ? props.whiteSpace : 0;
var position = props.whiteSpace ? props.whiteSpace : 0;
pdf.addImage(
imgData,
"PNG",
widthSpace,
position,
imgWidth - widthSpace * 2, // 여백을 준다.
imgHeight - widthSpace * 2,
"",
"FAST" // 해당 옵션을 안주면 용량은 훨씬큰데, 품질은 비슷한 pdf가 만들어져서 용량 차원에서 옵션을 넣었다.
);
// 한 page 안에 다 못그릴 경우
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(
imgData,
"PNG",
widthSpace,
position,
imgWidth - widthSpace * 2,
imgHeight - widthSpace * 2,
"",
"FAST"
);
heightLeft -= pageHeight;
}
//
// 저장한다면 바로 pdf 다운로드 진행
if (props.isSave)
pdf.save(props.filename ? props.filename : "preview.pdf");
// console.log(imgData);
// Canvas 에 그린후 Image Data 를 raw data 로 추출
r(imgData);
});
}
});
if (el) el.setAttribute("style", "");
return res;
};
나의 경우 특정 데이터를 껴넣어야(?) 할 필요가 있어 직접 만들었다.
단순하게 html2pdf 기능은 아래 library 를 참고하면 될 듯 싶다.
https://ekoopmans.github.io/html2pdf.js/
그럼 안녕👋
페이지 처리하는 것 때문에 애먹고 있었는데 감사합니다!