You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PDF页数计算算法优化请求:解决多算一页问题

改进PDF页数计算算法的思路

原算法用于计算生成PDF所需的总页数,以便在页面底部显示分页信息(如“当前页码 / 总页数”),但在部分场景下会出现多计算一页的问题,以下是问题分析和改进思路:

原算法代码

int idx, pckIdx, totalPages;
bool increment;

foreach (MyObject item in result.OrderBy(x => x.Name))
{
    idx = 0;
    increment = false;
    itemsGrouped = item.Lines.GroupBy(grp => grp.Order);

    foreach (var itemLineGrp in itemsGrouped.OrderBy(r => r.Key))
    {
        pckIdx = 1;

        foreach (MyObjectLine itemLine in itemLineGrp)
        {
            if (idx % rowsPerPage == 0 && idx != 0)
            {
                totalPages++;
                idx = 0;
            }

            idx++;
            increment = true;
        }

        if (idx % rowsPerPage == 0 && idx != 0)
        {
            totalPages++;
            idx = 0;
        }
    }

    totalPages++;
}

public class MyObject 
{
    public string Name { get; set; }
    public IList<MyObjectLine> Lines  { get; set; }  
    // Other props
}

public class MyObjectLine
{
    public int Order { get; set; }
    // Other props
}

原算法的问题点

  • 每个MyObject末尾强制加页:无论该对象的内容是否已经被完全计算页数,都会执行totalPages++,这会导致当对象内容刚好占满整数页时,额外多算一页。
  • 重复的分页判断:在分组内的行循环结束后,又重复判断一次分页条件,和行循环内的判断逻辑重叠,可能导致重复计数。
  • 未处理空内容边界:如果某个MyObject没有Lines数据,或者分组后没有内容,依然会强制加一页,造成无效计数。

改进思路与优化代码

核心优化方向

  1. 移除强制加页逻辑:删除每个MyObject循环末尾的totalPages++,页数完全由实际内容的行数决定。
  2. 用向上取整统一计算页数:对于每个对象的总行数,使用(总行数 + rowsPerPage - 1) / rowsPerPage的公式快速计算所需页数,避免逐行计数的误差。
  3. 增加空内容判断:当对象没有有效行数据时,不计算页数。

优化后的示例代码

int totalPages = 0;
int rowsPerPage = // 你的每页行数配置

foreach (MyObject item in result.OrderBy(x => x.Name))
{
    // 先获取当前对象的所有有效行数
    int totalLines = item.Lines?.Count ?? 0;
    if (totalLines == 0)
    {
        continue; // 空内容跳过,不计算页数
    }

    // 计算当前对象需要的页数:向上取整
    int pagesForItem = (totalLines + rowsPerPage - 1) / rowsPerPage;
    totalPages += pagesForItem;
}

// 类定义保持不变
public class MyObject 
{
    public string Name { get; set; }
    public IList<MyObjectLine> Lines  { get; set; }  
    // Other props
}

public class MyObjectLine
{
    public int Order { get; set; }
    // Other props
}

若需保留分组分页逻辑(比如分组间强制分页)

如果你的业务要求每个Order分组必须单独分页(即不同分组不能在同一页),可以调整为按分组计算页数:

int totalPages = 0;
int rowsPerPage = // 你的每页行数配置

foreach (MyObject item in result.OrderBy(x => x.Name))
{
    if (item.Lines == null || !item.Lines.Any())
    {
        continue;
    }

    var itemsGrouped = item.Lines.GroupBy(grp => grp.Order).OrderBy(r => r.Key);
    foreach (var group in itemsGrouped)
    {
        int groupLineCount = group.Count();
        // 每个分组的页数向上取整
        int pagesForGroup = (groupLineCount + rowsPerPage - 1) / rowsPerPage;
        totalPages += pagesForGroup;
    }
}

内容的提问来源于stack exchange,提问作者Antônio MFA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:33:41