簡體   English   中英

在C#中操作Word 2007文檔XML

[英]Manipulating Word 2007 Document XML in C#

我試圖在C#中操縱Word 2007文檔的XML。 我已經設法找到並操縱了我想要的節點,但現在我似乎無法弄清楚如何將其保存回來。 這是我正在嘗試的:

// Open the document  from memoryStream
Package pkgFile = Package.Open(memoryStream, FileMode.Open, FileAccess.ReadWrite);
PackageRelationshipCollection pkgrcOfficeDocument = pkgFile.GetRelationshipsByType(strRelRoot);

foreach (PackageRelationship pkgr in pkgrcOfficeDocument)
{
    if (pkgr.SourceUri.OriginalString == "/")
    {
        Uri uriData = new Uri("/word/document.xml", UriKind.Relative);

        PackagePart pkgprtData = pkgFile.GetPart(uriData);

        XmlDocument doc = new XmlDocument();
        doc.Load(pkgprtData.GetStream());

        NameTable nt = new NameTable();
        XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
        nsManager.AddNamespace("w", nsUri);

        XmlNodeList nodes = doc.SelectNodes("//w:body/w:p/w:r/w:t", nsManager);

        foreach (XmlNode node in nodes)
        {
            if (node.InnerText == "{{TextToChange}}")
            {
                node.InnerText = "success";
            }
        }


        if (pkgFile.PartExists(uriData))
        {
            // Delete template "/customXML/item1.xml" part
            pkgFile.DeletePart(uriData);
        }
        PackagePart newPkgprtData = pkgFile.CreatePart(uriData, "application/xml");
        StreamWriter partWrtr = new StreamWriter(newPkgprtData.GetStream(FileMode.Create, FileAccess.Write));

        doc.Save(partWrtr);
        partWrtr.Close();
    }
}   

pkgFile.Close();

我收到錯誤'內存流不可擴展'。 有任何想法嗎?

我建議您使用Open XML SDK而不是自己破解格式。

使用OpenXML SDK 2.0,我這樣做:

public void SearchAndReplace(Dictionary<string, string> tokens)
{
    using (WordprocessingDocument doc = WordprocessingDocument.Open(_filename, true))
        ProcessDocument(doc, tokens);
}

private string GetPartAsString(OpenXmlPart part)
{
    string text = String.Empty;
    using (StreamReader sr = new StreamReader(part.GetStream()))
    {
        text = sr.ReadToEnd();
    }
    return text;
}

private void SavePart(OpenXmlPart part, string text)
{
    using (StreamWriter sw = new StreamWriter(part.GetStream(FileMode.Create)))
    {
        sw.Write(text);
    }
}

private void ProcessDocument(WordprocessingDocument doc, Dictionary<string, string> tokenDict)
{
    ProcessPart(doc.MainDocumentPart, tokenDict);
    foreach (var part in doc.MainDocumentPart.HeaderParts)
    {
        ProcessPart(part, tokenDict);
    }
    foreach (var part in doc.MainDocumentPart.FooterParts)
    {
        ProcessPart(part, tokenDict);
    }
}

private void ProcessPart(OpenXmlPart part, Dictionary<string, string> tokenDict)
{
    string docText = GetPartAsString(part);

    foreach (var keyval in tokenDict)
    {
        Regex expr = new Regex(_starttag + keyval.Key + _endtag);
        docText = expr.Replace(docText, keyval.Value);
    }

    SavePart(part, docText);
}

從這里你可以編寫一個GetPartAsXmlDocument,用它做你想做的事情,然后用SavePart(part,xmlString)將它流回來。

希望這可以幫助!

問題似乎是doc.Save(partWrtr),它是使用newPkgprtData構建的,它是使用pkgFile構建的,它從內存流加載...因為你從內存流加載它試圖將文檔保存回原來的記憶流。 這會導致您看到的錯誤。

不要將其保存到內存流,而是嘗試將其保存到新文件或新內存流中。

獲取“內存流不可擴展”的問題的簡短答案是:不要從memoryStream打開文檔。 所以在這方面,早期的答案是正確的,只需打開一個文件。

從MemoryStream打開編輯文檔(根據我的經驗)容易導致'內存流不可擴展'。 我想當一個編輯需要內存流擴展時會出現該消息。 我發現我可以做一些編輯但不能增加任何尺寸。 因此,f.ex刪除自定義xml部分是正常的,但添加一個和一些數據不是。

因此,如果您確實需要打開內存流,則必須弄清楚如何添加可擴展的MemoryStream。 我需要這個,希望找到一個解決方案。

Stein-Tore Erdal

PS:剛剛注意到“2011年1月26日15:18”的回答。 不要認為這是所有情況下的答案。 我在嘗試這個時遇到錯誤:

     var ms = new MemoryStream(bytes);
     using (WordprocessingDocument wd = WordprocessingDocument.Open(ms, true))
     {
        ...
        using (MemoryStream msData = new MemoryStream())
        {
           xdoc.Save(msData);
           msData.Position = 0;
           ourCxp.FeedData(msData); // Memory stream is not expandable.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM