summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-11-03 19:50:47 +0900
committerjoonhoekim <26rote@gmail.com>2025-11-03 19:50:47 +0900
commitfd9ffaaa01d79910f82c7c821b03966afed5f939 (patch)
treea0562482a572d309de330b4658e7fa29030d1a57
parent16dcdfe67bd7488a9b2ee1e0389602ec9dd7976b (diff)
(김준회) swp: 커버페이지 pdf로 확장자 변경, 생성 로직 최적화 (임시파일 로직 제거, 메모리에서 버퍼 직접 사용)
-rw-r--r--app/api/projects/[projectId]/cover/route.ts6
-rw-r--r--lib/cover/cover-service.ts60
2 files changed, 27 insertions, 39 deletions
diff --git a/app/api/projects/[projectId]/cover/route.ts b/app/api/projects/[projectId]/cover/route.ts
index 802e2ab6..f4038d43 100644
--- a/app/api/projects/[projectId]/cover/route.ts
+++ b/app/api/projects/[projectId]/cover/route.ts
@@ -51,15 +51,15 @@ export async function GET(
)
}
- // DOCX 파일로 응답
+ // PDF 파일로 응답
// Buffer를 Uint8Array로 변환
const uint8Array = new Uint8Array(result.buffer)
return new NextResponse(uint8Array, {
status: 200,
headers: {
- "Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
- "Content-Disposition": `attachment; filename="${encodeURIComponent(result.fileName || "cover.docx")}"`,
+ "Content-Type": "application/pdf",
+ "Content-Disposition": `attachment; filename="${encodeURIComponent(result.fileName || "cover.pdf")}"`,
"Content-Length": result.buffer.length.toString(),
},
})
diff --git a/lib/cover/cover-service.ts b/lib/cover/cover-service.ts
index eecc289b..6db0c9b4 100644
--- a/lib/cover/cover-service.ts
+++ b/lib/cover/cover-service.ts
@@ -2,7 +2,6 @@
import { PDFNet } from "@pdftron/pdfnet-node"
import { promises as fs } from "fs"
import path from "path"
-import { file as tmpFile } from "tmp-promise"
import db from "@/db/db"
import { projectCoverTemplates, projects } from "@/db/schema"
import { eq, and } from "drizzle-orm"
@@ -147,40 +146,29 @@ export async function generateCoverPage(
const result = await PDFNet.runWithCleanup(async () => {
console.log("🔄 PDFTron 초기화 및 변수 치환 시작")
- // 임시 파일 생성 (결과물 저장용)
- const { path: tempOutputPath, cleanup } = await tmpFile({
- postfix: ".docx",
- })
-
- try {
- // 템플릿 로드 및 변수 치환
- console.log("📄 템플릿 로드 중...")
- const templateDoc = await PDFNet.Convert.createOfficeTemplateWithPath(
- templateFilePath
- )
-
- console.log("🔄 변수 치환 중...")
- // JSON 형태로 변수 전달하여 치환
- const resultDoc = await templateDoc.fillTemplateJson(
- JSON.stringify(templateData)
- )
-
- console.log("💾 결과 파일 저장 중...")
- // 임시 파일로 저장
- await resultDoc.save(tempOutputPath, PDFNet.SDFDoc.SaveOptions.e_linearized)
-
- console.log("✅ 변수 치환 완료")
-
- // 파일 읽기
- const buffer = await fs.readFile(tempOutputPath)
-
- return {
- success: true,
- buffer: Buffer.from(buffer),
- }
- } finally {
- // 임시 파일 정리
- await cleanup()
+ // 템플릿 로드 및 변수 치환
+ console.log("📄 템플릿 로드 중...")
+ const templateDoc = await PDFNet.Convert.createOfficeTemplateWithPath(
+ templateFilePath
+ )
+
+ console.log("🔄 변수 치환 중...")
+ // JSON 형태로 변수 전달하여 치환
+ const resultDoc = await templateDoc.fillTemplateJson(
+ JSON.stringify(templateData)
+ )
+
+ console.log("💾 메모리 버퍼로 저장 중...")
+ // 메모리에서 직접 버퍼 가져오기 (임시 파일 불필요)
+ const buffer = await resultDoc.saveMemoryBuffer(
+ PDFNet.SDFDoc.SaveOptions.e_linearized
+ )
+
+ console.log("✅ 변수 치환 및 PDF 생성 완료")
+
+ return {
+ success: true,
+ buffer: Buffer.from(buffer),
}
}, process.env.NEXT_PUBLIC_PDFTRON_SERVER_KEY)
@@ -192,7 +180,7 @@ export async function generateCoverPage(
}
// 7. 파일명 생성
- const fileName = `${docNumber}_cover.docx`
+ const fileName = `${docNumber}_cover.pdf`
console.log(`✅ 커버페이지 생성 완료: ${fileName}`)