天天看點

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生成的規則還不太清楚,好像隻有相同字型的内容都會分到一起。如下圖

wpf采用Xps實作文檔顯示、套打功能(原創)

3、檢視标記是否正确,可以先把xps文檔的字尾名修改一下,然後用winrar解壓,檢視解開目錄 \Documents\1\Pages\1.fpage ,用記事本打開,查找一下确定标簽是否正确。

如下圖:

wpf采用Xps實作文檔顯示、套打功能(原創)

其中X.fpage是指的第幾頁。

标簽的樣式如下:

wpf采用Xps實作文檔顯示、套打功能(原創)

請注意,這樣的解壓是單向的,處理前請備份。

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可能會有驚喜!

轉載于:https://www.cnblogs.com/lizhaoduo/p/3421089.html