Create a PDF/VT file with personalized business cards
PDF VDP Personalization Color Profile Font
This sample shows how to generate a print-ready PDF/VT (variable-data/transactional) file containing a batch of personalized business cards. It reuses a single shared page layout loaded from a PDF template for every card, and adds document- and record-level PDF/VT metadata (job, sender, and production details) using PdfVtDictionary and the CIP4 dictionary keys. The sample uses PdfWriter with an OutputIntent and PdfVtOptions to embed a CMYK ICC profile and document metadata, and a CustomFontRegistry to draw each recipient's name, position, and contact details with custom TrueType fonts.
Сode Snippet
public static void Run()
{
var pdfTemplatePath = "business-card-front_template.pdf";
var pdfVtPath = "business-cards_pdf_vt.pdf";
var dpi = 300;
var now = DateTime.Now;
using (var pdfReader = new PdfReader(pdfTemplatePath, dpi, dpi))
using (var sharedContent = pdfReader.Frames[0].GetContent())
using (var fr = GetFontRegistry())
using (var profile = new ColorProfile("ISOcoated_v2_eci.icc"))
{
// Create the output intent
var intent = new OutputIntent
{
Profile = profile,
OutputConditionId = "ISOcoated_v2_eci",
Info = "ISO Coated v2 (ECI) CMYK output profile for sheetfed offset printing on coated paper",
OutputCondition = "Offset printing on coated paper (ISO 12647-2:2004 / Amd 1)",
Registry = "http://www.eci.org",
};
// Create document-level metadata for the PDF/VT file
var dpm = new PdfVtDictionary()
.AddDictionary(CIP4.Root, new PdfVtDictionary()
.AddDictionary(CIP4.Metadata, new PdfVtDictionary()
.AddString(CIP4.Conformance, "Meta - L1")
.AddString(CIP4.Creator, "Aurigma Graphics Mill")
.AddString(CIP4.JobID, "NorthwindBusinessCards-2026-04")
.AddString(CIP4.ModificationDate, PdfVtDictionary.DateTimeToPdfString(now))
.AddDictionary(CIP4.Sender, new PdfVtDictionary()
.AddDictionary(CIP4.Address, new PdfVtDictionary()
.AddString(CIP4.City, "San Francisco")
.AddString(CIP4.CivicNumber, "120")
.AddString(CIP4.Country, "United States")
.AddString(CIP4.PostalCode, "94105")
.AddString(CIP4.Region, "CA")
.AddString(CIP4.StreetName, "Howard Street"))
.AddDictionary(CIP4.Person, new PdfVtDictionary()
.AddString(CIP4.Department, "Print Production")
.AddString(CIP4.FirstName, "Laura")
.AddString(CIP4.LastName, "Stevens")
.AddString(CIP4.Organization, "Northwind Creative LLC"))))
.AddDictionary(CIP4.Summary, new PdfVtDictionary()
.AddInteger(CIP4.PageCount, 15)
.AddInteger(CIP4.RecipientCount, 15)
.AddDictionary(CIP4.Uniform, new PdfVtDictionary()
.AddBoolean(CIP4.Color, true)
.AddBoolean(CIP4.Orientation, true)
.AddBoolean(CIP4.Size, true))
.AddBoolean(CIP4.UniformRecipientStructure, true))
.AddDictionary(CIP4.Production, new PdfVtDictionary()
.AddInteger(CIP4.CopyCount, 100)
.AddDictionary(CIP4.Part, new PdfVtDictionary()
.AddName(CIP4.ProductType, "BusinessCard"))));
var vtOptions = new PdfVtOptions
{
DPartMetadata = dpm,
Title = "Northwind Creative Business Cards",
};
// Create the PDF/VT writer with the output intent and document-level metadata
using (var writer = new PdfWriter(pdfVtPath, intent, vtOptions))
using (var gr = writer.GetGraphics())
{
// Get our sample data for the business cards
var personData = GetPersonData();
for (int i = 0; i < personData.Length; i++)
{
var person = personData[i];
// Create record-level metadata for the current recipient
var recordDpm = new PdfVtDictionary()
.AddDictionary(CIP4.Root, new PdfVtDictionary()
.AddDictionary(CIP4.Metadata, new PdfVtDictionary()
.AddString(CIP4.Conformance, "Meta - L1")
.AddString(CIP4.Creator, "Aurigma Graphics Mill")
.AddString(CIP4.JobID, $"NorthwindBusinessCards-{now.Year.ToString()}-{now.Month.ToString()}")
.AddString(CIP4.ModificationDate, PdfVtDictionary.DateTimeToPdfString(DateTime.Now)))
.AddDictionary(CIP4.Summary, new PdfVtDictionary()
.AddInteger(CIP4.PageCount, 1)
.AddInteger(CIP4.RecipientCount, 1)
.AddDictionary(CIP4.Uniform, new PdfVtDictionary()
.AddBoolean(CIP4.Color, true)
.AddBoolean(CIP4.Orientation, true)
.AddBoolean(CIP4.Size, true))
.AddBoolean(CIP4.UniformRecipientStructure, true))
.AddDictionary(CIP4.Production, new PdfVtDictionary()
.AddInteger(CIP4.CopyCount, 100)
.AddDictionary(CIP4.Part, new PdfVtDictionary()
.AddName(CIP4.ProductType, "BusinessCard")))
.AddDictionary(CIP4.Recipient, new PdfVtDictionary()
.AddString(CIP4.UniqueID, $"BC-{now.Year.ToString()}-{now.Month.ToString()}-{(i + 1).ToString("0000")}")
.AddString(CIP4.FirstName, person.Name)
.AddString(CIP4.Organization, person.Company)
.AddString("Position", person.Position)
.AddDictionary(CIP4.Contact, new PdfVtDictionary()
.AddString(CIP4.Phone, person.Phone)
.AddString(CIP4.EMail, person.Email)
.AddString(CIP4.URI, person.Website)
.AddDictionary(CIP4.Address, new PdfVtDictionary()
.AddString("FormattedAddress", person.Address)))));
// Begin a new record in the PDF/VT document with the record-level metadata
writer.BeginRecord(recordDpm);
writer.AddPage(new PdfPage(
sharedContent.Width,
sharedContent.Height,
sharedContent.DpiX,
sharedContent.DpiY)
{
TrimBox = new System.Drawing.RectangleF(0, 0, sharedContent.Width, sharedContent.Height),
});
gr.FontRegistry = fr;
// sharedContent will be written to the PDF file only once, and then reused for each record.
gr.DrawContainer(sharedContent, 0, 0);
// Draw the variable data for the current recipient
DrawVariableData(gr, person);
// End the current record in the PDF/VT document
writer.EndRecord();
}
}
}
}
private static PersonInfo[] GetPersonData()
{
return new PersonInfo[]
{
new PersonInfo
{
Name = "Olivia Bennett",
Position = "Creative Director",
Phone = "+1 (415) 555-0101",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "olivia.bennett@northwindcreative.com",
},
new PersonInfo
{
Name = "Ethan Parker",
Position = "Senior Graphic Designer",
Phone = "+1 (415) 555-0102",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "ethan.parker@northwindcreative.com",
},
new PersonInfo
{
Name = "Sophia Reed",
Position = "Brand Strategist",
Phone = "+1 (415) 555-0103",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "sophia.reed@northwindcreative.com",
},
new PersonInfo
{
Name = "Liam Foster",
Position = "Art Director",
Phone = "+1 (415) 555-0104",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "liam.foster@northwindcreative.com",
},
new PersonInfo
{
Name = "Ava Coleman",
Position = "Account Manager",
Phone = "+1 (415) 555-0105",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "ava.coleman@northwindcreative.com",
},
new PersonInfo
{
Name = "Noah Hayes",
Position = "Senior Copywriter",
Phone = "+1 (415) 555-0106",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "noah.hayes@northwindcreative.com",
},
new PersonInfo
{
Name = "Isabella Ward",
Position = "UX Designer",
Phone = "+1 (415) 555-0107",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "isabella.ward@northwindcreative.com",
},
new PersonInfo
{
Name = "Mason Brooks",
Position = "Motion Designer",
Phone = "+1 (415) 555-0108",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "mason.brooks@northwindcreative.com",
},
new PersonInfo
{
Name = "Mia Price",
Position = "Marketing Coordinator",
Phone = "+1 (415) 555-0109",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "mia.price@northwindcreative.com",
},
new PersonInfo
{
Name = "Lucas Russell",
Position = "Production Manager",
Phone = "+1 (415) 555-0110",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "lucas.russell@northwindcreative.com",
},
new PersonInfo
{
Name = "Charlotte Griffin",
Position = "Client Success Manager",
Phone = "+1 (415) 555-0111",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "charlotte.griffin@northwindcreative.com",
},
new PersonInfo
{
Name = "James Diaz",
Position = "Digital Marketing Specialist",
Phone = "+1 (415) 555-0112",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "james.diaz@northwindcreative.com",
},
new PersonInfo
{
Name = "Amelia Sanders",
Position = "Illustrator",
Phone = "+1 (415) 555-0113",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "amelia.sanders@northwindcreative.com",
},
new PersonInfo
{
Name = "Benjamin Powell",
Position = "Business Development Manager",
Phone = "+1 (415) 555-0114",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "benjamin.powell@northwindcreative.com",
},
new PersonInfo
{
Name = "Harper Long",
Position = "Studio Coordinator",
Phone = "+1 (415) 555-0115",
Website = "https://www.northwindcreative.com",
Address = "120 Howard Street, San Francisco, CA 94105",
Company = "Northwind Creative LLC",
Email = "harper.long@northwindcreative.com",
},
};
}
private static void DrawVariableData(Aurigma.GraphicsMill.Drawing.Graphics gr, PersonInfo person)
{
var nameFont = gr.CreateFont("FrankRuhlLibre-Bold", 16);
var positionFont = gr.CreateFont("FrankRuhlLibre-Medium", 8);
var dataFont = gr.CreateFont("FrankRuhlLibre-Regular", 8);
var darkBrush = new SolidBrush(CmykColor.FromPercentages(.97f, 0.73f, 0.5f, 0.47f));
var redBrush = new SolidBrush(CmykColor.FromPercentages(.26f, 0.89f, 0.74f, 0.19f));
gr.DrawText(new PlainText(person.Name, nameFont) { Position = new System.Drawing.PointF(284, 187), Brush = darkBrush });
gr.DrawText(new PlainText(person.Position, positionFont) { Position = new System.Drawing.PointF(284, 247), Brush = redBrush });
gr.DrawText(new PlainText(person.Phone, dataFont) { Position = new System.Drawing.PointF(284, 347), Brush = darkBrush });
gr.DrawText(new PlainText(person.Email, dataFont) { Position = new System.Drawing.PointF(284, 405), Brush = darkBrush });
gr.DrawText(new PlainText(person.Website, dataFont) { Position = new System.Drawing.PointF(284, 464), Brush = darkBrush });
gr.DrawText(new PlainText(person.Address, dataFont) { Position = new System.Drawing.PointF(284, 524), Brush = darkBrush });
}
private static FontRegistry GetFontRegistry()
{
var fr = new CustomFontRegistry();
fr.Add("FrankRuhlLibre-Bold.ttf");
fr.Add("FrankRuhlLibre-Medium.ttf");
fr.Add("FrankRuhlLibre-Regular.ttf");
return fr;
}
Input
business-card-front_template.pdf
DownloadOutput
business-cards_pdf_vt.pdf
DownloadFor AI-assisted development: Download Graphics Mill Code Samples XML Catalog