【问题标题】:iText -- How do I get the rendered dimensions of text?iText -- 如何获得文本的渲染尺寸?
【发布时间】:2014-02-28 11:10:28
【问题描述】:

我想了解有关 PdfPCell 中文本布局的信息。我知道 BaseFont.getWidthPointKerned(),但我正在寻找更详细的信息,例如:

  1. 如果在给定宽度(例如 30pt)的单元格中呈现字符串,需要多少行? PdfPCell 的高度是多少?

  2. 给我一​​个字符串的前缀或后缀,该字符串适合给定宽度和高度的单元格。也就是说,如果我必须在宽度为 12pt、高度为 20pt 的 PdfPCell 中以特定字体呈现文本“Today is a good day to die”,那么字符串的哪一部分适合可用空间?

  3. 当要求 iText 在给定宽度的单元格中呈现给定字符串时,它在哪里中断?

这是关于 iText 2.1.6 的。谢谢。

【问题讨论】:

  • 是否有限制提问速度的政策?顺便说一句,我已经使用 iText 好几个月了。只是我决定立即问我的问题,而不是把它们运出去。我查看了 BaseFont 中的其他方法,看看是否有方法可以为我提供此信息,但没有。
  • 对于其他问题,我已经展示了我尝试过的内容(例如:stackoverflow.com/questions/22093993/…)。那个描述了这个问题,到目前为止我是如何部分解决它的,并就我接下来可以做什么提出了建议。在这种情况下,我想不出还有什么可以尝试的,因为我找不到合适的 API 方法可以尝试。我不是要求被教导或“请做我的功课”。关于你的代码请求,我可以给你分列的代码,但这会比帮助更令人困惑。
  • 拆分列不适用于此问题,但适用于 stackoverflow.com/questions/22093993/… 。您的评论是否适用于这个问题或链接的问题?谢谢。
  • 感谢有关 PdfTemplate 的提示。我会试试看。关于你的另一点,我已尽力提出具体、详细的问题。不是“如何设置行高?” (这将是一个家庭作业/新手问题)但是“setMinimumHeight() 和 setFixedHeight() 如何交互?”我使用过 iText,阅读过 API 文档,尝试过,等等。但是你急于责怪我没有阅读这本书,却没有意识到这本书没有回答所提出的问题。如果你不想帮助我,那取决于你:)
  • 哦,感谢您构建 iText,我从中受益 :) 而且,作为一般说明,如果您发现特定问题令人困惑,请告诉我它的哪个方面令人困惑,我可以发布代码来说明这方面。简单地发布代码来涵盖所有内容会进入页面并混淆而不是澄清。

标签: itext


【解决方案1】:

iText 使用ColumnText 类将内容呈现到单元格。我在第 98-99 页的书中对此进行了解释。这意味着,就像ColumnText 一样,您需要区分文本模式复合模式

在任何情况下,ColumnText 都会测量字符的宽度并测试它们是否适合可用的宽度。如果不是,则拆分文本。您可以通过不同的方式更改拆分行为:通过引入连字符或定义自定义拆分字符。

我编写了一个小型概念证明来展示如何实现自定义“截断”行为。请参阅TruncateTextInCell 示例。

我没有将内容添加到单元格,而是有一个空单元格,我为其定义了一个单元格事件。我将长文本"D2 is a cell with more content than we can fit into the cell." 传递给此事件。

在这种情况下,我使用了一种奇特的算法:我希望在中间截断文本并在我截断文本的地方插入“...”。

BaseFont bf = BaseFont.createFont();
Font font = new Font(bf, 12);
float availableWidth = position.getWidth();
int contentLength = content.length();
int leftChar = 0;
int rightChar = contentLength - 1;
availableWidth -= bf.getWidthPoint("...", 12);
while (leftChar < contentLength && rightChar != leftChar) {
    availableWidth -= bf.getWidthPoint(content.charAt(leftChar), 12);
    if (availableWidth > 0)
        leftChar++;
    else
        break;
    availableWidth -= bf.getWidthPoint(content.charAt(rightChar), 12);
    if (availableWidth > 0)
        rightChar--;
    else
        break;
    }
    String newContent = content.substring(0, leftChar) + "..." + content.substring(rightChar);
    PdfContentByte canvas = canvases[PdfPTable.TEXTCANVAS];
    ColumnText ct = new ColumnText(canvas);
    ct.setSimpleColumn(position);
    ct.addElement(new Paragraph(newContent, font));
    ct.go();

如您所见,我们从 position 参数中获取可用宽度,并检查有多少字符匹配,在内容开头的字符和结尾的字符之间交替。

结果显示在the resulting PDF:内容被截断如下:"D2 is a c... the cell."

您关于“多少行”的问题可以用类似的方式解决。 ColumnText 类有一个 getLinesWritten() 方法,可以为您提供该信息。您可以在我对您其他问题的回答中找到有关定位 ColumnText 对象的更多信息:Can I tell iText how to clip text to fit in a cell

【讨论】:

  • 谢谢,布鲁诺。我会尽快阅读您的三个答案并回复您。
  • 这个答案的一部分已被复制here
  • @KartickVaddadi 回答问题是我的荣幸。它一次又一次地证明 iText 的人真的很了解他们的东西。不幸的是,贵公司的一些人过去曾向我做出虚假承诺。不守信用是我认为不光彩的事情,所以我希望贵公司在拖了这么多年之后,终于能做正确的事了。
  • 我不知道我公司的其他人有什么承诺或没有承诺什么,以及在什么情况下等等,所以我对重复这些内容不感兴趣。让我们继续专注于技术讨论,好吗?
  • 不,这样不行。作为开发人员,您有责任做正确的事。您应该等到支持合同到位。我已经等了5年你们公司成为客户,你应该可以等到签订合同。我在等贵公司迈出这一步,不是相反!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
  • 2016-09-29
  • 1970-01-01
  • 2018-05-27
  • 1970-01-01
相关资源
最近更新 更多