我有一个包含我指定的模式文本{pattern}的word文件,我想用从数据库中读取的新字符串替换这些模式。所以我使用了来自我的docx模板文件的open xml读取流替换我的模式字符串然后返回流,支持下载文件而不创建临时文件。但是当我打开它时会在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文件格式返回内存流?
答案 0 :(得分:2)
您采取的方法不正确。如果您正在搜索的模式偶然与某些Open XML标记匹配,则会损坏文档。如果您要搜索的文本在多次运行中分割,则您的搜索/替换代码将找不到文本,并且无法正常运行。如果要在WordprocessingML文档中搜索和替换文本,可以使用相当简单的算法:
我写了一篇博客文章并录制了一个屏幕演员,其中介绍了这个算法。
博文:http://openxmldeveloper.org/archive/2011/05/12/148357.aspx
屏幕投射:http://www.youtube.com/watch?v=w128hJUu3GM
-Eric
答案 1 :(得分:1)
直接写入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
}
答案 2 :(得分:1)
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");