Search code examples
c#wpfitextitext7

Write text to fixed position in paragraph with iText7


I try to write a pdf file with a header, logo and table using iText7 in c#.

I never used iText7 before and therefore I don't know how to write text in a paragraph to a fixed position.

Right now I am just using tabstops as anchors for my text. But the problem here is, when the string is too long everything following in the line will be shifted by a tabstop and the "columns" in the header aren't aligned anymore.

The following picture is what I want too achieve:

header with correct text alignment

This picture shows what happens if a string gets too long (in this example I used a long username):

header with too long username

Here is a code snippet I use to write one line of the header:

// generate 8 tabstops to split pdf in equal sections
List<TabStop> tabStops = new List<TabStop>();
for (uint i = 0; i < 8; i++)
{
    float tabSize = pageSize.GetWidth() / 8;
    tabStops.Add(new TabStop(tabSize, TabAlignment.LEFT));
}

Paragraph p = new Paragraph();
p.SetFontSize(10);

// add tabstops to paragraph for text alignment
p.AddTabStops(tabStops);

// add title of header 
p.Add(title1).Add("\n");

// write line one of header 
p.Add("Serie: ").Add(new Tab()).Add(info.serial.ToString())
    .Add(new Tab()).Add(new Tab())
    .Add("Input CSV: ").Add(new Tab()).Add(info.inputFileName)
    .Add(new Tab()).Add(new Tab()).Add("Out-Series: ")
    .Add(info.serial.ToString()).Add("\n");
// line 2...
p.Add("User: ").Add(new Tab()).Add(info.username)
    .Add(new Tab()).Add(new Tab()).Add(new Tab())
    .Add("qPCR-Datei: ").Add(new Tab()).Add(info.qpcr1FileName)
    .Add(new Tab()).Add(new Tab()).Add(new Tab())
    .Add("STR-Out: ").Add(strFileName).Add("\n");

I hope someone can help me show me a better way of text alignment or has information where to look at.

Another nice tip would be how I can keep linebreaks in the same tab stop section. for example if a file name gets too long (s. "STR-Out: " in picture) the linebreak will be executed but the part of the filename in the new line should stay at the tab stop behind "STR-OUT: "


Solution

  • Thanks @shihabudheenk for pointing me in the right direction with the idea of using a table.

    Just had to adjust some code to iText7.

    First thing is that

    Table headerTable = new Table().SetBorder(Border.NO_BORDER);
    

    has no effect in iText7, you have to set the option for each cell individually like:

    Cell cell = new Cell().SetBorder(Border.NO_BORDER);
    

    but here is the problem that

    cell.Add()
    

    in iText7 only accepts IBlockElement as parameter so i have too use it like this:

    cell.Add(new Paragraph("text");
    

    which is pretty annoying doing that for every cell over and over again. Therefore i used a removeBorder function as suggested here

    So the final code I use to build the header looks like this:

     // initialize table with fixed column sizes
     Table headerTable = new Table(UnitValue.CreatePercentArray(
        new[] { 1f, 1.2f, 1f, 1.8f, 0.7f, 2.5f })).SetFixedLayout();
     
     // write headerline 1
     headerTable.AddCell("Serie: ").AddCell(info.serial.ToString())
                    .AddCell("Input CSV: ")
                    .AddCell(info.inputFileName)
     // write remaining lines...
     ....
    
     // remove boarder from all cells 
     removeBorder(headerTable);
    
     private static void removeBorder(Table table)
     {
         foreach (IElement iElement in table.GetChildren())
         {
             ((Cell)iElement).SetBorder(Border.NO_BORDER);
         }
     }