Red_Phoenix
Red_Phoenix

Reputation: 507

Split overflow text in iText 7 paragraph

I have a document where the first page has three sections. The top and bottom section are required to be on the first page. The center section has dynamic text. I am trying to find a way to get all the text that will fit in the center section, set it, and then add the remaining to the continuation second page (if required).

I have looked at this S.O. answer, but it seems that it wouldn't allow for the bottom section to be placed where it needs to go.

Here is what I am trying to do.

using (var workStream = new MemoryStream())
{
    using (var pdfWriter = new PdfWriter(workStream))
    {
        using (var pdfDoc = new PdfDocument(pdfWriter))
        {
            var document = new Document(pdfDoc);
            var pageSize = pdfDoc.GetDefaultPageSize();
            var width = pageSize.GetWidth() - document.GetLeftMargin() - document.GetRightMargin();

            // *** First Top Section ***
            // ... variable creations removed for brevity ...
            document.Add(paragraph);
            document.Add(table);



            // *** CENTER SECTION ***
            // This section has a required float height of 325f



            // *** Third Bottom Section ***
            // ... table creation removed for brevity ...
            document.Add(table);

            // *** Create the second page if needed and add the overflow text ***

        }
    }
}

Upvotes: 0

Views: 777

Answers (1)

Red_Phoenix
Red_Phoenix

Reputation: 507

I found a solution that works for me. I am sure I could streamline it, but tempest fugit.

So here is how I got the text for section 1:

// Set the height of section 2 paragraph
var section2Height = 325f;

// Create a Text element with the desired text
var tempText = new Text(myDesiredText).SetFont(font);

// Create rectangle for the allowable space for section 2
var rectangle = new Rectangle(width, section2Height);

// Create PDFCanvas for the document
var pdfCanvas = new PdfCanvas(pdfDoc, 1);

// Create canvas space for adding the temp paragraph to for splitting
var canvas = new Canvas(pdfCanvas, rectangle);

// Set the temp text to a paragraph 
var synopsis = new Paragraph(tempText).SetFixedLeading(12f);

// Get the paragraph renderer
var renderer = synopsis.CreateRendererSubTree();

// Set the paragraph renderer parent to the canvas renderer
renderer.SetParent(canvas.GetRenderer());

// Process the renderer and get the layout result
var result = renderer.Layout(new LayoutContext(new LayoutArea(1, rectangle)));

// If the renderer is full, get all text, otherwise get the text that fits
var page1 = result.GetStatus() == LayoutResult.FULL ? renderer : result.GetSplitRenderer();

// Create a new paragraph for Section 2 (SYNOPSIS)
var newParagraph = new Paragraph().SetFixedLeading(12f);

// Set the Paragraph height and width
newParagraph.SetWidth(width);
newParagraph.SetHeight(section2Height);

// Get the count of child renderers.  Each one is a new line
var page1Count = page1.GetChildRenderers().Count;

// Instantiate a string for the last renderer text
var lastText = string.Empty;

// Iterate through the child renderers
for (var i = 0; i < page1Count; i++)
{
    // Get the string value
    var text = page1.GetChildRenderers()[i].ToString();

    // Create a text element
    var t1 = new Text(text + Environment.NewLine).SetFont(font);

    // Add the Text element to the new paragraph
    newParagraph.Add(t1);

    // If this is the last line, store the text for later use
    if (i + 1 == page1Count)
        lastText = text;
}

// Get the index of the last string of text
index = myDesiredText.IndexOf(lastText);

// Get the remaining text base off the index and the last text string length
var page2 = myDesiredText.Substring(index + lastText.Length);

// If there is a string value...
if (!string.IsNullOrEmpty(page2))
{
    // Create a list of line returns
    var returnCharList = new List<string> { "\r", "\n" };

    // Remove the beginning line returns
    while (returnCharList.Contains(page2.Substring(0, 1)))
        page2 = page2.Substring(2);

}

// Add the new paragraph to the section
document.Add(newParagraph);

This I how I set the rest of the text to the next page

// If there is a second page, build it out
if (!string.IsNullOrEmpty(page2))
{
    // Create the text element
    var page2Text = new Text(page2).SetFont(font);

    // Get the workable height for the paragraph minus the space for the page footer
    var page2Height = height - 30f;

    // Create page 2 paragraph
    var page2Paragraph = new Paragraph(page2Text).SetHeight(page2Height).SetFixedLeading(12f);

    // Add the paragraph to the document
    document.Add(page2Paragraph);

    // Create new pager
    pager = new Paragraph().AddTabStops(tabStops);

    // Set the page string for page 2
    pageBill = $"EBM - { RemoveBillSpaces(bsd.Bill.BillNumber)} - 2 of { totalPages }";

    // Create the text element
    pagerText = new Text(pageBill).SetFont(font).SetFontSize(fontSize_Small);

    // Add the tabs and text for the pager
    pager
    .Add(new Tab())
    .Add(new Tab())
    .Add(pagerText);

    // Add the pager to page 2
    document.Add(pager);
}

Upvotes: 1

Related Questions