2016-04-08 52 views
7

Ho il seguente codice semplificato per estrarre PDF 8x10 esistenti da più posizioni, ruotandoli se necessario (quasi tutti devono essere), quindi li scrivo in una singola pagina PDF 11x17 di pagina ...Ruota più PDF e scrivi su un singolo PDF

while (Page < StackOne.Length) 
{ 
    Files++; 
    using (var strm = new FileStream(RenderPath + "Test_" + Page + ".pdf", FileMode.Create, FileAccess.Write, FileShare.Read)) 
    { 
     using (var MasterReport = new iTextSharp.text.Document(iTextSharp.text.PageSize._11X17)) 
     { 
      using (var writer = PdfWriter.GetInstance(MasterReport, strm)) 
      { 
       MasterReport.Open(); 
       MasterReport.NewPage(); 
       var cb = writer.DirectContent; 

       for (; Page <= NumPages * Files && Page < StackOne.Length; Page++) 
       { 
        var ProductionEntry = StackOne[Page - 1]; 

        var filepath = NetPath + ProductionEntry.UniqueProductId + ".pdf"; 
        if (File.Exists(filepath)) 
        { 
         var reader = new PdfReader(filepath); 
         var pagesize = reader.GetPageSize(1); 
         if (pagesize.Height > pagesize.Width) 
         { 
          var ExistingPage = reader.GetPageN(1); 
          var rotation = ExistingPage.GetAsNumber(PdfName.ROTATE); 
          int desiredrot = 90; 
          if (rotation != null) 
          { 
           desiredrot += rotation.IntValue; 
           desiredrot %= 360; 
          } 
          ExistingPage.Put(PdfName.ROTATE, new PdfNumber(desiredrot)); 
         } 
         cb.AddTemplate(writer.GetImportedPage(reader, 1), 50, 50); 
        } 
        MasterReport.NewPage(); 
       } 
      } 
     } 
    } 
} 

Tuttavia, la pagina visualizzata non ha le pagine ruotata come dovrebbero essere, ho verificato l'altezza è infatti in fase di presa> ramo larghezza ma le pagine restituite sono ancora 8x10 invece di 10x8 scritto su ogni pagina 11x17.

Ho cercato una domanda specifica ma non ho trovato uno che non si limitasse a scrivere su un altro file o sull'intera pagina anziché su una posizione specifica su un foglio 11x17.

EDIT: Così, con un po 'di sperimentazione e, cercando in altri esempi sono in grado di ruotare la pagina 8x10 e scrivere al mio 11x17 ma purtroppo non riesco a trovare un modo per metterlo esattamente dove mi vuole che qui è il relativo frammento di codice:

var reader = new PdfReader(filepath); 
var tm = new AffineTransform(1.0F, 0, 0, 1.0F, x, y); 
if (reader.GetPageSize(1).Height > reader.GetPageSize(1).Width) 
    tm.SetTransform(0, -1f, 1f, 0, 0, reader.GetPageSize(1).Height); 
writer.DirectContent.AddTemplate(writer.GetImportedPage(reader, 1), tm); 
+0

Mentre PdfCopy è il metodo consigliato per risolvere il problema, non sono riuscito a trovare alcuna documentazione che supporti la scrittura di più pagine su una singola pagina e tanto meno la rotazione. DirectContent sembrava essere l'unico modo per farlo. (Anche http://developers.itextpdf.com/examples/merging-pdf-documents/create-booklet-a4-document) – JasonSec

+0

'PdfCopy' è consigliato se vuoi avere le pagine il più originali possibile, ma sei interessato cambiandolo ridimensionando e arrangiando con più altre pagine. – mkl

+0

@mkl Questa è stata anche la mia impressione, grazie per aver verificato. – JasonSec

risposta

4

Va bene così, dopo tonnellate di ricerca e passare al setaccio il codice appare la risposta era molto semplice (come al solito), come illustrato sopra il mio problema iniziale stava mettendo un tag rotazione sul la pagina non ha effettivamente ruotato la pagina come mi aspettavo. Dopo aver appreso la possibilità di specificare una matrice per la pdftemplate è stato abbastanza semplice ecco il codice di lavoro:

var reader = new PdfReader(filepath); 
var tm = new AffineTransform(); 
if (reader.GetPageSize(1).Height > reader.GetPageSize(1).Width) 
    tm.SetTransform(0, -1f, 1f, 0, 0, reader.GetPageSize(1).Height); 
tm.Concatenate(new AffineTransform(1f, 0, 0, 1f, y, x)); 
writer.DirectContent.AddTemplate(writer.GetImportedPage(reader, 1), tm); 

P.S. http://partners.adobe.com/public/developer/en/pdf/PDFReference.pdf P: 162 (143 nella forma fisica) per coloro che non sono freschi su algebra

EDIT: Come @mkl ha seguito riportato il seguente è realmente applicabile solo per le voci di rotazione di 0 ° o 90 ° se avete pagine a 180 ° o 270 ° questo codice avrà bisogno di alcune modifiche. Inoltre, tutte le annotazioni dell'originale andranno perse.

+0

In alcuni casi il risultato potrebbe essere ancora diverso dalle tue aspettative: la pagina di origine potrebbe ad es. avere una voce di 180 ° ** Ruota **; in quel caso la tua copia viene disegnata sottosopra mentre il file originale viene mostrato correttamente.Essenzialmente il tuo codice è buono per la sorgente ** Ruota ** voci di 0 ° e 90 ° ma non per 180 ° e 270 °. Se la fonte utilizza un valore non predefinito ** UserUnit **, probabilmente otterrai una copia ridotta; è molto raro, tuttavia, modificare questo valore per dimensioni di pagina come la tua. Inoltre, se ti interessano le annotazioni, si perderanno. – mkl

+0

@mkl Non è applicabile nel mio caso, ma sicuramente vedo dove potrebbe essere un problema. Lo aggiungerò come appendice alla mia risposta. – JasonSec

0

È possibile aggiungere una trasformazione affine semplice nella procedura AddTemplate.

Ti piace questa:

   PdfContentByte cb = stamper.getOverContent(pageNumber); 
       int rotation = reader.getPageRotation(pageNumber); 

       PdfImportedPage page = stamper.getImportedPage(reader, pageNumber); 

       if (rotation == 270) 
        cb.addTemplate(page, 0, 1f, -1f, 0, reader.getPageSizeWithRotation(pageNumber).getWidth(), 0); 
       else if (rotation == 90) { 
        cb.addTemplate(page, 0, -1f, 1f, 0, 0, reader.getPageSizeWithRotation(pageNumber).getHeight()); 
       } else { 
        cb.addTemplate(page, 0, 0); 
       } 

sua java, ma penso che non è un problema.

+0

Alla tua soluzione manca ancora il trattamento corretto della custodia a 180 °. – mkl