Superposicion sobre PDF existente
Descripcion general
gpdf puede abrir PDFs existentes y superponer nuevo contenido sobre ellos sin modificar los datos originales. Esto utiliza la tecnica de Actualizacion Incremental — los nuevos objetos se agregan despues de los bytes originales del PDF.
Casos de uso comunes:
- Agregar marcas de agua ("DRAFT", "CONFIDENTIAL")
- Insertar numeros de pagina
- Estampar marcas de aprobacion con fechas
- Agregar encabezados/pies de pagina a documentos existentes
Abrir un PDF existente
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)
}
Puede pasar las mismas opciones que NewDocument — fuentes, fuente predeterminada, etc.:
doc, err := gpdf.Open(pdfBytes,
gpdf.WithFont("NotoSans", fontData),
gpdf.WithDefaultFont("NotoSans", 12),
)
Superposicion en una pagina especifica
Use Overlay(pageIndex, fn) para agregar contenido en una pagina especifica (indice basado en 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)),
)
})
})
El PageBuilder soporta la misma API que al crear nuevas paginas — AutoRow, Absolute, Row, etc.
Superposicion en cada pagina
Use EachPage(fn) para iterar sobre todas las paginas:
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)))
})
Guardar el resultado
result, err := doc.Save()
if err != nil {
log.Fatal(err)
}
os.WriteFile("output.pdf", result, 0644)
El contenido original del PDF se conserva — Save() agrega los datos de superposicion despues de los bytes originales.
Ejemplo completo: Marca de agua + Numeros de pagina
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)
Referencia de API
| Metodo | Descripcion |
|---|---|
gpdf.Open(data, opts...) | Abrir un PDF existente para modificacion |
doc.PageCount() | Obtener el numero de paginas |
doc.Overlay(pageIndex, fn) | Agregar contenido en una pagina especifica (basado en 0) |
doc.EachPage(fn) | Agregar contenido en cada pagina |
doc.Save() | Devolver los bytes del PDF modificado |
Siguientes pasos
- Uso basico — Crear PDFs desde cero
- Estilos — Colores, decoracion de texto y tipografia
- Referencia de API — Referencia completa del paquete
gpdf