3

次の問題があります。XMLファイルが注釈として添付されたPDFがあります。埋め込みファイルとしてではなく、注釈として。今、私は次のリンクからのコードでそれを読み込もうとしています:

iTextSharp-添付ファイルを開く/読み取る/抽出する方法は?

埋め込みファイルでは機能しますが、注釈としてのファイル添付ファイルでは機能しません。

私はグーグルでPDFから注釈を抽出し、次のリンクを見つけました: iTextでPDF注釈を読む

したがって、注釈の種類は「添付ファイルの注釈」です。

誰かが実用的な例を示すことができますか?

助けてくれてありがとう

4

1 に答える 1

11

iTextとiTextSharpに関する質問でよくあることですが、最初にitexpdf.comのキーワードリストを確認する必要があります。ここにファイルの添付ファイルがあり、 iText in Actionから2つのJavaサンプルを参照する添付ファイルを抽出します—第2版:

古いキーワードリストはもうありません。itextpdf.comサイトは現在、例を検索するための他の方法を提供していますが、サイトが再び変更され、リンク切れがもう一度発生しないように、それらについては説明しません...

iText in Action —SecondEditionに基づく関連するiTextの例は次のとおりです。

  • part4.chapter16.KubrickDvds
  • part4.chapter16.KubrickDocumentary

これがiText5のサンプルです

(.NetおよびiText 7へのサンプルのポートは見つかりませんでしたが、他のソースに基づくと、このポートはそれほど難しくないはずです...)

KubrickDvdsには、ファイル添付ファイルの注釈を抽出するための次のメソッドが含まれていextractAttachmentsます。ExtractAttachments

Java、iText 5.x:

/**
 * Extracts attachments from an existing PDF.
 * @param src   the path to the existing PDF
 */
public void extractAttachments(String src) throws IOException {
    PdfReader reader = new PdfReader(src);
    PdfArray array;
    PdfDictionary annot;
    PdfDictionary fs;
    PdfDictionary refs;
    for (int i = 1; i <= reader.getNumberOfPages(); i++) {
        array = reader.getPageN(i).getAsArray(PdfName.ANNOTS);
        if (array == null) continue;
        for (int j = 0; j < array.size(); j++) {
            annot = array.getAsDict(j);
            if (PdfName.FILEATTACHMENT.equals(annot.getAsName(PdfName.SUBTYPE))) {
                fs = annot.getAsDict(PdfName.FS);
                refs = fs.getAsDict(PdfName.EF);
                for (PdfName name : refs.getKeys()) {
                    FileOutputStream fos
                        = new FileOutputStream(String.format(PATH, fs.getAsString(name).toString()));
                    fos.write(PdfReader.getStreamBytes((PRStream)refs.getAsStream(name)));
                    fos.flush();
                    fos.close();
                }
            }
        }
    }
    reader.close();
}

Java、iText 7.x:

public void extractAttachments(String src) throws IOException {
    PdfDocument pdfDoc = new PdfDocument(new PdfReader(src));
    PdfReader reader = new PdfReader(src);
    PdfArray array;
    PdfDictionary annot;
    PdfDictionary fs;
    PdfDictionary refs;
    for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
        array = pdfDoc.getPage(i).getPdfObject().getAsArray(PdfName.Annots);
        if (array == null) continue;
        for (int j = 0; j < array.size(); j++) {
            annot = array.getAsDictionary(j);
            if (PdfName.FileAttachment.equals(annot.getAsName(PdfName.Subtype))) {
                fs = annot.getAsDictionary(PdfName.FS);
                refs = fs.getAsDictionary(PdfName.EF);
                for (PdfName name : refs.keySet()) {
                    FileOutputStream fos
                            = new FileOutputStream(String.format(PATH, fs.getAsString(name).toString()));
                    fos.write(refs.getAsStream(name).getBytes());
                    fos.flush();
                    fos.close();
                }
            }
        }
    }
    reader.close();
}

C#、iText 5.x:

/**
 * Extracts attachments from an existing PDF.
 * @param src the path to the existing PDF
 * @param zip the ZipFile object to add the extracted images
 */
public void ExtractAttachments(byte[] src, ZipFile zip) {
  PdfReader reader = new PdfReader(src);
  for (int i = 1; i <= reader.NumberOfPages; i++) {
    PdfArray array = reader.GetPageN(i).GetAsArray(PdfName.ANNOTS);
    if (array == null) continue;
    for (int j = 0; j < array.Size; j++) {
      PdfDictionary annot = array.GetAsDict(j);
      if (PdfName.FILEATTACHMENT.Equals(
          annot.GetAsName(PdfName.SUBTYPE)))
      {
        PdfDictionary fs = annot.GetAsDict(PdfName.FS);
        PdfDictionary refs = fs.GetAsDict(PdfName.EF);
        foreach (PdfName name in refs.Keys) {
          zip.AddEntry(
            fs.GetAsString(name).ToString(), 
            PdfReader.GetStreamBytes((PRStream)refs.GetAsStream(name))
          );
        }
      }
    }
  }
}

KubrickDocumentaryには、ドキュメントレベルの添付ファイルを抽出するための次のメソッドが含まれていextractDocLevelAttachmentsます。ExtractDocLevelAttachments

Java、iText 5.x:

/**
 * Extracts document level attachments
 * @param filename     a file from which document level attachments will be extracted
 * @throws IOException
 */
public void extractDocLevelAttachments(String filename) throws IOException {
    PdfReader reader = new PdfReader(filename);
    PdfDictionary root = reader.getCatalog();
    PdfDictionary documentnames = root.getAsDict(PdfName.NAMES);
    PdfDictionary embeddedfiles = documentnames.getAsDict(PdfName.EMBEDDEDFILES);
    PdfArray filespecs = embeddedfiles.getAsArray(PdfName.NAMES);
    PdfDictionary filespec;
    PdfDictionary refs;
    FileOutputStream fos;
    PRStream stream;
    for (int i = 0; i < filespecs.size(); ) {
      filespecs.getAsString(i++);
      filespec = filespecs.getAsDict(i++);
      refs = filespec.getAsDict(PdfName.EF);
      for (PdfName key : refs.getKeys()) {
        fos = new FileOutputStream(String.format(PATH, filespec.getAsString(key).toString()));
        stream = (PRStream) PdfReader.getPdfObject(refs.getAsIndirectObject(key));
        fos.write(PdfReader.getStreamBytes(stream));
        fos.flush();
        fos.close();
      }
    }
    reader.close();
}

Java、iText 7.x

public void extractDocLevelAttachments(String src) throws IOException {
    PdfDocument pdfDoc = new PdfDocument(new PdfReader(src));
    PdfDictionary root = pdfDoc.getCatalog().getPdfObject();
    PdfDictionary documentnames = root.getAsDictionary(PdfName.Names);
    PdfDictionary embeddedfiles = documentnames.getAsDictionary(PdfName.EmbeddedFiles);
    PdfArray filespecs = embeddedfiles.getAsArray(PdfName.Names);
    PdfDictionary filespec;
    PdfDictionary refs;
    FileOutputStream fos;
    PdfStream stream;
    for (int i = 0; i < filespecs.size(); ) {
        filespecs.getAsString(i++);
        filespec = filespecs.getAsDictionary(i++);
        refs = filespec.getAsDictionary(PdfName.EF);
        for (PdfName key : refs.keySet()) {
            fos = new FileOutputStream(String.format(PATH, filespec.getAsString(key).toString()));
            stream = refs.getAsStream(key);
            fos.write(stream.getBytes());
            fos.flush();
            fos.close();
        }
    }
    pdfDoc.close();
}

C#、iText 5.x:

/**
 * Extracts document level attachments
 * @param PDF from which document level attachments will be extracted
 * @param zip the ZipFile object to add the extracted images
 */
public void ExtractDocLevelAttachments(byte[] pdf, ZipFile zip) {
  PdfReader reader = new PdfReader(pdf);
  PdfDictionary root = reader.Catalog;
  PdfDictionary documentnames = root.GetAsDict(PdfName.NAMES);
  PdfDictionary embeddedfiles = 
      documentnames.GetAsDict(PdfName.EMBEDDEDFILES);
  PdfArray filespecs = embeddedfiles.GetAsArray(PdfName.NAMES);
  for (int i = 0; i < filespecs.Size; ) {
    filespecs.GetAsString(i++);
    PdfDictionary filespec = filespecs.GetAsDict(i++);
    PdfDictionary refs = filespec.GetAsDict(PdfName.EF);
    foreach (PdfName key in refs.Keys) {
      PRStream stream = (PRStream) PdfReader.GetPdfObject(
        refs.GetAsIndirectObject(key)
      );
      zip.AddEntry(
        filespec.GetAsString(key).ToString(), 
        PdfReader.GetStreamBytes(stream)
      );
    }
  }
}

(何らかの理由で、c#の例では抽出されたファイルをZIPファイルに入れ、Javaバージョンではファイルシステムに入れます...まあ...)

于 2013-02-19T06:57:56.897 に答える