如何在最后一行包装文本的PdfPCell中生成数字表格的领导者

时间:2014-11-20 17:56:48

标签: itextsharp

我有一个使用PDFPTable生成的数据表。

-------------------------------------- 
|Caption|Figure Title           |  PP|
-------------------------------------- 
| fig 1 |title text             |  2 |
--------------------------------|----|
| fig 2 | This is a longer title|    |
|       | text that wraps       | 55 |
--------------------------------------
| fig N | another title         | 89 |
--------------------------------------

我需要从最后一行文本生成领导点;它可能已经包裹在细胞中。

这里的示例再次显示了包装标题文本的图2项目,另外还有从文本末尾到单元格右侧的引导点。

| fig 2 | This is a longer title|    |
|       | text that wraps.......| 55 |

这就是我想要实现的目标。

当我写单元格文本时,我不知道它将在哪里包装,因此我不知道最后一行文本是为了测量它,如果我知道的话最后一行文字我很难找到跟随它的直接x位置。

到目前为止,我已经尝试利用Cell EventsTable Events在事后写出领导点。到目前为止阻止我的两个问题是:

  1. 我无法在包装文本的最后一行之后找到x位置。

  2. 如果我在整个文本的最后一行下面尝试底层点的策略(所以我不必知道它在x位置停止的位置。我现在做的是y位置)唯一的画布允许点出现的是PdfPTable.TEXTCANVAS但是它将引导点写在现有文本的顶部而不是下面。我可以给文本块一个背景颜色,所以如果它后面有一些领导点,它们将不可见(一个穷人的作物)。

  3. 我对PDFPTable上下文中的任何策略都持开放态度。

2 个答案:

答案 0 :(得分:3)

首先要做的事情:+1问题和你自己提供的答案。

但是...

虽然您的答案可能有效,但有更好的方法可以实现您的目标。我写了一个名为DottedLineLeader的小样本作为替代方案,它将更容易维护。此示例使用DottedLineSeparator对象中包含的Chunk

看看如何使用这样的块分隔符

Chunk leader = new Chunk(new DottedLineSeparator());
Paragraph p;
p = new Paragraph("This is a longer title text that wraps");
p.add(leader);

当我们将此Paragraph添加到PdfPCell时,我们会收到以下效果:

enter image description here

虚线中的点不是'.'个字符。相反,它是具有特定划线图案的实际线(矢量数据)。使用这种方法而不是您自己的方法,将显着减少代码中的行数,使用更少的CPU并生成更清晰的 PDF。

答案 1 :(得分:1)

这是一个满足问题要求的解决方案。

每个PdfPCell对象都有一个.Column属性,“返回列”的复合元素列表。其属性ColumnText.LastX返回“已写入的最后一行之后的X位置”。这是我们希望领导者点开始的位置。

这项工作可以在PdfPTablEvent.TableLayout处理程序中完成,其中所有单元格位置都是已知的。

class TofEvents : IPdfPTableEvent {
    public void TableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases)
    {
      // do the work here 
    }
 }

因为我们知道文本的最后一行在页面上的结束位置以及单元格右侧的位置,所以我们可以用点填充该空格。

为特定单元格创建适当数量的点的常规计算是:

// You'll have to get references to things you need from the handler method args - 
float ptXCellLeft = GetLeftSideOfCellFromIncomingWidthsArgument();
PdfPCell cell = GetCurrentCellFromIncomingCellsArgument(); 

// the math - 
Font f = getTheFontToUse(); // for measuring the text size in this font 
float leaderDotSymbolWidth = f.BaseFont.GetWidthPoint(".", f.Size);
float leaderDotsWidth = cell.Width - (cell.Column.LastX - ptXCellLeft);
string strLeaderDotsFillText = ".".Repeat(Convert.ToInt32(leaderDotsWidth / leaderDotSymbolWidth));

生成的 strLeaderDotsFillText 应该很好地适应最后一行的空间。