如何从pdf文件中提取附件?

gyu*_*isc 9 .net c# pdf

我有一大堆pdf文档,附有xml文件.我想提取那些附加的xml文件并读取它们.如何使用.net以编程方式执行此操作?

Mar*_*rer 8

iTextSharp也能够提取附件......虽然您可能必须使用低级别对象来执行此操作.

有两种方法可以在PDF中嵌入文件:

  1. 在文件注释中
  2. 在文档级别"EmbeddedFiles".

从任一源获得文件规范字典后,文件本身将成为字典中标记为"EF"(嵌入文件)的流.

因此,要列出文档级别的所有文件,可以编写代码(使用Java):

Map<String, byte[]> files = new HashMap<String,byte[]>();

PdfReader reader = new PdfReader(pdfPath);
PdfDictionary root = reader.getCatalog();
PdfDictionary names = root.getAsDict(PdfName.NAMES); // may be null
PdfDictionary embeddedFilesDict = names.getAsDict(PdfName.EMBEDDEDFILES); //may be null
PdfArray embeddedFiles = embeddedFilesDict.getAsArray(PdfName.NAMES); // may be null

int len = embeddedFiles.size();
for (int i = 0; i < len; i += 2) {
  PdfString name = embeddedFiles.getAsString(i); // should always be present
  PdfDictionary fileSpec = embeddedFiles.getAsDict(i+1); // ditto

  PdfDictionary streams = fileSpec.getAsDict(PdfName.EF);
  PRStream stream = null;

  if (streams.contains(PdfName.UF))
    stream = (PRStream)streams.getAsStream(PdfName.UF);
  else
    stream = (PRStream)streams.getAsStream(PdfName.F); // Default stream for backwards compatibility

  if (stream != null) {
    files.put( name.toUnicodeString(), PdfReader.getStreamBytes((PRStream)stream));
  }
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*ini 5

这是一个古老的问题,尽管如此,我认为我的替代解决方案(使用PDF Clown)可能会引起人们的兴趣,因为它比以前建议的代码片段更加整洁(并且在文档和页面级别都可以迭代,因此更加完整)

using org.pdfclown.bytes;
using org.pdfclown.documents;
using org.pdfclown.documents.files;
using org.pdfclown.documents.interaction.annotations;
using org.pdfclown.objects;

using System;
using System.Collections.Generic;

void ExtractAttachments(string pdfPath)
{
  Dictionary<string, byte[]> attachments = new Dictionary<string, byte[]>();

  using(org.pdfclown.files.File file = new org.pdfclown.files.File(pdfPath))
  {
    Document document = file.Document;

    // 1. Embedded files (document level).
    foreach(KeyValuePair<PdfString,FileSpecification> entry in document.Names.EmbeddedFiles)
    {EvaluateDataFile(attachments, entry.Value);}

    // 2. File attachments (page level).
    foreach(Page page in document.Pages)
    {
      foreach(Annotation annotation in page.Annotations)
      {
        if(annotation is FileAttachment)
        {EvaluateDataFile(attachments, ((FileAttachment)annotation).DataFile);}
      }
    }
  }
}

void EvaluateDataFile(Dictionary<string, byte[]> attachments, FileSpecification dataFile)
{
  if(dataFile is FullFileSpecification)
  {
    EmbeddedFile embeddedFile = ((FullFileSpecification)dataFile).EmbeddedFile;
    if(embeddedFile != null)
    {attachments[dataFile.Path] = embeddedFile.Data.ToByteArray();}
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,您不必担心null指针异常,因为PDF Clown提供了所有必要的抽象和自动化功能,以确保顺利进行模型遍历。

PDF Clown是LGPL 3库,同时在Java和.NET平台中实现(我是其主要开发人员):如果您想尝试一下,建议您在sourceforge.net上查看其SVN存储库,以保持其状态。不断发展。