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