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解壓,查看解開目錄 \Documents\1\Pages\1.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可能會有驚喜!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM