2010-09-25 27 views

Répondre

9

J'ai couru à travers ce blog de Josh Twist qui semble faire ce que vous voulez.

Cracking an XPS in WPF

sur la recherche sur le net, il y a beaucoup de programmes payés/d'essai qui prétendent le faire (je n'ai pas essayé l'un d'eux, donc je ne peux pas se porter garant/liste l'un d'eux). Je suppose que vous voulez écrire votre propre code.

Voici la « viande » du billet de blog (condensé):

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

Merci beaucoup! C'est exactement ce que je voulais; et je l'ai utilisé et ça marche! Merci encore! –

+0

Excellent, content que cela a aidé. –

+0

Merci pour cette solution. On pourrait penser qu'une opération relativement simple serait beaucoup plus facile que ce code assez dense ... ce n'est pas tout à fait évident. –

1

S'il vous plaît se référer au accepté answer il est vraiment utile (il m'a aidé aussi) .Je veux juste noter une certaine très point important dans cette solution.

si vous implémentez votre propre DocumentPaginator (comme dans mon cas), alors que le code ne fonctionnera pas parce que nous ne se référence à votre Paginator spécifique de la déclaration

DocumentPaginator paginator = seq.DocumentPaginator; 

casting ceci à votre propre paginator aussi ne fonctionnera pas.

également cette solution est très complexe dans le cas où vous avez votre propre Paginator.
J'ai donc développé une solution simplifiée, basée sur la solution acceptée de cette question et qui a fonctionné exactement selon les besoins.

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