2011-04-15 3 views
2

내 지정된 패턴 텍스트 {pattern}을 포함하는 단어 파일을 가지고 있으며이 패턴을 데이터베이스에서 읽은 새 문자열로 바꾸려고합니다. 그래서 열린 xml을 사용하여 내 docx 템플릿 파일에서 스트림을 바꾼 다음 패턴 파일을 다운로드하지 않고 임시 파일을 만들지 않고 스트림으로 반환했습니다. 하지만 내가 열 때 그것은 나를 docx 파일에 오류가 발생했습니다. 다음은 대신 워드 파일에서 텍스트를 읽은 다음 다시 원래의 파일에 데이터를 기록하는 예상 패턴 텍스트를 대체 나에게 어떤 솔루션을 제안하십시오 내 예제 코드Open XML은 단어 파일의 텍스트를 대체하고 MVC를 사용하여 메모리 스트림을 반환합니다.

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 
} 

입니다. WordprocessingDocument 라이브러리로 텍스트를 대체하는 솔루션이 있습니까? 유효성 검사 docx 파일 형식으로 메모리 스트림으로 어떻게 되돌릴 수 있습니까?

답변

2

취하는 방법이 올바르지 않습니다. 우연히 찾고있는 패턴이 일부 Open XML 마크 업과 일치하면 문서가 손상됩니다. 검색하려는 텍스트가 여러 번 실행되는 경우 검색/바꾸기 코드가 텍스트를 찾지 못해 올바르게 작동하지 않습니다.

  • 브레이크 모든 실행을 하나의 캐릭터의 실행에 : 당신이 검색하고 WordprocessingML의 문서에서 텍스트를 교체하려는 경우, 당신이 사용할 수있는 매우 쉽게 알고리즘이있다. 여기에는 에 줄 바꿈, 캐리지 리턴 또는 하드 탭과 같은 특수 문자가있는 실행이 포함됩니다.
  • 그러면 검색 문자열에 문자와 일치하는 실행 집합이 개로 쉽게 발견됩니다.
  • 당신은 실행의 집합을 그 일치를 확인하면, 는 당신은 검색 문자열과 일치하는 첫 번째 문자를 포함하는 실행 의 실행 속성을 가진 새로 생성 된 실행으로 실행 의 세트를 (대체 할 수있다).
  • 을 새로 작성한 실행으로 바꾸면 다음에 인접한 실행을 동일한 서식으로 통합 할 수 있습니다.

블로그 게시물을 작성하고이 알고리즘을 수행하는 스크린 캐스트를 기록했습니다.

블로그 게시물 : http://openxmldeveloper.org/archive/2011/05/12/148357.aspx
스크린 캐스트 : http://www.youtube.com/watch?v=w128hJUu3GM

-Eric

1

워드 문서 스트림에 직접 쓰면 실제로 손상됩니다. MainDocumentPart 스트림에 쓰기를해야하지만 먼저 스트림을 자릅니다. 마치 MainDocumentPart.FeedData(Stream sourceStream)처럼 보이는 방법입니다.

테스트하지는 않았지만 정상적으로 작동합니다.

0
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");