- 토정비결 페이지 구현 (연간/월별 운세) - 분야별 운세 (재물, 건강, 관운, 애정) - PDF 저장 기능 구현 (jsPDF + html2canvas) - 모든 결과 페이지에 PDF 다운로드 기능 추가 - PDFButton 재사용 가능한 컴포넌트 생성 - 홈페이지에 토정비결 링크 추가 - 페이지 간 네비게이션 링크 업데이트 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
73 lines
2.0 KiB
TypeScript
73 lines
2.0 KiB
TypeScript
import jsPDF from 'jspdf';
|
|
import html2canvas from 'html2canvas';
|
|
|
|
/**
|
|
* HTML 요소를 PDF로 변환하여 다운로드
|
|
* @param elementId - PDF로 변환할 HTML 요소의 ID
|
|
* @param filename - 다운로드될 PDF 파일명
|
|
*/
|
|
export async function downloadPDF(elementId: string, filename: string) {
|
|
try {
|
|
const element = document.getElementById(elementId);
|
|
if (!element) {
|
|
throw new Error(`Element with id "${elementId}" not found`);
|
|
}
|
|
|
|
// 로딩 표시
|
|
const originalContent = element.innerHTML;
|
|
|
|
// HTML을 캔버스로 변환
|
|
const canvas = await html2canvas(element, {
|
|
scale: 2, // 해상도 향상
|
|
useCORS: true,
|
|
logging: false,
|
|
backgroundColor: '#ffffff'
|
|
});
|
|
|
|
// 캔버스를 이미지로 변환
|
|
const imgData = canvas.toDataURL('image/png');
|
|
|
|
// PDF 생성
|
|
const pdf = new jsPDF({
|
|
orientation: 'portrait',
|
|
unit: 'mm',
|
|
format: 'a4'
|
|
});
|
|
|
|
const imgWidth = 210; // A4 width in mm
|
|
const pageHeight = 297; // A4 height in mm
|
|
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
|
let heightLeft = imgHeight;
|
|
let position = 0;
|
|
|
|
// 첫 페이지 추가
|
|
pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
|
|
heightLeft -= pageHeight;
|
|
|
|
// 여러 페이지가 필요한 경우
|
|
while (heightLeft > 0) {
|
|
position = heightLeft - imgHeight;
|
|
pdf.addPage();
|
|
pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
|
|
heightLeft -= pageHeight;
|
|
}
|
|
|
|
// PDF 다운로드
|
|
pdf.save(filename);
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error('PDF 생성 중 오류 발생:', error);
|
|
alert('PDF 생성에 실패했습니다. 다시 시도해주세요.');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 현재 페이지를 PDF로 다운로드
|
|
* @param filename - 다운로드될 PDF 파일명
|
|
*/
|
|
export async function downloadCurrentPageAsPDF(filename: string) {
|
|
return downloadPDF('pdf-content', filename);
|
|
}
|