与OfficeOpenXML.WordProcessing命名空间

时间:2015-12-28 23:02:26

标签: c# xml linq linq-to-xml openxml

我正在开发一个需要根据用户输入,数据库值和模板生成Word文档的应用程序。我在网上看了一些例子,并找到了许多不同的方法来生成word文档,但我已经下定决心并决定坚持使用官方Office Open XML SDK 2.5。现在我刚刚写了一个简单的程序,将一个表(存储在.xml文件中)插入到word文档中:

编辑: 如果对代码不感兴趣,请在底部提问

static void Main(string[] args)
{
XNamespace ns = XNamespace
    .Get(@"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
byte[] byteArray = File.ReadAllBytes(@"C:/Users/Alexander/Downloads/WordTest.docx");
using (var stream = new MemoryStream())
{
    XDocument xdoc;
    stream.Write(byteArray, 0, byteArray.Length);

    using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true))
    {

然后我可以做两件不同的事情,它们会产生相同的输出。

1)使用 OfficeOpenXml.Wordprocessing 命名空间方法:

#region Openxml.WordProcessing

var paragraphs = doc.MainDocumentPart.Document.Body.ToList();
Table tbl = new Table(File.ReadAllText(@"C:/users/alexander/downloads/tablecontent.xml"));
var bookmark = paragraphs.SelectMany(p => p.Descendants<BookmarkStart>()
                                           .Where(bm => bm.Id == "0")).FirstOrDefault();
doc.MainDocumentPart.Document.Body.ReplaceChild(tbl, bookmark.Parent);

#endregion Openxml.WordProcessing

2)使用 Linq-To-XML

#region LINQ TO XML

XElement xtbl = XElement.Load(
   new FileStream(@"C:/users/alexander/downloads/tablecontent.xml", FileMode.Open));

using (StreamReader sr = new StreamReader(doc.MainDocumentPart.GetStream()))
using (XmlReader xr = XmlReader.Create(sr))
    xdoc = XDocument.Load(xr);

//Document - Body - Paragraphs - Runs/Bookmarks/etc. 
//any way to write this more clearly in linq-to-xml?
var test = xdoc.Elements().First().Elements().First().Elements()
               .SelectMany(e => e.Elements()).ToList();

var startBookmark = test.Where(p => p.Name == XName.Get("bookmarkStart", ns.NamespaceName) 
                 && p.Attribute(XName.Get("id", ns.NamespaceName)).Value == "0").First();

startBookmark.Parent.ReplaceWith(xtbl);

using (XmlWriter xw = XmlWriter.Create(doc.MainDocumentPart.GetStream()))
            xdoc.Save(xw);

#endregion LINQ TO XML

最后我将文档写入新文件:

using (FileStream fs = 
    new FileStream(@"C:/users/alexander/downloads/WordTestModified.docx", FileMode.Create))
{
    stream.WriteTo(fs);
}

据我所知,第一个选项更简单,代码更清晰易读(不使用XName而无需额外StreamReader / XmlReader/Writer)但Linq-to-xml对这种方法有什么明显的优势吗?这将是一个很大的应用程序,我不想在以后受到限制。

0 个答案:

没有答案