Управление XML-документом Word 2007 в C # - PullRequest
4 голосов
/ 25 января 2011

Я пытаюсь манипулировать XML документа Word 2007 в C #.Мне удалось найти нужный узел и манипулировать им, но теперь я не могу понять, как его сохранить.Вот что я пытаюсь:

// 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();

Я получаю сообщение об ошибке «Поток памяти не расширяется».Есть идеи?

Ответы [ 5 ]

8 голосов
/ 26 января 2011

Я бы порекомендовал вам использовать Open XML SDK вместо взлома формата самостоятельно.

2 голосов
2 голосов
/ 26 января 2011

Используя 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).

Надеюсь, это поможет!

1 голос
/ 26 января 2011

Проблема, по-видимому, в doc.Save (partWrtr), который построен с использованием newPkgprtData, который построен с использованием pkgFile, который загружается из потока памяти ... Поскольку вы загружены из потока памяти, он пытается сохранить документ обратно в тот же поток памяти. Это приводит к ошибке, которую вы видите.

Вместо сохранения в потоке памяти попробуйте сохранить его в новом файле или в новом потоке памяти.

0 голосов
/ 15 декабря 2013

Короткий и простой ответ на вопрос о получении «Поток памяти не расширяется»: не открывайте документ из memoryStream.Поэтому в этом отношении предыдущий ответ верен, просто откройте файл.

Открытие из MemoryStream редактирования документа (по моему опыту) легко приводит к «Потоку памяти не расширяется».Я предполагаю, что сообщение появляется, когда кто-то делает редактирование, которое требует расширения памяти.Я обнаружил, что могу внести некоторые изменения, но не все, что увеличивает размер.Итак, удаление пользовательской части XML для f.ex - это нормально, но добавление одной и некоторых данных - нет.

Так что если вам действительно нужно открыть поток памяти, вы должны выяснить, как открыть расширяемую MemoryStream, если хотитедобавить к этому.Я нуждаюсь в этом и надеюсь найти решение.

Stein-Tore Erdal

PS: только что заметил ответ от "26 января '11 в 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...