如何创建XPS文档?

20

我想创建一个用于存储和打印的XPS文档。

如何在我的程序中最简单地创建一个XPS文档(例如,带有一些数据的简单网格),并将其传递给其他人?


这可能也会有帮助:[http://blogs.msdn.com/fyuan/archive/2005/09/12/463887.aspx] (http://blogs.msdn.com/fyuan/archive/2005/09/12/463887.aspx) - noesgard
3个回答

15

这并不容易,但是可以完成。我在我的博客上为创建内存中的文档提供了一些(可悲的是仍然有漏洞)示例代码和信息。

下面是我编写的用于测试的代码,它封装了所有内容(将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;
}

注意糟糕的线程代码。在多线程单元中无法执行此操作;如果您在单线程单元上,则可以将其去除。

2
有趣的线程超时代码- 你为什么不直接使用t.Join(5000)呢?我还在努力理解其余部分 :) - Sam
2
我尝试了这段代码,但是出现错误:参数是意外类型的 'System.String'。期望的类型是 'System.Windows.Documents.FixedPage'。参数名称: 值在行 ((IAddChild)pc).AddChild(fp);。我该如何解决这个问题? - Sudha
4
@Sudha 是的,这时候有一个程序员会很方便。我建议你雇一个。 - user1228
@Will 抱歉..我没听懂你的意思..你是做什么类型的程序员? - Sudha
这段代码的某些部分对我解决问题有很大帮助。谢谢! - krflol
显示剩余5条评论

7

如果您正在使用.NET(v2或更高版本),则可以非常轻松地从WPF可视化对象生成有效的XPS文档。

例如,请参阅我的这篇博客文章:

http://nixps.blogspot.com/2008/12/wpf-to-pdf.html

在这个例子中,我创建了一个WPF可视化对象并将其转换为XPS文件,然后再进行进一步处理。
如果您不是在.NET上工作,或者想要更多地控制XPS输出,则建议使用库(如NiXPS SDK)。这样编码会更容易,并且比自己编写XML结构(以及进行适当的资源管理等...)更少出错。

1
你的博客链接无法访问,或许你可以在回答中复制代码示例? - Sam
复制并粘贴URL,而不是跟随它,因为href链接有误。它完美地展示了如何从WPF可视化对象创建XPS文件。 - Kristof Van Landschoot
直到.NET Framework 3.0(随Windows Vista一起发布),WPF(Windows Presentation Foundation)才被推出。 - Ian Boyd
注意:NiXPS SDK 是需要付费的(目前最便宜的套餐价格为750欧元)。 - itsho
目前NiXPS似乎已经死亡。主页http://nixps.com/显示为空白页面,并且最后一次更新新闻是在2010年(http://www.nixps.com/news.php?id=1)。 - Patrick D'Souza

0

其实,它就是XML。如果您熟悉使用XML文件,那么使用XPS文档应该不会有任何问题。以下是我过去使用的简单教程,可以帮助您入门:

http://blogs.ocrasoft.nl/jeroenveurink/?p=21


很奇怪,但这确实是一种方法。我不建议您这样做,除非您了解XPS文档规范。 - user1228
创建一个奇怪的XML文档,压缩成zip文件?这不是我写“最简单的方法”时想到的 :) - Sam
这个教程还能在其他地方找到吗?博客已经不存在了,但我很感兴趣... - Mladen Mihajlovic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接