2

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: "

mkl
  • 90,588
  • 15
  • 125
  • 265
try_3xcept
  • 151
  • 9

2 Answers2

1

Instead of Tab/Tabspace use Tables and Cells so that alignment will be proper.

Create table of column 8 size (Label, Value, space , Label, Value, Space, Label, Value)

Use this sample Code.

PdfPTable table = new PdfPTable(8);

PdfPCell cell;

cell = new PdfPCell();

cell.setRowspan(2); //only if spanning needed

table.addCell(cell);

for(int aw=0;aw<8;aw++){

table.addCell("hi");

}

shihabudheenk
  • 593
  • 5
  • 18
1

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);
     }
 }
try_3xcept
  • 151
  • 9