Guidance for PdfSharpCore PDF generation and modification library for .NET. USE FOR: creating PDF documents programmatically, drawing text/shapes/images on PDF pages, modifying existing PDFs, merging PDF files, generating reports and invoices as PDF, adding headers/footers/page numbers. DO NOT USE FOR: extracting text from PDFs (use PdfPig), PDF form filling with complex logic, high-volume HTML-to-PDF conversion (use a headless browser), PDF/A compliance.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Guidance for PdfSharpCore PDF generation and modification library for .NET. USE FOR: creating PDF documents programmatically, drawing text/shapes/images on PDF pages, modifying existing PDFs, merging PDF files, generating reports and invoices as PDF, adding headers/footers/page numbers. DO NOT USE FOR: extracting text from PDFs (use PdfPig), PDF form filling with complex logic, high-volume HTML-to-PDF conversion (use a headless browser), PDF/A compliance.
PdfSharpCore is a .NET Core port of the PdfSharp library for creating and modifying PDF documents. It provides a GDI+-style drawing API (XGraphics) for rendering text, shapes, images, and paths onto PDF pages. PdfSharpCore works entirely in managed code with no native dependencies, making it suitable for cross-platform and containerized environments.
PdfSharpCore is focused on PDF creation and modification. For reading/extracting text from existing PDFs, use PdfPig. For HTML-to-PDF conversion, consider a headless browser approach or QuestPDF for declarative document layout.
Install via NuGet:
dotnet add package PdfSharpCore
Creating a Simple PDF
Create a new PDF document with text and basic formatting.
using PdfSharpCore.Pdf;
using PdfSharpCore.Drawing;
var document = new PdfDocument();
document.Info.Title = "Sample Invoice";
document.Info.Author = "My Application";
var page = document.AddPage();
page.Size = PdfSharpCore.PageSize.A4;
var gfx = XGraphics.FromPdfPage(page);
// Titlevar titleFont = new XFont("Arial", 24, XFontStyle.Bold);
gfx.DrawString("INVOICE",
titleFont, XBrushes.DarkBlue,
new XRect(0, 40, page.Width, 40),
XStringFormats.Center);
// Company infovar normalFont = new XFont("Arial", 12);
gfx.DrawString("Acme Corporation", normalFont, XBrushes.Black, 50, 100);
gfx.DrawString("123 Business Ave, Suite 100", normalFont, XBrushes.Gray, 50, 118);
gfx.DrawString("New York, NY 10001", normalFont, XBrushes.Gray, 50, 136);
// Invoice detailsvar boldFont = new XFont("Arial", 12, XFontStyle.Bold);
gfx.DrawString("Invoice #: INV-2025-001", boldFont, XBrushes.Black, 350, 100);
gfx.DrawString("Date: January 15, 2025", normalFont, XBrushes.Black, 350, 118);
gfx.DrawString("Due: February 14, 2025", normalFont, XBrushes.Black, 350, 136);
document.Save("invoice.pdf");
Drawing Tables
Draw structured tables with headers, rows, and alternating row colors.
using PdfSharpCore.Pdf;
using PdfSharpCore.Drawing;
var document = new PdfDocument();
var page = document.AddPage();
var gfx = XGraphics.FromPdfPage(page);
var headerFont = new XFont("Arial", 11, XFontStyle.Bold);
var cellFont = new XFont("Arial", 10);
// Table configurationdouble startX = 50;
double startY = 200;
double[] columnWidths = { 200, 80, 80, 100 };
double rowHeight = 25;
string[] headers = { "Description", "Quantity", "Unit Price", "Total" };
// Draw header rowvar headerBrush = new XSolidBrush(XColor.FromArgb(40, 80, 120));
gfx.DrawRectangle(headerBrush,
startX, startY,
columnWidths.Sum(), rowHeight);
double x = startX;
for (int i = 0; i < headers.Length; i++)
{
gfx.DrawString(headers[i], headerFont, XBrushes.White,
new XRect(x + 5, startY + 5, columnWidths[i] - 10, rowHeight),
XStringFormats.CenterLeft);
x += columnWidths[i];
}
// Draw data rowsvar data = new[]
{
new { Description = "Web Development", Qty = "40 hrs", Price = "$150.00", Total = "$6,000.00" },
new { Description = "UI Design", Qty = "20 hrs", Price = "$120.00", Total = "$2,400.00" },
new { Description = "Server Hosting", Qty = "1 mo", Price = "$200.00", Total = "$200.00" }
};
for (int row = 0; row < data.Length; row++)
{
double y = startY + rowHeight * (row + 1);
// Alternating row backgroundif (row % 2 == 0)
{
gfx.DrawRectangle(new XSolidBrush(XColor.FromArgb(240, 240, 240)),
startX, y, columnWidths.Sum(), rowHeight);
}
// Row border
gfx.DrawRectangle(XPens.LightGray,
startX, y, columnWidths.Sum(), rowHeight);
// Cell valuesvar values = new[] { data[row].Description, data[row].Qty, data[row].Price, data[row].Total };
x = startX;
for (int col = 0; col < values.Length; col++)
{
gfx.DrawString(values[col], cellFont, XBrushes.Black,
new XRect(x + 5, y + 5, columnWidths[col] - 10, rowHeight),
XStringFormats.CenterLeft);
x += columnWidths[col];
}
}
document.Save("table-report.pdf");
Drawing Shapes and Lines
Use XGraphics to draw lines, rectangles, ellipses, and paths.
using PdfSharpCore.Pdf;
using PdfSharpCore.Drawing;
var document = new PdfDocument();
var page = document.AddPage();
var gfx = XGraphics.FromPdfPage(page);
// Horizontal rule
gfx.DrawLine(new XPen(XColors.DarkGray, 1), 50, 180, page.Width - 50, 180);
// Filled rectangle with rounded corners
gfx.DrawRoundedRectangle(
new XPen(XColors.Navy, 2),
new XSolidBrush(XColor.FromArgb(230, 240, 250)),
50, 400, 200, 100, 10, 10);
// Circle
gfx.DrawEllipse(XPens.Red, XBrushes.LightPink, 300, 400, 100, 100);
// Dashed linevar dashedPen = new XPen(XColors.Gray, 1)
{
DashStyle = XDashStyle.Dash
};
gfx.DrawLine(dashedPen, 50, 550, page.Width - 50, 550);
document.Save("shapes.pdf");
Adding Images
Embed images into PDF documents from files or streams.
using System.IO;
using PdfSharpCore.Pdf;
using PdfSharpCore.Drawing;
var document = new PdfDocument();
var page = document.AddPage();
var gfx = XGraphics.FromPdfPage(page);
// Load image from filevar logo = XImage.FromFile("logo.png");
// Draw at specific position and size (maintaining aspect ratio)double targetWidth = 150;
double aspectRatio = (double)logo.PixelHeight / logo.PixelWidth;
double targetHeight = targetWidth * aspectRatio;
gfx.DrawImage(logo, 50, 30, targetWidth, targetHeight);
// Draw from a streamusingvar imageStream = File.OpenRead("photo.jpg");
var photo = XImage.FromStream(() => imageStream);
gfx.DrawImage(photo, 50, 200, 400, 300);
document.Save("with-images.pdf");
Multi-Page Documents with Headers and Footers
Generate multi-page documents with consistent headers, footers, and page numbers.
using PdfSharpCore.Pdf;
using PdfSharpCore.Drawing;
var document = new PdfDocument();
var headerFont = new XFont("Arial", 9, XFontStyle.Italic);
var bodyFont = new XFont("Arial", 11);
var footerFont = new XFont("Arial", 8);
string[] paragraphs = GetReportParagraphs(); // your content sourceint totalPages = 3;
for (int pageNum = 1; pageNum <= totalPages; pageNum++)
{
var page = document.AddPage();
page.Size = PdfSharpCore.PageSize.A4;
var gfx = XGraphics.FromPdfPage(page);
// Header
gfx.DrawString("Acme Corp - Annual Report 2025",
headerFont, XBrushes.Gray,
new XRect(50, 20, page.Width - 100, 20),
XStringFormats.CenterLeft);
gfx.DrawLine(XPens.LightGray, 50, 40, page.Width - 50, 40);
// Body content areadouble yPos = 60;
// ... render content starting at yPos ...// Footer
gfx.DrawLine(XPens.LightGray, 50, page.Height - 50, page.Width - 50, page.Height - 50);
gfx.DrawString($"Page {pageNum} of {totalPages}",
footerFont, XBrushes.Gray,
new XRect(0, page.Height - 40, page.Width, 20),
XStringFormats.Center);
gfx.DrawString("Confidential",
footerFont, XBrushes.Gray,
new XRect(50, page.Height - 40, 200, 20),
XStringFormats.CenterLeft);
}
document.Save("multi-page-report.pdf");
string[] GetReportParagraphs() => new[] { "Content goes here." };
Merging PDF Documents
Combine multiple PDF files into a single document.
using System.Collections.Generic;
using PdfSharpCore.Pdf;
using PdfSharpCore.Pdf.IO;
publicclassPdfMerger
{
publicvoidMerge(IEnumerable<string> inputFiles, string outputFile)
{
var outputDocument = new PdfDocument();
foreach (varfilein inputFiles)
{
var inputDocument = PdfReader.Open(file, PdfDocumentOpenMode.Import);
for (int i = 0; i < inputDocument.PageCount; i++)
{
var page = inputDocument.Pages[i];
outputDocument.AddPage(page);
}
}
outputDocument.Save(outputFile);
}
}
// Usagevar merger = new PdfMerger();
merger.Merge(
new[] { "cover.pdf", "report.pdf", "appendix.pdf" },
"combined.pdf");
PdfSharpCore vs Other PDF Generators
Feature
PdfSharpCore
QuestPDF
iTextSharp
Puppeteer/Playwright
API style
Low-level drawing
Fluent layout
Mixed
HTML-to-PDF
Layout engine
Manual positioning
Auto-layout
Manual/auto
Browser engine
Learning curve
Medium
Low
High
Low
Cross-platform
Yes
Yes
Yes
Needs browser
Fine control
Excellent
Good
Excellent
Limited
License
MIT
Community/Paid
AGPL/Commercial
Apache 2.0
Best Practices
Dispose XGraphics objects or use them within the scope of a single page -- create a new XGraphics for each page rather than reusing across pages.
Use XRect with XStringFormats for text alignment instead of manually calculating text positions, which is error-prone and breaks with different font sizes.
Calculate page overflow by tracking the Y position of drawn content and adding new pages when content exceeds the page height minus margins.
Pre-calculate table column widths based on content or fixed proportions before rendering to avoid text overflow and misaligned columns.
Use consistent font instances by creating fonts once and reusing them across pages to reduce object creation and ensure visual consistency.
Maintain aspect ratio when drawing images by calculating target dimensions from the original PixelWidth and PixelHeight ratios.
Open existing PDFs with PdfDocumentOpenMode.Import when merging, and PdfDocumentOpenMode.Modify when editing in place.
Save to a MemoryStream in web applications and return the stream as a file download rather than writing to temporary disk files.
Use points (1/72 inch) for all measurements since PdfSharp uses points as its coordinate system -- convert from millimeters by multiplying by 72/25.4.
Test generated PDFs in multiple viewers (Adobe Acrobat, Chrome, macOS Preview) since different renderers handle fonts and transparency differently.