2010-09-25 7 views

Odpowiedz

9

Przebiegłem ten wpis na blogu od Josh Twist, który wydaje się robić to, co chcesz.

Cracking an XPS in WPF

Na przeszukiwania sieci, istnieje wiele płatnych programów/próby, które twierdzą, aby to zrobić (nie próbowałem żadnej z nich, więc nie mogę ręczyć/wymienić żadnego z nich). Zakładałem, że chcesz napisać własny kod.

Oto „mięso” z blogu (skrócone):

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

Dziękuję bardzo! Dokładnie tego chciałem; i użyłem go i działa! Dzięki jeszcze raz! –

+0

Wspaniale, cieszę się, że pomogło. –

+0

Dzięki za to rozwiązanie. Można by pomyśleć, że stosunkowo prosta operacja byłaby dużo łatwiejsza niż ten dość gęsty kod ... nie jest to dokładnie oczywiste. –

1

Proszę odnieść się do przyjętego answer to jest naprawdę pomocny (pomógł mi też) .I po prostu chcą zwrócić uwagę na kilka bardzo ważny punkt w tym rozwiązaniu.

jeśli wdrażają własne DocumentPaginator (jak w moim przypadku), a następnie, że kod nie będzie działać, ponieważ nie będzie odniesienie do konkretnego paginator z rachunku

DocumentPaginator paginator = seq.DocumentPaginator; 

Casting to na swój paginator także nie będzie działać.

również to rozwiązanie jest bardzo skomplikowane, jeśli masz własny Paginator.
Opracowałem więc uproszczone rozwiązanie, które opierało się na przyjętym rozwiązaniu tego pytania i działało dokładnie tak, jak było to konieczne.

// 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(); 
} 
Powiązane problemy