65.9K
CodeProject 正在变化。 阅读更多。
Home

OpenXML + FlowDocument = OpenFlowDocument?

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (13投票s)

2008 年 4 月 9 日

CPOL

2分钟阅读

viewsIcon

94392

downloadIcon

2227

一篇关于如何通过解析 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 familysize 。然后我创建一个新的 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 中的显示效果

OpenFlowDocScreen.jpg

简单易用…

如果您喜欢这篇文章,请为它投票,并访问我的博客:http://dotnet.org.za/rudi

历史

  • 2008 年 4 月 9 日:初始发布
© . All rights reserved.