近期的一個項目需對數據進行套打,用戶要求現場不允許安裝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可能會有驚喜!