2016-07-21 19 views
0

Ich arbeite an einer PDF-Datei, die eine gesicherte ist und ein Excel ist in der PDF-Datei angehängt.Anhang von einem gesicherten PDF lesen

Folgendes ist der Code, den ich ausprobiert habe.

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(); 
     } 
    } 
} 

Der obige Code enthält die Schaffung eines verschlüsselten PDF mit einem Befestigungs Excel und ebenfalls gleich zu extrahieren.

Jetzt ist das eigentliche Problem mit der Datei, die ich bereits als Anforderungsdokument habe (ich kann die Datei nicht teilen), die auch einen Excel-Anhang wie mein Beispiel hat.

Aber der obige Code funktioniert für die gesicherte PDF, die ich erstellt habe, aber nicht für die eigentliche Secured PDF.

Während des Debuggens, fand ich, dass das Problem mit dem folgenden Code ist

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

, in dem

catalog.Get(PdfName.NAMES) 

als NULL zurückgegeben wird, Wo, wie die Datei von mir erstellt, liefert die erwartete Ausgabe.

Bitte führen Sie mich auf dem oben genannten.

TIA.

+0

Ihr Code fügt Anhänge auf Dokumentebene hinzu und extrahiert solche Anhänge auf Dokumentebene. Alternativ dazu können PDFs Anhänge auf Seitenebene mithilfe von Anmerkungen hinzufügen. [Diese Antwort] (http://stackoverflow.com/a/14951567/1729265) zeigt iText/Java und iTextSharp/C# Code zum Extrahieren beider Arten von Anhängen. Vielleicht möchten Sie etwas wie "ExtractAttachments" versuchen. (Die Links in dieser Antwort funktionieren möglicherweise nicht mehr, da die iText-Site inzwischen komplett überarbeitet wurde.) – mkl

+0

Danke @mkl .. Es ist sehr benutzerfreundlich. . Aber es muss eine Alternative gefunden werden und das gleiche wurde unten beantwortet. –

Antwort

0

Wie mkl vorgeschlagen, wurde es als Anhang mit Anmerkungen versehen. Aber die Referenz, die in dem Beispiel verwendet wird, wird bereitgestellt ZipFile Methode wird nicht mehr unterstützt. Daher habe ich unten einen alternativen Code gefunden.

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); 
        } 
       } 
      } 
     } 
    } 

Bitte lassen Sie mich wissen, ob es auf andere Weise erreicht werden kann.

Danke !!!