当前位置:  开发笔记 > 编程语言 > 正文

如何创建XPS文档?

如何解决《如何创建XPS文档?》经验,为你挑选了2个好方法。

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

在我的程序中创建XPS文档的最简单方法是什么(例如,在其中包含一些带有一些数据的简单网格),并传递它?



1> 小智..:

没什么好吃的.但这是可以完成的.我在我的博客上有一些(遗憾的,仍然是错误的)示例代码和信息,用于在内存中创建文档.

这是我为测试而编写的一些代码封装了所有内容(它将一组FixedPages写入内存中的XPS文档).它包含用于将文档序列化为字节数组的代码,但您可以跳过该部分并返回文档:

public static byte[] ToXpsDocument(IEnumerable 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线程上,你也可以摆脱它.


@Sudha是的,这是一个程序员方便的时候.我建议你雇一个.
有趣的线程超时代码 - 你不是只使用t.Join(5000)的任何原因吗?我还在努力理解其余的:)
我尝试了这段代码并得到错误:参数是意外类型'System.String'.预期的类型是'System.Windows.Documents.FixedPage'.参数名称:行中的值((IAddChild)pc).AddChild(fp); 我该如何解决这个问题?

2> nixps..:

如果您使用的是.NET(v2或更高版本),则可以从WPF visual中轻松生成有效的XPS文档.

举个例子,看一下我的博文:

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

在示例中,我创建了一个WPF visual并将其转换为XPS文件,然后再进行进一步处理.

如果您不在.NET中工作,或者想要更多地控制XPS输出,那么我建议您使用库(如NiXPS SDK).编写代码要容易得多,并且比自己编写XML构造(并进行适当的资源管理等等)更不容易出错.

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有