기존 PDF 오버레이

개요

gpdf는 기존 PDF를 열고 원본 데이터를 수정하지 않으면서 새 콘텐츠를 위에 오버레이할 수 있습니다. 이는 증분 업데이트(Incremental Update) 기술을 사용하며 — 원본 PDF 바이트 뒤에 새 객체가 추가됩니다.

일반적인 사용 사례:

  • 워터마크 추가 ("DRAFT", "CONFIDENTIAL")
  • 페이지 번호 삽입
  • 날짜가 포함된 승인 도장 찍기
  • 기존 문서에 머리글/바닥글 추가

기존 PDF 열기

import gpdf "github.com/gpdf-dev/gpdf"

// Read existing PDF bytes (from file, HTTP response, database, etc.)
pdfBytes, _ := os.ReadFile("input.pdf")

doc, err := gpdf.Open(pdfBytes)
if err != nil {
    log.Fatal(err)
}

NewDocument와 동일한 옵션을 전달할 수 있습니다 — 폰트, 기본 폰트 등:

doc, err := gpdf.Open(pdfBytes,
    gpdf.WithFont("NotoSans", fontData),
    gpdf.WithDefaultFont("NotoSans", 12),
)

단일 페이지에 오버레이

Overlay(pageIndex, fn)을 사용하여 특정 페이지(0부터 시작하는 인덱스)에 콘텐츠를 추가합니다:

doc.Overlay(0, func(p *template.PageBuilder) {
    p.Absolute(document.Mm(40), document.Mm(120), func(c *template.ColBuilder) {
        c.Text("DRAFT",
            template.FontSize(72),
            template.TextColor(pdf.Gray(0.85)),
        )
    })
})

PageBuilder는 새 페이지를 생성할 때와 동일한 API를 지원합니다 — AutoRow, Absolute, Row 등.

모든 페이지에 오버레이

EachPage(fn)을 사용하여 모든 페이지를 순회합니다:

count, _ := doc.PageCount()

doc.EachPage(func(pageIndex int, p *template.PageBuilder) {
    p.Absolute(document.Mm(170), document.Mm(285), func(c *template.ColBuilder) {
        c.Text(fmt.Sprintf("%d / %d", pageIndex+1, count),
            template.FontSize(10),
            template.AlignRight(),
        )
    }, template.AbsoluteWidth(document.Mm(20)))
})

결과 저장

result, err := doc.Save()
if err != nil {
    log.Fatal(err)
}
os.WriteFile("output.pdf", result, 0644)

원본 PDF 콘텐츠는 보존됩니다 — Save()는 원본 바이트 뒤에 오버레이 데이터를 추가합니다.

전체 예제: 워터마크 + 페이지 번호

pdfBytes, _ := os.ReadFile("report.pdf")

doc, err := gpdf.Open(pdfBytes)
if err != nil {
    log.Fatal(err)
}

count, _ := doc.PageCount()

doc.EachPage(func(i int, p *template.PageBuilder) {
    // Watermark
    p.Absolute(document.Mm(40), document.Mm(140), func(c *template.ColBuilder) {
        c.Text("CONFIDENTIAL",
            template.FontSize(60),
            template.TextColor(pdf.Color{R: 0.9, G: 0.9, B: 0.9, A: 1, Space: pdf.ColorSpaceRGB}),
        )
    })

    // Page number (bottom-right)
    p.Absolute(document.Mm(170), document.Mm(285), func(c *template.ColBuilder) {
        c.Text(fmt.Sprintf("%d / %d", i+1, count),
            template.FontSize(10),
            template.AlignRight(),
        )
    }, template.AbsoluteWidth(document.Mm(20)))
})

result, _ := doc.Save()
os.WriteFile("report_stamped.pdf", result, 0644)

API 레퍼런스

메서드설명
gpdf.Open(data, opts...)수정을 위해 기존 PDF 열기
doc.PageCount()페이지 수 가져오기
doc.Overlay(pageIndex, fn)특정 페이지에 콘텐츠 추가 (0부터 시작)
doc.EachPage(fn)모든 페이지에 콘텐츠 추가
doc.Save()수정된 PDF 바이트 반환

다음 단계