讀取XPS格式文件或將doc,txt文件轉化爲XPS文件,效果圖以下:html
1.XAML頁面代碼:node
<Window x:Class="WpfWord.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WordReader" Height="500" Width="900"> <Grid> <Grid.RowDefinitions> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="0" Name="cdTree"/> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="3*"/> </Grid.ColumnDefinitions> <GroupBox Header="導航目錄"> <TreeView Name="tvTree" SelectedItemChanged="tvTree_SelectedItemChanged"/> </GroupBox> <GridSplitter Width="3" ResizeBehavior="PreviousAndNext" Grid.Column="1" Background="LightGray"/> <Grid Grid.Column="3"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <DocumentViewer Name="dvShow" Grid.Row="1"/> <StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Right"> <CheckBox Content="顯示導航" Height="16" Margin="5" Name="cbNav" Width="75" Click="cbNav_Click" /> <Label Content="頁面"/> <Label Name="lblCurPage" Margin="0"/> <Label Name="lblPage"/> <Button Content="上一頁" Height="23" Name="btnPrev" Width="75" Click="btnPrev_Click" /> <Button Content="下一頁" Height="23" Name="btnNext" Width="75" Click="btnNext_Click" /> <Label Content="總字數:" Name="lblWordCount"/> </StackPanel> </Grid> </Grid> </Window>
2.後臺CS文件代碼:函數
首先引用Microsoft.Office.Interop.Word.dll; //具體代碼以下↓ using System; using System.IO; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Xps.Packaging; using System.Xml; using Microsoft.Office.Interop.Word; namespace WpfWord { /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : System.Windows.Window { #region 全局變量 /// <summary> /// 用於存放目錄文檔各節點OutlineLevel值,並轉化爲int型 /// </summary> int[] array = null; /// <summary> /// 用於存放目錄文檔各節點OutlineLevel值 /// </summary> string[] array1 = null; /// <summary> /// 用於存放目錄文檔各節點Description值,章節信息 /// </summary> string[] arrayName = null; /// <summary> /// 用於存放目錄文檔各節點OutlineTarget值,頁碼信息 /// </summary> string[] pages = null; #endregion public MainWindow() { InitializeComponent(); OpenFile(null); } /// <summary> /// 構造函數 /// </summary> /// <param name="strFilePath">文件路徑</param> public MainWindow(string strFilePath) : this() { } #region 方法 /// <summary> /// 讀取導航目錄 /// </summary> private void ReadDoc(XpsDocument xpsDoc) { IXpsFixedDocumentSequenceReader docSeq = xpsDoc.FixedDocumentSequenceReader; IXpsFixedDocumentReader docReader = docSeq.FixedDocuments[0]; XpsStructure xpsStructure = docReader.DocumentStructure; Stream stream = xpsStructure.GetStream(); XmlDocument doc = new XmlDocument(); doc.Load(stream); //獲取節點列表 XmlNodeList nodeList = doc.ChildNodes.Item(0).FirstChild.FirstChild.ChildNodes; if (nodeList.Count <= 0)//判斷是否存在目錄節點 { //tvTree.Visibility = System.Windows.Visibility.Hidden; tvTree.Items.Add(new TreeViewItem { Header = "沒有導航目錄" }); return; } tvTree.Visibility = System.Windows.Visibility.Visible; array = new int[nodeList.Count]; array1 = new string[nodeList.Count]; arrayName = new string[nodeList.Count]; pages = new string[nodeList.Count]; for (int i = 0; i < nodeList.Count; i++) { array[i] = Convert.ToInt32(nodeList[i].Attributes["OutlineLevel"].Value); array1[i] = nodeList[i].Attributes["OutlineLevel"].Value.ToString(); arrayName[i] = nodeList[i].Attributes["Description"].Value.ToString(); pages[i] = nodeList[i].Attributes["OutlineTarget"].Value.ToString(); } for (int i = 0; i < array.Length - 1; i++) { //對array進行轉換組裝成可讀的樹形結構,經過ASCII值進行增長、轉換 array1[0] = "A"; if (array[i + 1] - array[i] == 1) { array1[i + 1] = array1[i] + 'A'; } if (array[i + 1] == array[i]) { char s = Convert.ToChar(array1[i].Substring((array1[i].Length - 1), 1)); array1[i + 1] = array1[i].Substring(0, array1[i].Length - 1) + (char)(s + 1); } if (array[i + 1] < array[i]) { int m = array[i + 1]; char s = Convert.ToChar(array1[i].Substring(0, m).Substring(m - 1, 1)); array1[i + 1] = array1[i].Substring(0, m - 1) + (char)(s + 1); } } //添加一個節點做爲根節點 TreeViewItem parent = new TreeViewItem(); TreeViewItem parent1 = null; parent.Header = "目錄導航"; Boolean flag = false; for (int i = 0; i < array.Length; i++) { if (array[i] == 1) { flag = true; } if (flag) //若是找到實際根節點,加載樹 { parent1 = new TreeViewItem(); parent1.Header = arrayName[i]; parent1.Tag = array1[i]; parent.Items.Add(parent1); parent.IsExpanded = true; parent1.IsExpanded = true; FillTree(parent1, array1, arrayName); flag = false; } } tvTree.Items.Clear(); tvTree.Items.Add(parent); } /// <summary> /// 填充樹的方法 /// </summary> /// <param name="parentItem"></param> /// <param name="str1"></param> /// <param name="str2"></param> public void FillTree(TreeViewItem parentItem, string[] str1, string[] str2) { string parentID = parentItem.Tag as string; for (int i = 0; i < str1.Length; i++) { if (str1[i].IndexOf(parentID) == 0 && str1[i].Length == (parentID.Length + 1) && str1[i].ElementAt(0).Equals(parentID.ElementAt(0))) { TreeViewItem childItem = new TreeViewItem(); childItem.Header = str2[i]; childItem.Tag = str1[i]; parentItem.Items.Add(childItem); FillTree(childItem, str1, str2); } } } /// <summary> /// 打開文件-若是傳入路徑爲空則在此打開選擇文件對話框 /// </summary> /// <param name="strFilepath">傳入文件全路徑</param> private void OpenFile(string strFilepath) { if (string.IsNullOrEmpty(strFilepath)) { Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog(); openFileDialog.DefaultExt = ".doc|.txt|.xps"; openFileDialog.Filter = "*(.xps)|*.xps|Word documents (.doc)|*.doc|Word(2007-2010)(.docx)|*.docx|*(.txt)|*.txt"; Nullable<bool> result = openFileDialog.ShowDialog(); strFilepath = openFileDialog.FileName; if (result != true) { return; } } this.Title = strFilepath.Substring(strFilepath.LastIndexOf("\\")+1); if (strFilepath.Length > 0) { XpsDocument xpsDoc = null; //若是是xps文件直接打開,不然需轉換格式 if (!strFilepath.EndsWith(".xps")) { string newXPSdocName = String.Concat(System.IO.Path.GetDirectoryName(strFilepath), "\\", System.IO.Path.GetFileNameWithoutExtension(strFilepath), ".xps"); xpsDoc = ConvertWordToXPS(strFilepath, newXPSdocName); } else { xpsDoc = new XpsDocument(strFilepath, System.IO.FileAccess.Read); } if (xpsDoc != null) { dvShow.Document = xpsDoc.GetFixedDocumentSequence(); //讀取文檔目錄 ReadDoc(xpsDoc); xpsDoc.Close(); } this.lblCurPage.Content = 0; this.lblPage.Content = "/" + dvShow.PageCount; } } /// <summary> /// 將word文檔轉換爲xps文檔 /// </summary> /// <param name="wordDocName">word文檔全路徑</param> /// <param name="xpsDocName">xps文檔全路徑</param> /// <returns></returns> private XpsDocument ConvertWordToXPS(string wordDocName, string xpsDocName) { XpsDocument result = null; //建立一個word文檔,並將要轉換的文檔添加到新建立的對象 Microsoft.Office.Interop.Word.Application wordApplication = new Microsoft.Office.Interop.Word.Application(); try { wordApplication.Documents.Add(wordDocName); Document doc = wordApplication.ActiveDocument; doc.ExportAsFixedFormat(xpsDocName, WdExportFormat.wdExportFormatXPS, false, WdExportOptimizeFor.wdExportOptimizeForPrint, WdExportRange.wdExportAllDocument, 0, 0, WdExportItem.wdExportDocumentContent, true, true, WdExportCreateBookmarks.wdExportCreateHeadingBookmarks, true, true, false, Type.Missing); result = new XpsDocument(xpsDocName, System.IO.FileAccess.ReadWrite); } catch (Exception ex) { string error = ex.Message; wordApplication.Quit(WdSaveOptions.wdDoNotSaveChanges); } wordApplication.Quit(WdSaveOptions.wdDoNotSaveChanges); return result; } #endregion /// <summary> /// 導航樹跳轉事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void tvTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) { int x = 0; TreeViewItem selectTV = this.tvTree.SelectedItem as TreeViewItem; if (null == selectTV) return; if (null == selectTV.Tag) return; string page = selectTV.Tag.ToString(); for (int i = 0; i < array1.Length; i++) { if (array1[i].Equals(page)) { x = i; } } string[] strPages = pages[x].Split('_'); dvShow.GoToPage(Int32.Parse(strPages[1])); } private void cbNav_Click(object sender, RoutedEventArgs e) { this.cdTree.Width = this.cbNav.IsChecked == true ? new GridLength(300) : new GridLength(0); } private void btnPrev_Click(object sender, RoutedEventArgs e) { this.dvShow.PreviousPage(); } private void btnNext_Click(object sender, RoutedEventArgs e) { this.dvShow.NextPage(); } } }