2010-09-25 12 views

risposta

9

Mi sono imbattuto in questo post del blog da Josh Twist che sembra fare ciò che vuoi.

Cracking an XPS in WPF

a cercare la rete, ci sono molti programmi/prova a pagamento che pretendono di fare questo (non ho provato nessuno di loro, quindi non posso pronunciarmi/elencare uno di essi). Presumo che tu voglia scrivere il tuo codice.

Ecco la 'carne' del post del blog (condensato):

Uri uri = new Uri(string.Format("memorystream://{0}", "file.xps")); 
FixedDocumentSequence seq; 

using (Package pack = Package.Open("file.xps", ...)) 
using (StorePackage(uri, pack)) // see method below 
using (XpsDocument xps = new XpsDocument(pack, Normal, uri.ToString())) 
{ 
    seq = xps.GetFixedDocumentSequence(); 
} 

DocumentPaginator paginator = seq.DocumentPaginator; 
Visual visual = paginator.GetPage(0).Visual; // first page - loop for all 

FrameworkElement fe = (FrameworkElement)visual; 

RenderTargetBitmap bmp = new RenderTargetBitmap((int)fe.ActualWidth, 
          (int)fe.ActualHeight, 96d, 96d, PixelFormats.Default); 
bmp.Render(fe); 

PngBitmapEncoder png = new PngBitmapEncoder(); 
png.Frames.Add(BitmapFrame.Create(bmp)); 

using (Stream stream = File.Create("file.png")) 
{ 
    png.Save(stream); 
} 

public static IDisposable StorePackage(Uri uri, Package package) 
{ 
    PackageStore.AddPackage(uri, package); 
    return new Disposer(() => PackageStore.RemovePackage(uri)); 
} 
+0

Grazie mille! Questo è esattamente quello che volevo; e l'ho usato e funziona! Grazie ancora! –

+0

Eccellente, felice che abbia aiutato. –

+0

Grazie per questa soluzione. Si potrebbe pensare che un'operazione relativamente semplice sarebbe molto più semplice di questo codice abbastanza denso ... non è esattamente ovvio. –

1

Si prega di fare riferimento al accettato la answer è davvero utile (mi ha anche aiutato) .Io voglio solo notare per alcuni molto punto importante in quella soluzione.

se si implementa il proprio DocumentPaginator (come nel mio caso), allora che il codice non funzionerà, perché non avremo riferimento alla vostra Paginator specifica dalla dichiarazione

DocumentPaginator paginator = seq.DocumentPaginator; 

Casting questo al tuo Paginator anche non funzionerà.

anche questa soluzione è molto complessa nel caso in cui tu abbia il tuo Paginator.
Così ho sviluppato una soluzione semplificata, che si basava sulla soluzione accettata di questa domanda e questo ha funzionato esattamente come necessario.

// create your own paginator instead of this 
// this is my specific own implementation for DocumentPaginator class 
ReportPaginator paginator = new ReportPaginator(report); 

Visual visual = paginator.GetPage(0).Visual; // first page - loop for all 

RenderTargetBitmap bmp = new RenderTargetBitmap((int)paginator.PageSize.Width, (int)paginator.PageSize.Height, 96d, 96d, PixelFormats.Default); 
bmp.Render(visual); 

PngBitmapEncoder png = new PngBitmapEncoder(); 
png.Frames.Add(BitmapFrame.Create(bmp)); 

using (MemoryStream sm = new MemoryStream()) 
{ 
    png.Save(sm); 
    return sm.ToArray(); 
}