2010-09-25 17 views

Respuesta

9

Me encontré con esta publicación de blog desde Josh Twist que parece hacer lo que quiere.

Cracking an XPS in WPF

En búsqueda de la red, hay muchos programas/juicio pagados que pretenden hacer esto (no he probado ninguno de ellos, así que no puedo dar fe/lista de cualquiera de ellos). Supuse que querías escribir tu propio código.

Aquí es la 'carne' de la entrada de blog (condensada):

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

Gracias mucho! Esto es exactamente lo que quería; ¡y lo he usado y funciona! ¡Gracias de nuevo! –

+0

Excelente, me alegro de que haya ayudado. –

+0

Gracias por esta solución. Uno pensaría que una operación relativamente directa sería mucho más fácil que este código bastante denso ... no es exactamente obvio. –

1

Por favor refiérase a la answer aceptado que es realmente útil (me ayudó también) .I sólo quiero señalar a algunos muy punto importante en esa solución.

si está implementando su propio DocumentPaginator (como en mi caso), entonces ese código no funcionará porque no vamos a conseguir referencia a su Paginator específica de la declaración

DocumentPaginator paginator = seq.DocumentPaginator; 

casting esto a su propia paginador también no trabajará.

también esa solución es muy compleja en caso de que tenga su propia Paginator.
Así que desarrollé una solución simplificada, que basada en la solución aceptada de esta pregunta, funcionó exactamente como era necesario.

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