2013-08-19 43 views
9

Tôi đã tạo tệp docx từ mẫu từ, giờ tôi đang truy cập tệp docx được sao chép và muốn thay thế văn bản nhất định bằng một số dữ liệu khác.Thay thế văn bản trong tài liệu Word bằng cách sử dụng Open Xml

Tôi không thể nhận được gợi ý về cách truy cập văn bản từ phần chính doument?

Mọi trợ giúp đều đáng được đánh giá cao.

Dưới đây là mã của tôi cho đến bây giờ.

private void CreateSampleWordDocument() 
    { 
     //string sourceFile = Path.Combine("D:\\GeneralLetter.dot"); 
     //string destinationFile = Path.Combine("D:\\New.doc"); 
     string sourceFile = Path.Combine("D:\\GeneralWelcomeLetter.docx"); 
     string destinationFile = Path.Combine("D:\\New.docx"); 
     try 
     { 
      // Create a copy of the template file and open the copy 
      File.Copy(sourceFile, destinationFile, true); 
      using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFile, true)) 
      { 
       // Change the document type to Document 
       document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document); 
       //Get the Main Part of the document 
       MainDocumentPart mainPart = document.MainDocumentPart; 
       mainPart.Document.Save(); 
      } 
     } 
     catch 
     { 
     } 
    } 

Bây giờ, làm cách nào để tìm văn bản nhất định và thay thế? Tôi không thể nhận được thông qua Liên kết, vì vậy một số gợi ý mã sẽ được đánh giá cao.

Trả lời

11

Chỉ cần để cung cấp cho bạn những ý tưởng về cách để làm điều đó, hãy thử:

using (WordprocessingDocument doc = 
        WordprocessingDocument.Open(@"yourpath\testdocument.docx", true)) 
      { 
       var body = doc.MainDocumentPart.Document.Body; 
       var paras = body.Elements<Paragraph>(); 

       foreach (var para in paras) 
       { 
        foreach (var run in para.Elements<Run>()) 
        { 
         foreach (var text in run.Elements<Text>()) 
         { 
          if (text.Text.Contains("text-to-replace")) 
          { 
           text.Text = text.Text.Replace("text-to-replace", "replaced-text"); 
          } 
         } 
        } 
       } 
      } 
     } 

Xin lưu ý các văn bản là trường hợp nhạy cảm. Định dạng văn bản sẽ không bị thay đổi sau khi thay thế. Hy vọng điều này sẽ giúp bạn.

+0

tôi đã yêu cầu bạn cung cấp cho câu trả lời cho câu hỏi trước đây của tôi cũng như liên kết của bạn đã giúp tôi, vì vậy bài trả lời đó là tốt. –

+0

@flowerking: Nếu bạn có một vài phút, bạn có thể giúp với điều này? http://stackoverflow.com/questions/26307691 – slayernoah

+4

điều này chỉ thay thế văn bản trong một lần chạy. Tuy nhiên, văn bản có thể được cắt nhỏ trong các lần chạy khác nhau, mà fisrt phải được ghép lại trước khi thay thế có thể được thực hiện. – Erik

2

Có lẽ giải pháp này là dễ dàng hơn:
1. một StreamReader đọc tất cả các văn bản,
2. sử dụng một Regex bạn trường insensitively thay thế các văn bản mới thay cho tex cũ
3. một StreamWriter viết lại các sửa đổi văn bản vào tài liệu.

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true)) 
{ 
    string docText = null; 
    using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream())) 
     docText = sr.ReadToEnd(); 

    foreach (var t in findesReplaces) 
     docText = new Regex(findText, RegexOptions.IgnoreCase).Replace(docText, replaceText); 

    using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create))) 
     sw.Write(docText); 
} 
+0

@Roy bạn có nghĩ rằng bây giờ tốt hơn không? –

+0

Có. Cảm ơn bạn đã thêm mô tả cho câu trả lời hay của mình – MickyD

5

Ngoài Flowerking 's câu trả lời:

Khi tập tin doc của bạn có textbox trong đó, quá trình này sẽ không hoạt động. Bởi vì textbox có phần tử TextBoxContent nên nó sẽ không xuất hiện ở vòng lặp foreach.

Nhưng khi viết

using (WordprocessingDocument doc = 
        WordprocessingDocument.Open(@"yourpath\testdocument.docx", true)) 
      { 
       var document = doc.MainDocumentPart.Document 

       foreach (var text in document.Descendants<Text>()) // <<< Here 
       { 
        if (text.Text.Contains("text-to-replace")) 
        { 
          text.Text = text.Text.Replace("text-to-replace", "replaced-text"); 
        } 
       } 
      } 

nó sẽ lặp tất cả các văn bản trong tài liệu (cho dù đó là trong textbox hay không) vì vậy nó sẽ thay thế các văn bản.

-1

here là giải pháp từ msdn.

Ví dụ từ đó:

public static void SearchAndReplace(string document) 
{ 
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, 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 (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create))) 
     { 
      sw.Write(docText); 
     } 
    } 
} 
+2

Điều này về cơ bản là vô ích nếu từ tách văn bản bạn tìm kiếm thành nhiều lần chạy (hoặc tệ hơn) ... – Santhos

+0

Tôi đang gặp vấn đề chính xác này @Santhos và thậm chí sẽ ném các RUN tôi không biết từ đó chia tách văn bản như thế nào, nó khiến tôi đau đầu rất lớn. – Zorkind

+0

@Eduardo Bạn tôi đã cố gắng giải quyết nó nhưng cuối cùng đã phải tự đi qua tất cả các lần chạy và cố gắng soạn thảo văn bản. Nếu tệp từ nằm dưới sự kiểm soát của bạn, bạn có thể chỉnh sửa xml của nó và sửa các lần xuất hiện bạn cần thay thế để chúng không vượt quá nhiều lần chạy. – Santhos

0

Nếu văn bản mà bạn đang tìm kiếm được đặt trong ngoặc đơn và Word Tách văn bản của bạn trong nhiều chạy ...;

Tìm kiếm văn bản (IEnumerable (văn bản))

for (int i = 0; i <= SearchIn.Count - 1; i++) { 

    if (!(i + 2 > SearchIn.Count - 1)) { 
     Text TXT = SearchIn(i); 
     Text TXT1 = SearchIn(i + 1); 
     Text TXT2 = SearchIn(i + 2); 

     if (Strings.Trim(TXT.Text) == "[" & Strings.Trim(TXT2.Text) == "]") { 
      TXT1.Text = TXT.Text + TXT1.Text + TXT2.Text; 

      TXT.Text = ""; 
      TXT2.Text = ""; 
     } 
    } 
} 
Các vấn đề liên quan