我想创建一个用于存储和打印的XPS文档。
在我的程序中创建XPS文档(例如,包含一些数据的简单网格)并传递它的最简单方法是什么?
发布于 2008-12-09 12:11:41
这不是一件容易的事。但这是可以做到的。我在我的博客上有一些(遗憾的是,仍然有blog )示例代码和信息,用于在内存中创建文档。
下面是我为测试准备的一些代码,这些代码封装了所有内容(它将一组FixedPages写入内存中的XPS文档)。它包含将文档序列化为字节数组的代码,但您可以跳过该部分,只返回文档:
public static byte[] ToXpsDocument(IEnumerable<FixedPage> pages)
{
// XPS DOCUMENTS MUST BE CREATED ON STA THREADS!!!
// Note, this is test code, so I don't care about disposing my memory streams
// You'll have to pay more attention to their lifespan. You might have to
// serialize the xps document and remove the package from the package store
// before disposing the stream in order to prevent throwing exceptions
byte[] retval = null;
Thread t = new Thread(new ThreadStart(() =>
{
// A memory stream backs our document
MemoryStream ms = new MemoryStream(2048);
// a package contains all parts of the document
Package p = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
// the package store manages packages
Uri u = new Uri("pack://TemporaryPackageUri.xps");
PackageStore.AddPackage(u, p);
// the document uses our package for storage
XpsDocument doc = new XpsDocument(p, CompressionOption.NotCompressed, u.AbsoluteUri);
// An xps document is one or more FixedDocuments containing FixedPages
FixedDocument fDoc = new FixedDocument();
PageContent pc;
foreach (var fp in pages)
{
// this part of the framework is weak and hopefully will be fixed in 4.0
pc = new PageContent();
((IAddChild)pc).AddChild(fp);
fDoc.Pages.Add(pc);
}
// we use the writer to write the fixed document to the xps document
XpsDocumentWriter writer;
writer = XpsDocument.CreateXpsDocumentWriter(doc);
// The paginator controls page breaks during the writing process
// its important since xps document content does not flow
writer.Write(fDoc.DocumentPaginator);
//
p.Flush();
// this part serializes the doc to a stream so we can get the bytes
ms = new MemoryStream();
var writer = new XpsSerializerFactory().CreateSerializerWriter(ms);
writer.Write(doc.GetFixedDocumentSequence());
retval = ms.ToArray();
}));
// Instantiating WPF controls on a MTA thread throws exceptions
t.SetApartmentState(ApartmentState.STA);
// adjust as needed
t.Priority = ThreadPriority.AboveNormal;
t.IsBackground = false;
t.Start();
//~five seconds to finish or we bail
int milli = 0;
while (buffer == null && milli++ < 5000)
Thread.Sleep(1);
//Ditch the thread
if(t.IsAlive)
t.Abort();
// If we time out, we return null.
return retval;
}注意糟糕的线程代码。你不能在MTA线程上这样做;如果你在STA线程上,你也可以摆脱它。
发布于 2008-12-09 14:05:37
如果您使用的是.NET (v2或更高版本),则可以非常容易地从WPF visual生成有效的。
举个例子,看看我的这篇博文:
http://nixps.blogspot.com/2008/12/wpf-to-pdf.html
在本例中,我创建了一个WPF可视化文件,并将其转换为XPS文件,然后再进行进一步的处理。
如果您不是在.NET中工作,或者想要更好地控制XPS输出,那么我建议您使用一个库(比如NiXPS SDK)来实现这一点。与自己编写XML结构(以及进行适当的资源管理等)相比,它的编码要容易得多,错误的可能性也要小得多。
发布于 2008-12-09 12:10:44
它就是真正的XML。如果您习惯于使用XML文件,那么使用XPS文档应该没有问题。这是我过去用过的一个简单的教程,让我开始:
http://blogs.ocrasoft.nl/jeroenveurink/?p=21
https://stackoverflow.com/questions/352540
复制相似问题