DEV Community

IronSoftware
IronSoftware

Posted on

Adding a New Line in iTextSharp Alternatives Using IronPDF

Developers working with iTextSharp frequently struggle with a basic formatting task: adding new lines and paragraph breaks to PDF documents. With nearly 93,000 views on Stack Overflow, this question reveals a fundamental complexity in iTextSharp's text model. The library uses a hierarchy of Chunk, Phrase, and Paragraph objects that behave differently from standard text processing, leading to confusion when simple line breaks produce unexpected results. This article examines the various approaches to adding new lines in iTextSharp and compares them to HTML-based alternatives where standard markup handles formatting naturally.

The Problem

iTextSharp does not work like a word processor or HTML renderer. Text formatting requires understanding three distinct object types:

  • Chunk: The smallest text unit with uniform styling; has no concept of line wrapping
  • Phrase: A collection of Chunks that wraps text within page margins
  • Paragraph: A block-level element that automatically adds a new line after itself

Developers expecting \n to create line breaks often find their newlines ignored, text overlapping, or formatting breaking in unexpected ways. The confusion intensifies when using ColumnText, tables, or other layout containers where newline behavior differs from direct document insertion.

Error Messages and Symptoms

iTextSharp typically does not throw errors for newline issues. Instead, developers observe:

  • Newline characters (\n) being ignored entirely
  • Text rendering on top of itself without moving down
  • Chunk.NEWLINE having no visible effect in certain contexts
  • Multiple paragraphs appearing on the same line
  • Text wrapping at the margin but not where explicitly specified

Common code that fails to produce expected results:

// This may not create the line break developers expect
document.Add(new Chunk("Line 1\nLine 2"));

// Using Environment.NewLine also fails in some contexts
document.Add(new Phrase("First line" + Environment.NewLine + "Second line"));

// Chunk.NEWLINE ignored in ColumnText scenarios
columnText.AddText(new Chunk("Text before"));
columnText.AddText(Chunk.NEWLINE);
columnText.AddText(new Chunk("Text after")); // May render on same line
Enter fullscreen mode Exit fullscreen mode

Who Is Affected

This issue impacts developers across all experience levels:

Experience Levels: Junior developers are confused by the object hierarchy; experienced developers are frustrated when familiar patterns do not work.

Use Cases: Invoice generation, report building, document automation, form filling, certificate creation, and any application requiring formatted text output.

Scale: The 93,000 views on Stack Overflow indicate this is one of the most common iTextSharp questions, affecting thousands of developers.

Evidence from the Developer Community

Stack Overflow

Question Views Votes
Adding a new line in iTextSharp 92,854 19

Timeline

Date Event Source
2012-05-25 Original question posted Stack Overflow
2012-2020 Multiple answers posted with different approaches Stack Overflow
2020-06-12 Last activity on question Stack Overflow
Present Question still receiving views daily Stack Overflow

Developer Reports

"Edit One: Still not working with document"
— Developer, Stack Overflow, 2012

The frustration is evident: developers try multiple approaches, and even after reading answers, the newlines do not work as expected in their specific context.

Additional reports from the community describe:

  • Newlines being "stripped out or processed somehow"
  • Text wrapping on itself without moving down a line
  • ColumnText ignoring explicit line breaks entirely

Root Cause Analysis

The confusion stems from iTextSharp's PDF-centric design rather than a text-centric approach. PDF documents do not have a native concept of "lines" the way word processors do. Text is positioned at specific coordinates.

Understanding the Object Hierarchy

Chunk is the atomic unit. It cannot wrap text or handle line breaks on its own. A Chunk draws text at a position without any awareness of document boundaries or other text.

Phrase is a container for Chunks. It handles line wrapping when text exceeds the document width, but it does not automatically add spacing between separate Phrases. Multiple Phrases added consecutively appear on the same line if space permits.

Paragraph derives from Phrase and adds block-level behavior. Each Paragraph automatically inserts a new line after its content, similar to a <div> in HTML versus a <span>.

The analogy to HTML:

  • Chunk is like a <span> with inline styling but no block behavior
  • Phrase is like a <span> that can wrap
  • Paragraph is like a <div> or <p> with block-level formatting

ColumnText Complications

The ColumnText class introduces additional complexity. When using SetSimpleColumn, the leading (line spacing) must be set correctly, and text must be added as Phrases or Paragraphs rather than raw Chunks for newlines to take effect.

Methods to Add New Lines in iTextSharp

Method 1: Use Separate Paragraph Objects

The most reliable approach is to use separate Paragraph objects for each logical block of text:

using iTextSharp.text;
using iTextSharp.text.pdf;

public void CreateDocumentWithParagraphs()
{
    using (var document = new Document())
    using (var writer = PdfWriter.GetInstance(document, new FileStream("output.pdf", FileMode.Create)))
    {
        document.Open();

        // Each Paragraph automatically starts on a new line
        document.Add(new Paragraph("This is the first paragraph."));
        document.Add(new Paragraph("This is the second paragraph."));
        document.Add(new Paragraph("This is the third paragraph."));

        document.Close();
    }
}
Enter fullscreen mode Exit fullscreen mode

Advantage: Automatic line breaks between paragraphs.

Disadvantage: Cannot have inline styling variations within a single logical paragraph without nesting Phrases.

Method 2: Use Chunk.NEWLINE Within a Phrase

When you need multiple lines within a single styled block, add Chunk.NEWLINE to a Phrase:

public void CreateDocumentWithChunkNewline()
{
    using (var document = new Document())
    using (var writer = PdfWriter.GetInstance(document, new FileStream("output.pdf", FileMode.Create)))
    {
        document.Open();

        var phrase = new Phrase();
        phrase.Add(new Chunk("First line"));
        phrase.Add(Chunk.NEWLINE);
        phrase.Add(new Chunk("Second line"));
        phrase.Add(Chunk.NEWLINE);
        phrase.Add(new Chunk("Third line"));

        document.Add(phrase);

        document.Close();
    }
}
Enter fullscreen mode Exit fullscreen mode

Advantage: Keeps related lines together in a single container.

Disadvantage: Chunk.NEWLINE may be ignored in certain contexts like ColumnText.

Method 3: Embed Newline Characters in Chunk Text

You can include \n directly in the Chunk string:

public void CreateDocumentWithEmbeddedNewlines()
{
    using (var document = new Document())
    using (var writer = PdfWriter.GetInstance(document, new FileStream("output.pdf", FileMode.Create)))
    {
        document.Open();

        var paragraph = new Paragraph();
        paragraph.Add(new Chunk("Line 1\nLine 2\nLine 3"));
        document.Add(paragraph);

        document.Close();
    }
}
Enter fullscreen mode Exit fullscreen mode

Advantage: Compact syntax for simple cases.

Disadvantage: Inconsistent behavior depending on context; may be ignored in ColumnText.

Method 4: Use Empty Paragraphs for Spacing

To add vertical space (blank lines), use empty Paragraphs:

public void CreateDocumentWithBlankLines()
{
    using (var document = new Document())
    using (var writer = PdfWriter.GetInstance(document, new FileStream("output.pdf", FileMode.Create)))
    {
        document.Open();

        document.Add(new Paragraph("First section content."));

        // Add a blank line
        document.Add(new Paragraph(" "));

        document.Add(new Paragraph("Second section after blank line."));

        document.Close();
    }
}
Enter fullscreen mode Exit fullscreen mode

Advantage: Explicit control over vertical spacing.

Disadvantage: Uses a space character hack; SpacingBefore/SpacingAfter properties are more appropriate for controlled spacing.

Method 5: Use Paragraph Spacing Properties

For precise control, use the Paragraph class spacing properties:

public void CreateDocumentWithControlledSpacing()
{
    using (var document = new Document())
    using (var writer = PdfWriter.GetInstance(document, new FileStream("output.pdf", FileMode.Create)))
    {
        document.Open();

        var para1 = new Paragraph("First paragraph with spacing after.");
        para1.SpacingAfter = 20f; // 20 points after this paragraph

        var para2 = new Paragraph("Second paragraph with spacing before.");
        para2.SpacingBefore = 15f; // 15 points before this paragraph

        document.Add(para1);
        document.Add(para2);

        document.Close();
    }
}
Enter fullscreen mode Exit fullscreen mode

Advantage: Precise control over spacing in points.

Disadvantage: Requires understanding the Paragraph API rather than using intuitive newline characters.

Why These Approaches Fail in ColumnText

ColumnText.SetSimpleColumn requires explicit leading (line height) configuration:

public void CreateDocumentWithColumnText()
{
    using (var document = new Document())
    using (var writer = PdfWriter.GetInstance(document, new FileStream("output.pdf", FileMode.Create)))
    {
        document.Open();

        var cb = writer.DirectContent;
        var ct = new ColumnText(cb);

        // Define the column boundaries
        ct.SetSimpleColumn(36, 36, 559, 806);

        // Use Paragraphs, not raw Chunks, for proper line handling
        ct.AddElement(new Paragraph("Line 1"));
        ct.AddElement(new Paragraph("Line 2"));
        ct.AddElement(new Paragraph("Line 3"));

        ct.Go();

        document.Close();
    }
}
Enter fullscreen mode Exit fullscreen mode

Using AddElement with Paragraph objects provides consistent behavior. Using AddText with Chunks often results in ignored newlines.

A Different Approach: HTML with IronPDF

The complexity of Chunk, Phrase, and Paragraph objects exists because iTextSharp manipulates PDF primitives directly. An alternative approach is to define document content using HTML, where line breaks and paragraphs work as developers expect from web development.

Why HTML Eliminates the Confusion

In HTML:

  • <br> creates a line break
  • <p> creates a paragraph with automatic spacing
  • CSS controls margins, padding, and line height
  • No object hierarchy to memorize

IronPDF renders HTML using Chromium, so standard HTML and CSS produce expected results without learning a proprietary text model.

Code Example

using IronPdf;

public class DocumentWithLineBreaks
{
    public byte[] GenerateDocument()
    {
        var renderer = new ChromePdfRenderer();

        // Standard HTML handles line breaks naturally
        string html = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: Arial, sans-serif;
            font-size: 12pt;
            line-height: 1.6;
            margin: 40px;
        }
        p {
            margin-bottom: 16px;
        }
        .address {
            line-height: 1.4;
        }
        .section {
            margin-top: 24px;
        }
    </style>
</head>
<body>
    <h1>Invoice #12345</h1>

    <!-- Line breaks using <br> -->
    <div class='address'>
        Acme Corporation<br>
        123 Main Street<br>
        Suite 456<br>
        New York, NY 10001
    </div>

    <!-- Paragraphs with automatic spacing -->
    <div class='section'>
        <p>Thank you for your business. This invoice covers services rendered during the month of January 2025.</p>

        <p>Payment is due within 30 days of receipt. Please reference the invoice number when submitting payment.</p>

        <p>If you have any questions regarding this invoice, please contact our billing department.</p>
    </div>

    <!-- Controlled spacing with CSS margins -->
    <div style='margin-top: 40px;'>
        <p><strong>Total Due: $1,250.00</strong></p>
    </div>
</body>
</html>";

        using var pdf = renderer.RenderHtmlAsPdf(html);
        return pdf.BinaryData;
    }
}
Enter fullscreen mode Exit fullscreen mode

Key points about this approach:

  • <br> creates line breaks within a block
  • <p> elements create paragraphs with automatic spacing
  • CSS line-height controls spacing between lines
  • CSS margin properties control spacing between elements
  • No proprietary object model to learn

Comparison: iTextSharp vs HTML Approach

Task iTextSharp HTML (IronPDF)
Line break Chunk.NEWLINE or \n (context-dependent) <br>
New paragraph new Paragraph() <p>
Spacing control SpacingBefore, SpacingAfter properties CSS margin, padding
Line height Leading value in constructor CSS line-height
Mixed styling Nested Chunk/Phrase/Paragraph objects HTML tags with CSS

Complex Layout Example

public byte[] GenerateFormattedReport()
{
    var renderer = new ChromePdfRenderer();

    string html = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, sans-serif;
            margin: 50px;
            color: #333;
        }
        h1 {
            color: #2c3e50;
            border-bottom: 2px solid #3498db;
            padding-bottom: 10px;
        }
        .highlight {
            background-color: #f8f9fa;
            padding: 20px;
            border-left: 4px solid #3498db;
            margin: 20px 0;
        }
        .footer {
            margin-top: 40px;
            padding-top: 20px;
            border-top: 1px solid #ddd;
            font-size: 10pt;
            color: #666;
        }
        ul {
            line-height: 1.8;
        }
    </style>
</head>
<body>
    <h1>Monthly Status Report</h1>

    <p>This report summarizes project progress for the current reporting period.</p>

    <div class='highlight'>
        <strong>Key Achievements:</strong><br><br>
        Phase 1 development completed ahead of schedule.<br>
        User testing commenced with positive initial feedback.<br>
        Documentation updated to reflect latest changes.
    </div>

    <h2>Detailed Summary</h2>

    <p>The development team completed all scheduled tasks during this period. The following milestones were achieved:</p>

    <ul>
        <li>Database migration completed</li>
        <li>API endpoints deployed to staging</li>
        <li>Performance testing passed all benchmarks</li>
    </ul>

    <p>Next steps include production deployment and monitoring setup.</p>

    <div class='footer'>
        Generated on January 20, 2025<br>
        Confidential - Internal Use Only
    </div>
</body>
</html>";

    using var pdf = renderer.RenderHtmlAsPdf(html);
    return pdf.BinaryData;
}
Enter fullscreen mode Exit fullscreen mode

This example demonstrates headings, paragraphs, lists, styled blocks, and footers using standard HTML and CSS, without memorizing a proprietary object hierarchy.

API Reference

For more details on the methods used:

Migration Considerations

Licensing

  • iTextSharp (LGPL version) is available under LGPL for older versions
  • iText 7 requires commercial license or AGPL compliance
  • IronPDF is commercial software with per-developer licensing
  • IronPDF Pricing

API Differences

  • iTextSharp: PDF-centric object model (Chunk, Phrase, Paragraph)
  • IronPDF: HTML-centric approach with browser rendering

Migration involves:

  1. Converting document layout logic to HTML templates
  2. Replacing iTextSharp object construction with HTML string generation
  3. Using CSS for all spacing and formatting

What You Gain

  • Familiar HTML/CSS syntax for formatting
  • Consistent behavior for line breaks and spacing
  • No learning curve for web developers
  • CSS control over all visual aspects

What to Consider

  • Different approach to document generation
  • Chromium binaries add to deployment size
  • Commercial licensing model

Conclusion

iTextSharp's text model requires developers to understand the Chunk, Phrase, and Paragraph hierarchy to achieve consistent line breaks and spacing. The context-dependent behavior of newline characters leads to the 93,000-view Stack Overflow question and ongoing developer frustration. For teams comfortable with HTML and CSS, an HTML-to-PDF approach eliminates this complexity by using familiar web markup where <br> and <p> work as expected.


Jacob Mellor is CTO at Iron Software and originally built IronPDF.


References

  1. Stack Overflow: Adding a new line in iTextSharp{:rel="nofollow"} - 93K views
  2. iText Knowledge Base: How to add a full line break?{:rel="nofollow"} - Official documentation
  3. Mike's Dot Netting: iTextSharp - Adding Text with Chunks, Phrases and Paragraphs{:rel="nofollow"} - Comprehensive tutorial
  4. GitHub: Newlines being ignored{:rel="nofollow"} - Bug report on iTextSharp.LGPLv2.Core

For the latest IronPDF documentation and tutorials, visit ironpdf.com.

Top comments (0)