You need to enable JavaScript to run this app. C# iTextSharp提取PDF时PdfArray转PRIndirectReference报错如何解决
优惠活动
大模型
产品
解决方案
定价
更多

C# iTextSharp提取PDF时PdfArray转PRIndirectReference报错如何解决

问题根因

PDF规范中页面的/Contents属性支持两种存储格式:

  • 单内容流:存储为单个PRIndirectReference指向流对象,即你原有代码兼容的场景
  • 多内容流:存储为PdfArray数组,每个元素均为指向内容流的PRIndirectReference,你遇到报错的PDF就属于该场景

修改后完整代码

List<string> stringsList = new List<string>();
// 你原有excludeList、excludeHeaders的定义保持不变

for (int page = 1; page <= reader.NumberOfPages; page++)
{
    var cpage = reader.GetPageN(page);
    var content = cpage.Get(PdfName.CONTENTS);

    // 新增类型判断,兼容两种CONTENTS格式
    if (content is PdfArray contentArray)
    {
        // 遍历数组内的所有流引用
        foreach (var arrItem in contentArray)
        {
            ProcessContentStream(arrItem, reader, excludeList, excludeHeaders, stringsList);
        }
    }
    else if (content is PRIndirectReference ir)
    {
        // 单流场景走原有逻辑
        ProcessContentStream(ir, reader, excludeList, excludeHeaders, stringsList);
    }
}

// 抽离的流处理公共方法,保留你原有全部过滤逻辑
void ProcessContentStream(PdfObject contentObj, PdfReader reader, List<string> excludeList, List<string> excludeHeaders, List<string> stringsList)
{
    var ir = (PRIndirectReference)contentObj;
    var value = reader.GetPdfObject(ir.Number);

    if (value.IsStream())
    {
        PRStream stream = (PRStream)value;
        var streamBytes = PdfReader.GetStreamBytes(stream);
        var tokenizer = new PRTokeniser(new RandomAccessFileOrArray(streamBytes));

        try
        {
            while (tokenizer.NextToken())
            {
                if (tokenizer.TokenType == PRTokeniser.TK_STRING)
                {
                    string strs = tokenizer.StringValue;
                    bool br = excludeList.Any(st => strs.Contains(st));
                    if (!br)
                    {
                        if (!string.IsNullOrWhiteSpace(strs) &&
                            !stringsList.Any(i => i == strs && excludeHeaders.Contains(strs)))
                        {
                            stringsList.Add(strs);
                        }
                    }
                }
            }
        }
        finally
        {
            tokenizer.Close();
        }
    }
}

修改说明

  • 新增了/Contents返回值的类型判断逻辑,同时兼容单流、多流两种PDF存储结构,解决类型转换报错
  • 将原有的流解析逻辑抽为公共方法,避免代码冗余
  • 你原有的排除关键词、过滤页眉的业务逻辑完全保留,不会影响原有过滤效果

内容的提问来源于stack exchange,提问作者StackUseR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 14:15:02