zoukankan      html  css  js  c++  java
  • wpf采用Xps实现文档显示、套打功能(原创)

    近期的一个项目需对数据进行套打,用户要求现场不允许安装office、页面预览显示必须要与文档完全一致,xps文档来对数据进行处理。Wpf的DocumentView 控件可以直接将数据进行显示,xps也是一种开放式的文档,如果我们能够替换里面的标签就最终实现了我们想要的效果。

    推荐两篇关于xps的文档介绍

    http://www.microsoft.com/china/MSDN/library/Windev/WindowsVista/0601XMLPaperSpecification.mspx

    http://technet.microsoft.com/zh-cn/ms771722(fr-fr,VS.85).aspx

    废话不多说,上代码

          

       private void setPage()
    
            {
    
                string xpsFile = "d:\test.xps";//读取模板
    
                XpsDocument xpsDoc = new XpsDocument(xpsFile, FileAccess.Read);
    
                FixedDocumentSequence fds = xpsDoc.GetFixedDocumentSequence();
    
                foreach (DocumentReference DocRef in fds.References)
    
                {
    
                    bool bForceReload = false;
    
                    FixedDocument DocFd = DocRef.GetDocument(bForceReload);
    
                    foreach (PageContent DocFpPc in DocFd.Pages)
    
                    {
    
                        FixedPage DocFp = DocFpPc.GetPageRoot(bForceReload);
    
                        Canvas containCanvas = new Canvas(); //在页面上画一个大的图层
    
                        containCanvas.Width = DocFp.Width;
    
                        containCanvas.Height = DocFp.Height;
    
                        containCanvas.Background = Brushes.Transparent;//设置透明色
    
                        #region MyRegion
    
     
    
                        for (int i = 0; i < DocFp.Children.Count; i++)
    
                        {
    
                         
    
                            UIElement DocFpUiElem = DocFp.Children[i];
    
                            if (DocFpUiElem is Glyphs)
    
                            {
    
                                Glyphs gps = (Glyphs)DocFpUiElem;
    
                                string strMark = gps.UnicodeString;
    
     
    
                                if (strMark=="{1}")//判定当前数据是否为标签
    
                                {
    
                                   
    
                                    double x = gps.OriginX;
    
                                    double y = gps.OriginY;
    
                                    double fontSize = gps.FontRenderingEmSize;
    
                                    strMark = strMark.Replace("{", "").Replace("}", "");
    
     
    
                                    DocFp.Children.RemoveAt(i);//移除标签
    
                                   
    
                                    TextBlock label = new TextBlock();
    
                                    Canvas.SetLeft(label, x);
    
                                    Canvas.SetTop(label, y - fontSize);
    
                                    Canvas.SetZIndex(label, 99);
    
                                    label.Foreground = Brushes.Red;
    
                                    label.FontFamily = new System.Windows.Media.FontFamily("宋体");
    
                                    label.FontSize = fontSize;
    
                                    label.Text = "你的内容";
    
                                    containCanvas.Children.Add(label);
    
                                }
    
                            }
    
                        }
    
                        #endregion
    
     
    
                        DocFp.Children.Add(containCanvas);//将画布添加到页面上
    
                        ((IAddChild)DocFpPc).AddChild(DocFp);
    
                    }
    
                }
    
                this.docView.Document = fds;
    
                xpsDoc.Close();//这个地方需要注意关闭,否则的话会出现莫名其妙的错误
    
            }
    
     

    处理过程中的几点注意事项:

    1、关于xps文档的生成,我是采用的word2010,然后使用打印功能生成的xps文档。

     

    2、关于标签的设置:如果在word 中你直接写{@Name }  的话,在页面中未必能够按照你的想法生成标签。我用的方法是,对于同一行、相邻的标签,需要用不同的颜色来进行标记。标记的颜色也要与正文的颜色区分开,关于xps生成的规则还不太清楚,好像只有相同字体的内容都会分到一起。如下图

     

    3、查看标记是否正确,可以先把xps文档的后缀名修改一下,然后用winrar解压,查看解开目录 Documents1Pages1.fpage ,用记事本打开,查找一下确定标签是否正确。

    如下图:

    其中X.fpage是指的第几页。

    标签的样式如下:

    请注意,这样的解压是单向的,处理前请备份。

    4、需要引用的dll文件:

    WindowsBase.dll  PresentationCore.dll   ReachFramework.dll  PresentationFramework.dll  ,(部分文件在wpf中已经被引用了),光确定用需要引用那些文件都折腾了我半天,丢人啊。

    经过最近几天的折腾,我认为这种方法的优点:

    1、纯矢量绘图,无失真,模板上面随意画。

    2、xps模板一旦做好了,交付用户,用户一般无法自己进行修改,比较简单方便。

    3、不需要安装任何第三方插件。

    4、任何元素,想加就加,完全可以画图、添加水印等

    5、字体不会丢失,xps文件在打包的时候,会一并将字体打包进项目里面,不管安装到任何地方,都不需要考虑字体问题

     代码下载:http://download.csdn.net/detail/bcc222/6546761

    另外,在处理模板的时候,如果使用wps212可能会有惊喜!

  • 相关阅读:
    [ZJOI2011]营救皮卡丘
    TJOI2018Party
    HEOI2013SAO
    [BJOI2017]树的难题
    [HNOI2016]序列
    [SHOI2007]善意的投票
    CF802C Heidi and Library (hard)
    SPOJ DIVCNT2
    LOJ子序列
    BZOJ2882工艺
  • 原文地址:https://www.cnblogs.com/lizhaoduo/p/3421089.html
Copyright © 2011-2022 走看看