如何在c#中从pdf文档中获取标签

Posted

技术标签:

【中文标题】如何在c#中从pdf文档中获取标签【英文标题】:How to get Tags from pdf document in c# 【发布时间】:2018-04-20 09:36:11 【问题描述】:

我正在使用 iTextSharp 阅读 pdf 文档,并且阅读成功。现在我想从 pdf 文档中获取标签,但我不知道如何使用 iTextSharp 获取标签。

代码如下

class Program

    static void Main(string[] args)
    
        var result = pdfText(@"C:\Users\Purelogics\Desktop\tranfer\tagged.pdf");
    

    public static string pdfText(string path)
    
        PdfReader reader = new PdfReader(path);
        //This line return true that means this document is tagged
        bool isTagged = reader.IsTagged();
        var metadeta = reader.Metadata;
        IList<Dictionary<string, object>> bookmarks = SimpleBookmark.GetBookmark(reader);
        string text = string.Empty;
        var title = reader.Info["Title"];
        for (int page = 1; page <= reader.NumberOfPages; page++)
        
            var object1 = reader.GetPdfObject(page);
            text += PdfTextExtractor.GetTextFromPage(reader, page);
        
        reader.Close();
        return text;
    

【问题讨论】:

【参考方案1】:

这取决于你想用这个标记做什么。 假设您要提取标记为\P(段落)的所有内容

首先你需要得到一个文档的结构树根

File inputFile = new File("input.pdf");
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inputFile));
IStructureNode root = pdfDocument.getStructTreeRoot();

现在您有了结构树根,您可以爬取树。通过堆栈或递归。在这个例子中,我使用了递归。

private Set<PdfNameMCIDGroup> find(PdfDocument pdfDocument, IStructureNode node)
    Set<PdfNameMCIDGroup> out = new HashSet<>();

    PdfName role = node.getRole();
    if(markedRoles.contains(role))
        out.add(mark(pdfDocument, node));
    else
        for(IStructureNode kid : node.getKids())
            out.addAll(find(pdfDocument, kid));

    return out;

这就是mark 方法的样子

private PdfNameMCIDGroup mark(PdfDocument pdfDocument, IStructureNode node)
    PdfNameMCIDGroup out = new PdfNameMCIDGroup(0);

    Set<PdfMcr> leaves = new HashSet<>();
    Stack<IStructureNode> stk = new Stack<>();
    stk.push(node);
    while(!stk.isEmpty())
        IStructureNode tmp = stk.pop();
        if(tmp instanceof PdfMcr)
            leaves.add((PdfMcr) tmp);
        else
            for(IStructureNode kid : tmp.getKids())
                stk.push(kid);
    

    // mcids
    for(PdfMcr mcr : leaves)
        int mcid = mcr.getMcid();
        int pageNr = pdfDocument.getPageNumber(mcr.getPageObject());
        out.mcids.add(mcid);
        out.pageNrs.add(pageNr);
    

    return out;

这些方法背后的想法是find 将遍历树层次结构。而mark 将在节点匹配其中一个角色时立即处理它。

这段代码让我们获得了一半的解决方案。 我们现在有了标记为\P的任何内容的标记内容ID

我们现在需要实际提取与这些 ID 匹配的渲染指令。

为此,您需要编写自己的IEventListener。这个类可以传递给CanvasProcessor,然后每次解析器完成处理指令时都会收到通知。

public void eventOccurred(IEventData iEventData, EventType eventType) 
    if(eventType == EventType.RENDER_TEXT)
    
        TextRenderInfo tri = (TextRenderInfo) iEventData;
        int mcID = tri.getMcid();
        // this is where you can do something with it
    

【讨论】:

以上是关于如何在c#中从pdf文档中获取标签的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 PDFrw 在 Python 中从 PDF 中提取数据

如何解决利用aspose把word文档转换为pdf文档时出现乱码 C#

请问有大神知道C#怎么获取上传的文档的缩略图吗?

在 Python 中从 PDF 中提取页面大小

如何在 C# 的 REST API 中获取 PDF 文件

如何使用 C# 合并包含所有者密码的 PDF 文档