import { NextRequest, NextResponse } from 'next/server';
import puppeteer from 'puppeteer';
/**
* PDF 생성 API
* POST /api/pdf/generate
*
* Body: {
* html: string,
* styles: string,
* title?: string,
* orientation?: 'portrait' | 'landscape',
* documentNumber?: string,
* createdDate?: string,
* showHeaderFooter?: boolean
* }
* Response: PDF blob
*/
export async function POST(request: NextRequest) {
try {
const {
html,
styles = '',
title = '문서',
orientation = 'portrait',
documentNumber = '',
createdDate = '',
showHeaderFooter = true,
} = await request.json();
if (!html) {
return NextResponse.json(
{ error: 'HTML content is required' },
{ status: 400 }
);
}
// Puppeteer 브라우저 실행 (Docker Alpine에서는 시스템 Chromium 사용)
const browser = await puppeteer.launch({
headless: true,
executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || undefined,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu',
'--disable-software-rasterizer',
],
});
const page = await browser.newPage();
// 전체 HTML 문서 구성 (인라인 스타일 포함)
const fullHtml = `
${title}
${html}
`;
// 뷰포트 설정 (문서 전체가 보이도록 넓게)
await page.setViewport({
width: 1200,
height: 1600,
deviceScaleFactor: 2,
});
// HTML 설정
await page.setContent(fullHtml, {
waitUntil: 'networkidle0',
});
// 헤더 템플릿 (문서번호, 생성일)
const headerTemplate = showHeaderFooter
? `
${documentNumber ? `문서번호: ${documentNumber}` : ''}
${createdDate ? `생성일: ${createdDate}` : ''}
`
: '';
// 푸터 템플릿 (라인 + 페이지번호)
const footerTemplate = showHeaderFooter
? `
`
: '';
// PDF 생성 (자동 스케일로 A4에 맞춤)
const pdfBuffer = await page.pdf({
format: 'A4',
landscape: orientation === 'landscape',
printBackground: true,
preferCSSPageSize: false,
scale: 0.75, // 문서를 75%로 축소하여 A4에 맞춤
displayHeaderFooter: showHeaderFooter,
headerTemplate: headerTemplate,
footerTemplate: footerTemplate,
margin: {
top: showHeaderFooter ? '20mm' : '10mm',
right: '10mm',
bottom: showHeaderFooter ? '20mm' : '10mm',
left: '10mm',
},
});
// 브라우저 종료
await browser.close();
// PDF 응답
return new NextResponse(Buffer.from(pdfBuffer), {
status: 200,
headers: {
'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename="${encodeURIComponent(title)}.pdf"`,
},
});
} catch (error) {
console.error('PDF 생성 오류:', error);
return NextResponse.json(
{ error: 'PDF 생성 중 오류가 발생했습니다.' },
{ status: 500 }
);
}
}