使用 iText7 将文本写入段落中的固定位置

问题描述

我尝试在 c# 中使用 iText7 编写带有标题、徽标和表格的 pdf 文件

我以前从未使用过 iText7,因此我不知道如何将段落中的文本写入固定位置。

现在我只是使用制表符作为文本的锚点。但这里的问题是,当字符串太长时,该行后面的所有内容都将被制表位移动,并且标题中的“列”不再对齐。

下图也是我想要实现的:

header with correct text alignment

这张图显示了如果字符串太长会发生什么(在这个例子中我使用了一个很长的用户名):

header with too long username

这是我用来编写一行标题代码片段:

// 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");

我希望有人可以帮助我向我展示一种更好的文本对齐方式或提供可以查看的信息。

一个很好的技巧是如何在同一个制表位部分中保留换行符。例如,如果文件名太长(图片中的“STR-Out:”),将执行换行符,但新行中的文件名部分应保留在“STR-OUT:”后面的制表位处/p>

解决方法

使用表格和单元格代替 Tab/Tabspace,以便正确对齐。

创建第 8 列大小的表格(标签、值、空格、标签、值、空格、标签、值)

使用此示例代码。

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 为我指明了使用表格的正确方向。

只需要将一些代码调整为 iText7。

第一件事是

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

在 iText7 中无效,您必须为每个单元格单独设置选项,例如:

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

但问题在于

cell.Add()

在 iText7 中只接受 IBlockElement 作为参数,所以我也像这样使用它:

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

一遍又一遍地为每个单元格这样做非常烦人。因此,我按照建议使用了 removeBorder 函数 here

所以我用来构建标题的最终代码如下所示:

 // 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);
     }
 }