2016-07-21 23 views
0

私は安全なPDFファイルを作成しており、PDFファイルにはExcelが添付されています。保護されたPDFから添付ファイルを読む

以下は、私が試したコードです。

static void Main(string[] args) 
    { 
     Program pgm = new Program(); 
     pgm.EmbedAttachments(); 
     //pgm.ExtractAttachments(pgm.pdfFile); 
    } 

    private void ExtractAttachments(string _pdfFile) 
    { 
     try 
     { 
      if (!Directory.Exists(attExtPath)) 
       Directory.CreateDirectory(attExtPath); 

      byte[] password = System.Text.ASCIIEncoding.ASCII.GetBytes("TFAER13052016"); 
      //byte[] password = System.Text.ASCIIEncoding.ASCII.GetBytes("Password"); 


      PdfDictionary documentNames = null; 
      PdfDictionary embeddedFiles = null; 
      PdfDictionary fileArray = null; 
      PdfDictionary file = null; 
      PRStream stream = null; 

      //PdfReader reader = new PdfReader(_pdfFile); 

      PdfReader reader = new PdfReader(_pdfFile, password); 

      PdfDictionary catalog = reader.Catalog; 

      documentNames = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.NAMES)); 

      if (documentNames != null) 
      { 
       embeddedFiles = (PdfDictionary)PdfReader.GetPdfObject(documentNames.Get(PdfName.EMBEDDEDFILES)); 
       if (embeddedFiles != null) 
       { 
        PdfArray filespecs = embeddedFiles.GetAsArray(PdfName.NAMES); 

        for (int i = 0; i < filespecs.Size; i++) 
        { 
         i++; 
         fileArray = filespecs.GetAsDict(i); 
         file = fileArray.GetAsDict(PdfName.EF); 

         foreach (PdfName key in file.Keys) 
         { 
          stream = (PRStream)PdfReader.GetPdfObject(file.GetAsIndirectObject(key)); 
          string attachedFileName = fileArray.GetAsString(key).ToString(); 
          byte[] attachedFileBytes = PdfReader.GetStreamBytes(stream); 

          System.IO.File.WriteAllBytes(attExtPath + attachedFileName, attachedFileBytes); 
         } 

        } 
       } 
       else 
        throw new Exception("Unable to Read the attachment or There may be no Attachment"); 
      } 
      else 
      { 
       throw new Exception("Unable to Read the document"); 
      } 

     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
      Console.ReadKey(); 
     } 
    } 

    private void EmbedAttachments() 
    { 
     try 
     { 

      if (File.Exists(pdfFile)) 
       File.Delete(pdfFile); 

      Document PDFD = new Document(PageSize.LETTER); 



      PdfWriter writer; 
      writer = PdfWriter.GetInstance(PDFD, new FileStream(pdfFile, FileMode.Create)); 

      PDFD.Open(); 
      PDFD.NewPage(); 
      PDFD.Add(new Paragraph("This is test")); 

      PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(writer, @"C:\PDFReader\1.xls", "11.xls", null); 

      //PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(writer, attFile, "11", File.ReadAllBytes(attFile), true); 
      writer.AddFileAttachment(pfs); 
      //writer.AddAnnotation(PdfAnnotation.CreateFileAttachment(writer, new iTextSharp.text.Rectangle(100, 100, 100, 100), "File Attachment", PdfFileSpecification.FileExtern(writer, "C:\\test.xml"))); 

      //writer.Close(); 
      PDFD.Close(); 

      Program pgm=new Program(); 

      using (Stream input = new FileStream(pgm.pdfFile, FileMode.Open, FileAccess.Read, FileShare.Read)) 
      { 
       using (Stream output = new FileStream(pgm.epdfFile, FileMode.Create, FileAccess.Write, FileShare.None)) 
       { 
        PdfReader reader = new PdfReader(input); 
        PdfEncryptor.Encrypt(reader, output, true, "Password", "secret", PdfWriter.ALLOW_SCREENREADERS); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.StackTrace.ToString()); 
      Console.ReadKey(); 
     } 
    } 
} 

上記のコードには、Excel添付ファイル付きの暗号化されたPDFの作成と、それを抽出するコードが含まれています。

実際の問題は、既に私の例のようにExcelの添付ファイルを持っている要件文書(私はファイルを共有できません)として既に持っているファイルです。

しかし、上記のコードは、作成したセキュリティ保護されたPDFでは機能しますが、実際のセキュリティで保護されたPDFでは機能しません。

はデバッグ中、私は問題が

catalog.Get(PdfName.NAMES) 

は私が作成したファイルは、期待提供としてNULLとして返され

documentNames = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.NAMES)); 

、これには次のコードであることがわかりました出力。

私は上記に案内してください。

TIA。

+0

あなたのコードは添付ファイルをドキュメントレベルで追加し、そのようなドキュメントレベルの添付ファイルを抽出します。 PDFは、アノテーションを使用してページレベルで添付ファイルを追加することもできます。 [この回答](http://stackoverflow.com/a/14951567/1729265)では、両方のタイプの添付ファイルを抽出するiText/JavaとiTextSharp/C#コードを示しています。あなたは 'ExtractAttachments'のようなものを試したいかもしれません。 (iTextサイトが完全にオーバーホールされているので、その答えのリンクはもう機能しないかもしれません) – mkl

+0

ありがとう@mkl ..その非常に使いやすい。 。しかし、いくつかの代替案が行われなければならず、同じことが以下に回答されている。 –

答えて

0

mklが示唆しているように、注釈付き添付ファイルとして添付されています。しかし、この例で使用されている参照は提供されていますZipFileメソッドはサポートされなくなりました。したがって、私は下に別のコードが添付されています

public void ExtractAttachments(byte[] src) 
    { 
     PRStream stream = null; 
     string attExtPath = @"C:\PDFReader\Extract\"; 

     if (!Directory.Exists(attExtPath)) 
      Directory.CreateDirectory(attExtPath); 

     byte[] password = System.Text.ASCIIEncoding.ASCII.GetBytes("TFAER13052016"); 
     PdfReader reader = new PdfReader(src, password); 
     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)) 
         //); 
         stream = (PRStream)PdfReader.GetPdfObject(refs.GetAsIndirectObject(name)); 
         string attachedFileName = fs.GetAsString(name).ToString(); 
         var splitname = attachedFileName.Split('\\'); 
         if (splitname.Length != 1) 
          attachedFileName = splitname[splitname.Length - 1].ToString(); 
         byte[] attachedFileBytes = PdfReader.GetStreamBytes(stream); 

         System.IO.File.WriteAllBytes(attExtPath + attachedFileName, attachedFileBytes); 
        } 
       } 
      } 
     } 
    } 

他の方法で達成できるかどうか教えてください。

ありがとうございました!

関連する問題