2016-08-25 2 views
0

J'essaie de fusionner un groupe de fichiers PDF ensemble et de m'assurer qu'ils sont bien compressés et qu'il n'y a pas de ressources en double. Toutefois, dans mon code, si j'appelle SetSmartMode (true) sur mon graveur, la première écriture entraînera toujours une exception NullReferenceException.Si j'active le mode intelligent, une exception NullReferenceException est lancée

Voici mon code (vb.net):

Private Function CombinePdfBatch(pdfMetaData As IEnumerable(Of QuestDataSet.MetaDataRow), batchNumber As Integer, 
           fileNamePrefix As String, outputDir As String) As String 

    Dim outputFileName As String = Path.Combine(outputDir, fileNamePrefix & "_" & batchNumber & ".pdf") 

    Using combinedPdf As New PdfDocument(New PdfWriter(Path.Combine(outputDir, fileNamePrefix & "_" & batchNumber & ".pdf")).SetSmartMode(True)) 

     'Make sure we close the underlying stream when we're done with the combination 
     combinedPdf.SetCloseWriter(True) 
     combinedPdf.SetCloseReader(False) 
     combinedPdf.SetFlushUnusedObjects(False) 
     combinedPdf.GetWriter().SetCompressionLevel(CompressionConstants.BEST_COMPRESSION) 
     combinedPdf.GetWriter().SetCloseStream(True) 
     combinedPdf.SetDefaultPageSize(New Geom.PageSize(630, 810)) 

     Dim merger As New PdfMerger(combinedPdf) 

     For Each currentMD As QuestDataSet.MetaDataRow In pdfMetaData 
      Using currentPDF As New PdfDocument(New PdfReader(Path.Combine(programPaths.Input, currentMD.ReceivedFilesRowByInputFileRelation.FileName))) 
       currentPDF.SetCloseReader(True) 
       currentPDF.SetCloseWriter(False) 
       currentPDF.GetReader().SetCloseStream(True) 

       currentMD.CombinedFileName = outputFileName 
       currentMD.StartPage = combinedPdf.GetNumberOfPages() + 1 
       merger.Merge(currentPDF, 1, currentPDF.GetNumberOfPages()) 
       currentMD.EndPage = combinedPdf.GetNumberOfPages() 
      End Using 
     Next 
     merger.Close()    
    End Using 

    Return outputFileName 
End Function 

Dès merger.Merge est appelé, une NullReferenceException est levée. J'ai remplacé cela avec beaucoup d'autres fonctions, mais si quelque chose est ajouté au fichier PDF lorsque l'écrivain est en mode intelligent, il se bloque.

Si je désactive le mode intelligent, les fichiers PDF sont fusionnés. Mais je dois réduire la taille de ces fichiers PDF autant que possible sans sacrifiant trop de qualité. Puisque je sais qu'ils utilisent tous la même police et partagent des images de stock, je me suis dit que je les combinerais tous pour le faire.

EDIT: Voici une trace de la pile car Je t'aime les gars:

System.NullReferenceException occurred 
    HResult=-2147467261 
    Message=Object reference not set to an instance of an object. 
    Source=itext.kernel 
    StackTrace: 
     at iText.Kernel.Pdf.PdfWriter.ByteStore.SerDic(PdfDictionary dic, Int32 level, ByteBufferOutputStream bb, IntHashtable serialized) 
     at iText.Kernel.Pdf.PdfWriter.ByteStore.SerObject(PdfObject obj, Int32 level, ByteBufferOutputStream bb, IntHashtable serialized) 
     at iText.Kernel.Pdf.PdfWriter.ByteStore..ctor(PdfStream str, IntHashtable serialized) 
     at iText.Kernel.Pdf.PdfWriter.SmartCopyObject(PdfObject obj)  
     at iText.Kernel.Pdf.PdfWriter.CopyObject(PdfObject obj, PdfDocument document, Boolean allowDuplicating) 
     at iText.Kernel.Pdf.PdfObject.ProcessCopying(PdfDocument documentTo, Boolean allowDuplicating) 
     at iText.Kernel.Pdf.PdfArray.CopyContent(PdfObject from, PdfDocument document) 
     at iText.Kernel.Pdf.PdfWriter.CopyObject(PdfObject obj, PdfDocument document, Boolean allowDuplicating) 
     at iText.Kernel.Pdf.PdfObject.ProcessCopying(PdfDocument documentTo, Boolean allowDuplicating) 
     at iText.Kernel.Pdf.PdfDictionary.CopyContent(PdfObject from, PdfDocument document) 
     at iText.Kernel.Pdf.PdfWriter.CopyObject(PdfObject obj, PdfDocument document, Boolean allowDuplicating) 
     at iText.Kernel.Pdf.PdfObject.ProcessCopying(PdfDocument documentTo, Boolean allowDuplicating) 
     at iText.Kernel.Pdf.PdfObject.CopyTo(PdfDocument document, Boolean allowDuplicating) 
     at iText.Kernel.Pdf.PdfDictionary.CopyTo(PdfDocument document, Boolean allowDuplicating) 
     at iText.Kernel.Pdf.PdfDictionary.CopyTo(PdfDocument document, IList`1 excludeKeys, Boolean allowDuplicating) 
     at iText.Kernel.Pdf.PdfPage.CopyTo(PdfDocument toDocument, IPdfPageExtraCopier copier) 
     at iText.Kernel.Pdf.PdfDocument.CopyPagesTo(IList`1 pagesToCopy, PdfDocument toDocument, Int32 insertBeforePage, IPdfPageExtraCopier copier) 
     at iText.Kernel.Pdf.PdfDocument.CopyPagesTo(IList`1 pagesToCopy, PdfDocument toDocument, IPdfPageExtraCopier copier) 
     at iText.Kernel.Pdf.PdfDocument.CopyPagesTo(IList`1 pagesToCopy, PdfDocument toDocument) 
     at iText.Kernel.Utils.PdfMerger.Merge(PdfDocument from, IList`1 pages) 
     at iText.Kernel.Utils.PdfMerger.Merge(PdfDocument from, Int32 fromPage, Int32 toPage) 
     at QuestMonolithic.Process.CombinePdfBatch(IEnumerable`1 pdfMetaData, Int32 batchNumber, String fileNamePrefix, String outputDir) in C:\Users\cchrist\Documents\Visual Studio 2012\Projects\Quest_Monolithic\trunk\source\Process.vb:line 594 
    InnerException: 

Répondre

4

C'est un bug connu dans le iText 7 du code .NET et un correctif sera bientôt déployé. La méthode SerDic(), qui n'est appelée que lors de la copie en mode intelligent, gère incorrectement la récupération des clés de dictionnaire dans .NET, ce qui entraîne des pointeurs NULL.

Si vous voulez réparer vous-même, remplacer la ligne 592 itext.kernel.PdfWriter:

dic.KeySet().ToArray(keys); 

avec

keys = dic.KeySet().ToArray(keys); 
+0

Merci. Je vais essayer ça. Y a-t-il autre chose que je devrais savoir sur le code .NET? – sonicbhoc