OpenXML + FlowDocument = OpenFlowDocument?






4.74/5 (13投票s)
一篇关于如何通过解析 XLINQ 的 OpenXML WordML 来在 WPF FlowDocument 控件中渲染 Word 文档的文章。
引言
OpenXML 是微软所有新 Office 套件(Office 2007!)使用的新的标准!因为它是一个开放标准并且基于 XML,我们可以轻松解析使用这些产品创建的文档。本文的主题是如何解析 Word 文档(使用 XLINQ),然后在 WPF 控件中呈现该文档,该控件称为 FlowDocument
!
使用 XLINQ 解析 OpenXML 文档
System.IO.Packaging
第一个问题是将 *.docx 文件提取或解压缩到其包含的 *.xml 文件中。
Package package = Package.Open(filename);
Uri documentUri = new Uri("/word/document.xml", UriKind.Relative);
PackagePart documentPart = package.GetPart(documentUri);
XElement wordDoc = XElement.Load(new StreamReader(documentPart.GetStream()));
上面的代码片段打开一个 Word 文档,并将 document.xml 提取到一个 XElement
中。
使用 XLINQ 获取所有段落
所有 Word 文档都需要 WordML 命名空间
XNamespace w = http://schemas.openxmlformats.org/wordprocessingml/2006/main;
现在我们可以编写一个简单的 XLINQ 查询来获取所有段落(请注意:为了简单起见,我仅查看 paragraphs
,忽略图像、绘图、表格等)。
var paragraphs = from p in wordDoc.Descendants(w + "p")
select p;
接下来,我们遍历 paragraphs
集合,并在 FlowDocument
中显示它们!
FlowDocument
Sacha 在 这里 有一篇关于 FlowDocument
基本知识的好文章!
foreach (var p in paragraphs)
{
var style = from s in p.Descendants(w + "pPr")
select s;
var font = (from f in style.Descendants(w + "rFonts")
select f.FirstAttribute).FirstOrDefault();
var size = (from s in style.Descendants(w + "sz")
select s.FirstAttribute).FirstOrDefault();
Paragraph par = new Paragraph();
Run r = new Run(p.Value);
if (font != null)
{
FontFamilyConverter converter = new FontFamilyConverter();
r.FontFamily = (FontFamily)converter.ConvertFrom(font.Value);
}
if (size != null)
{
r.FontSize = double.Parse(size.Value);
}
par.Inlines.Add(r);
flowDoc.Blocks.Add(par);
}
对于每个 paragraph
,我检查它是否显式设置了 font family
或 size
。然后我创建一个新的 Paragraph
,并将一个 Run
添加到它的 Inlines
集合中(如果可用,我还会更改 font family
和 size
)。然后我将 Paragraph
添加到我的 FlowDocument
中!
就这样了!
现在剩下的就是找到一种很酷的方法来扩展正常的 FlowDocument
以支持 Word 文档?你可以对 FlowDocument
进行子类化……我决定将其作为扩展方法提供!
要将 Word 文档加载到 flow document 中,首先创建一个 FlowDocumentViewer
(我在 XAML 中创建了它)
<FlowDocumentPageViewer x:Name="flowDocViewer" Zoom="80" />
然后加载 Word 文档…
FlowDocument flowDoc = new FlowDocument();
flowDoc.loadWordML("DisciplesBios.docx");
flowDocViewer.Document = flowDoc;
我创建了一个包含所有 WPF Disciples 简介的简单的 Word 文档。以下是它在 FlowDocument
中的显示效果

简单易用…
如果您喜欢这篇文章,请为它投票,并访问我的博客:http://dotnet.org.za/rudi
历史
- 2008 年 4 月 9 日:初始发布