Откройте xml замените текст из файла word и верните поток памяти с помощью MVC



У меня есть файл word, который содержит мой указанный текст шаблона {pattern}, и я хочу заменить этот шаблон новой моей строкой, которая была прочитана из базы данных. Поэтому я использовал open xml read stream из моего файла шаблона docx замените мою строку шаблона, а затем вернитесь в поток, который поддерживает загрузку файла без создания временного файла. Но когда я открыл его сгенерировал мне ошибку на файле docx. Ниже приведен мой пример кода



public ActionResult SearchAndReplace(string FilePath)
{
MemoryStream mem = new MemoryStream(System.IO.File.ReadAllBytes(FilePath));
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(mem, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}

Regex regexText = new Regex("Hello world!");
docText = regexText.Replace(docText, "Hi Everyone!");

//Instead using this code below to write text back the original file. I write new string back to memory stream and return to a stream download file
//using (StreamWriter sw = new //StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
//{
// sw.Write(docText);
//}

using (StreamWriter sw = new StreamWriter(mem))
{
sw.Write(docText);
}
}
mem.Seek(0, SeekOrigin.Begin);

return File(mem, "application/octet-stream","download.docx"); //Return to download file
}


Пожалуйста, предложите мне какие-либо решения вместо того, чтобы читать текст из файл word и заменить те, которые ожидаются шаблон текста, а затем записать данные обратно в исходный файл. Существуют ли какие-либо решения заменить текст на wordprocessingdocument libary? Как я могу вернуться в поток памяти с проверкой формата файлов docx?

574   3  

3 ответов:

Подход, который вы принимаете, не является правильным. Если случайно шаблон, который вы ищете, совпадает с некоторой разметкой Open XML, вы повредите документ. Если текст, который вы ищете, разбит на несколько запусков, ваш код поиска / замены не найдет текст и не будет работать правильно. Если вы хотите найти и заменить текст в документе WordprocessingML, существует довольно простой алгоритм, который вы можете использовать:

  • разбить все прогоны на прогоны одного характер. Этот включает в себя запуски, которые имеют специальные символы, такие как разрыв строки, возврат каретки или жесткий вкладка.
  • тогда довольно легко найти набор запусков, соответствующих символам в строке поиска.
  • После того, как вы определили набор запусков, которые соответствуют, затем вы можете заменить этот набор запусков с недавно созданным запуском (который имеет свойства выполнения запуска содержащий первый символ, который соответствует строке поиска).
  • после замены односимвольных запусков с новым созданный бег, вы можете затем закрепить соседними работает с одинаковое форматирование.

Я написал сообщение в блоге и записал сценарий, который проходит через этот алгоритм.

Блоге: http://openxmldeveloper.org/archive/2011/05/12/148357.aspx
Актерский состав экрана: http://www.youtube.com/watch?v=w128hJUu3GM

- Эрик

Запись непосредственно в поток документов word действительно повредит его. Вместо этого вы должны написать в поток MainDocumentPart, но сначала вы должны его усечь. Похоже, что метод MainDocumentPart.FeedData(Stream sourceStream) сделает именно это.

Я не проверял его, но это должно сработать.

public ActionResult SearchAndReplace(string FilePath)
{
    MemoryStream mem = new MemoryStream(System.IO.File.ReadAllBytes(FilePath));
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(mem, true))
    {
        string docText = null;
        using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
        {
            docText = sr.ReadToEnd();
        }

        Regex regexText = new Regex("Hello world!");
        docText = regexText.Replace(docText, "Hi Everyone!");

        using (MemoryStream ms = new MemoryStream())
        {
            using (StreamWriter sw = new StreamWriter(ms))
            {
                sw.Write(docText);
            }
            ms.Seek(0, SeekOrigin.Begin);
            wordDoc.MainDocumentPart.FeedData(ms);
        }
    }
    mem.Seek(0, SeekOrigin.Begin); 

    return File(mem, "application/octet-stream","download.docx"); //Return to download file
}
string sourcepath = HttpContext.Server.MapPath("~/File/Form/s.docx");            
string targetPath = HttpContext.Server.MapPath("~/File/ExportTempFile/" + DateTime.Now.ToOADate() + ".docx");
System.IO.File.Copy(sourcepath, targetPath, true);
using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(targetPath, true))
{
    string docText = null;
    using (StreamReader sr = new StreamReader(wordDocument.MainDocumentPart.GetStream()))
    {
        docText = sr.ReadToEnd();
    }
    Regex regexText = new Regex("Hello world!");
    docText = regexText.Replace(docText, "Hi Everyone!");
    byte[] byteArray = Encoding.UTF8.GetBytes(docText); 
    MemoryStream stream = new MemoryStream(byteArray);
    wordDocument.MainDocumentPart.FeedData(stream);
}
MemoryStream mem = new MemoryStream(System.IO.File.ReadAllBytes(targetPath));
return File(mem, "application/octet-stream", "download.docx");

Comments

    Ничего не найдено.