C# 获取单元格占用的行数

C# 获取单元格占用的行数,c#,pdf,itext,C#,Pdf,Itext,各位 我想知道是否有一种方法可以准确地获取某个单元格占用的行 目前我正在使用ff进行此操作。功能: private int GetRowLines(string content, float maxFloatPerRow) { if (string.IsNullOrEmpty(content)) content = string.Empty; float noteFwidth = BaseFont.GetWidthPoint(content, cellFont.

各位

我想知道是否有一种方法可以准确地获取某个单元格占用的行

目前我正在使用ff进行此操作。功能:

private int GetRowLines(string content, float maxFloatPerRow)
{
    if (string.IsNullOrEmpty(content))
        content = string.Empty;

    float noteFwidth = BaseFont.GetWidthPoint(content, cellFont.Size);

    int nextRowLines = 0;
    var test = noteFwidth / maxFloatPerRow;
    nextRowLines = (int)Math.Ceiling(test);

    return nextRowLines == 0 ? 1 : nextRowLines;
}
唯一的问题是我需要提供
maxFloatPerRow
,这只能通过反复试验来完成

  • 我将在我要测试的特定单元格中生成一个pdf,其中包含大量的
    “I”
  • 然后,我将复制该单元格中1行的所有内容(这将是该单元格一行中的最大字符数)
  • 使用
    BaseFont.GetWidthPoint
    方法获取“每行最大内容”的浮动宽度
  • 但是,我想创建一个实用方法,该方法将提供内容将占用的行数,前提是标题的宽度、内容的字体以及内容本身。如果需要,更多

    根据评论编辑

    我使用的是
    itext v.3.1.7.0
    ,我正在创建一个pdf,而不是编辑现有的pdf


    我希望你们能分享一些东西。谢谢。

    有几种选择。我将仅描述两个最简单解决方案的要点

    方法1

    使用pdf2Data(它是一个iText7附加组件),它能够将pdf文档转换为xml数据(给定文档匹配的模板)。但是,此附加组件仅适用于iText7,因此需要进行一些迁移工作

    方法2

  • 使用EventListener从目标页面收集所有线条绘制事件
  • 获得所有线渲染信息后,对其进行聚类,当且仅当线以大约90度的角度相交时,才将线放入同一簇中
  • 检查每个集群,包含特定阈值行的集群可以视为一个表
  • 对所有水平线进行垂直投影,这会告诉您有多少行(总共,在整个表中)
  • 对所有垂直线进行水平投影,这会告诉您有多少列(总计,在整个表中)
  • 现在已经有了每个单元格的边界,可以对表中的每个坐标子范围重复步骤4和5,以准确计算出该坐标范围内有多少行/列

  • 经过几天的试验,以下是我迄今为止的解决方法,这似乎足够准确:

        /// <summary>
        /// Gets number of rows this cell occupies.
        /// </summary>
        /// <param name="headerFwidths">The fwidths of the headers of the table this cell belongs to</param>
        /// <param name="index">The column index of the cell to check</param>
        /// <param name="cCell">The cell to check</param>
        /// <returns>int the number of rows</returns>
        public int GetRowLines(float[] headerFwidths, int index, CellValue cCell) {
            float tableWidth = Document.GetRight(Document.LeftMargin);
            float lPad = cCell.PaddingLeft != null ? cCell.PaddingLeft.Value : 2f;
            float rPad = cCell.PaddingRight != null ? cCell.PaddingRight.Value : 2f;
            float maxFloatPerRow = ((tableWidth / headerFwidths.Sum()) * headerFwidths[index]) - (lPad + rPad);
            string content = string.IsNullOrEmpty(cCell.Title) ? string.Empty : cCell.Title;
    
            int rowLines = 0;
            float cellFontWidth = BaseFont.GetWidthPoint(content, cCell.CellFont.Size);
            rowLines = (int)Math.Ceiling(cellFontWidth / maxFloatPerRow);
            return rowLines == 0 ? 1 : rowLines;
        }
    
    我们可以使用
    BaseFont.GetWidthPoint
    获取单元格的浮点值,
    cellFontWidth

    最后,我们将
    cellFontWidth
    maxFloatPerRow
    相除,以获得单元格占用的行数

    这可能不是100%准确,但到目前为止,这适用于我们的案例


    我希望这能帮助和我一样的人。(我接受这个答案。但是如果你有更好的答案,请随时发布。如果证明你的答案更好,我会很乐意接受你的答案。)

    如果OP有现有的PDF,这确实是答案。我不确定情况是否如此。也许OP正在创建PDF,也许他想知道一个单元格中渲染了多少行。无论如何,这个问题并不清楚。有一个代码示例,但该代码示例似乎与以下问题无关:字体是什么?填充物是什么?为什么OP没有考虑内容是如何分割的?这是一个奇怪的问题。@GeomanYabes如果你真的想得到答案,你可能想把它添加到你的问题中。此外:您使用的是哪个版本的iText?版本3.1.7.0,您确定吗?那太古老了。。这是他们安装的版本。升级它不是一个选项如果它是4.1.x或4.2.0,你可能会很幸运,它们也是很古老但最后的非AGPL版本。或者,当然,当前的5.5.x或7.0.x。。。但是3.x呢?不管他们是谁,你都应该让他们认真点。
    float maxFloatPerRow = ((tableWidth / headerFwidths.Sum()) * headerFwidths[index]) - (lPad + rPad);