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

Download

Output

business-cards_pdf_vt.pdf

Download

For AI-assisted development: Download Graphics Mill Code Samples XML Catalog