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

如何在Xamarin.Forms中判断是否为Portfolio PDF并提取附件

Xamarin.Forms 无付费第三方包处理Portfolio PDF方案

前置依赖说明

你可以选择两种完全免费无授权成本的实现路径,无需使用任何付费商业包:

  1. 跨平台统一实现:使用iTextSharp 4.1.6版本,该版本遵循LGPL开源协议,只需动态链接即可商用,不需要开源你的业务代码,无任何付费要求
  2. 零第三方依赖实现:分别调用Android、iOS原生系统PDF解析API完成处理,完全不需要引入任何外部包

1. 判断PDF是否为Portfolio PDF

Portfolio PDF的核心特征是PDF根目录的Catalog字典中存在/Collection字段,以此作为判断依据即可,跨平台实现代码如下:

using iTextSharp.text.pdf;

public bool IsPortfolioPdf(string pdfFilePath)
{
    try
    {
        using (var reader = new PdfReader(pdfFilePath))
        {
            var catalog = reader.Catalog;
            // 检测是否存在Portfolio标识字段
            return catalog.GetAsDict(PdfName.COLLECTION) != null;
        }
    }
    catch
    {
        // 文件损坏或不是合法PDF直接返回false
        return false;
    }
}

如果选择原生实现,Android可以通过PdfRenderer读取PDF字典检测对应字段,iOS可以通过CorePDF框架解析Catalog字典完成判断,逻辑完全一致。


2. 提取Portfolio PDF中的附件文件

同样基于iTextSharp的跨平台提取代码如下:

using iTextSharp.text.pdf;
using System.IO;
using System.Collections.Generic;

public List<(string FileName, byte[] FileContent)> ExtractPortfolioAttachments(string pdfFilePath)
{
    var attachments = new List<(string, byte[])>();
    if (!IsPortfolioPdf(pdfFilePath)) return attachments;

    using (var reader = new PdfReader(pdfFilePath))
    {
        var namesDict = reader.Catalog.GetAsDict(PdfName.NAMES);
        if (namesDict == null) return attachments;
        
        var embeddedFilesDict = namesDict.GetAsDict(PdfName.EMBEDDEDFILES);
        if (embeddedFilesDict == null) return attachments;
        
        var filesArray = embeddedFilesDict.GetAsArray(PdfName.NAMES);
        if (filesArray == null) return attachments;

        for (int i = 0; i < filesArray.Size; i++)
        {
            // 偶数位为文件名,奇数位为文件描述对象
            if (i % 2 != 0) continue;
            
            var fileName = filesArray.GetAsString(i).ToString();
            var fileDescDict = filesArray.GetAsDict(i + 1);
            var embeddedFileStreamDict = fileDescDict.GetAsDict(PdfName.EF);
            
            foreach (PdfName streamKey in embeddedFileStreamDict.Keys)
            {
                var fileStream = (PRStream)embeddedFileStreamDict.GetAsStream(streamKey);
                var fileContent = PdfReader.GetStreamBytes(fileStream);
                attachments.Add((fileName, fileContent));
                break;
            }
        }
    }
    return attachments;
}

3. Xamarin.Forms 适配与展示说明

  • 权限配置:Android需要在Manifest中声明READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE权限,iOS需要在Info.plist中添加NSDocumentDirectoryUsageDescription等文件读写权限声明
  • 提取后的文件可以先写入应用沙盒目录,再通过WebView加载本地路径展示,普通PDF文件可直接被各平台WebView原生支持,无需额外渲染组件
  • 如果提取的附件是其他格式,也可以根据文件后缀调用对应系统能力打开展示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:09:03