2012-09-12 80 views
0

我們需要從2個其他文檔的內容創建一個矩陣。例如:引用其他文檔的內容

  1. 文檔有一個像場:

    4.2要求一個 胡說

  2. 文檔有一個像場:

    2.1分析的 等等等等

,我們要創建另一個文件(稱爲跟蹤矩陣),它是這樣的:

Col1 Col2 Col3 
4.2  2.1  Blah Blah Blah 

4.2和2.1應doc3的動態更新。

我們使用超鏈接檢查,交叉引用,但沒有任何東西似乎用於組合不同的文檔。無論如何要做到這一點?

編輯: 下面是一個例子:

Technical Specification Num   Requirement Num  Requirement 
4.2         2.1     A sentence that explains the relationship btw 2 cols: Technical Specification and Requirement Num 
+1

如果有這樣的完成只用微軟Word?或者可以通過實現一個通過COM對象與MS Word通信的C#應用​​程序來處理它?你舉了一個文檔中的一些「字段」的例子 - 對我來說,例子看起來像標題 - 你的意思是標題嗎?所以一般來說,如果你可以詳細說明一下細節,那將是很棒的:) –

+0

抱歉,對於遲到的回覆。你是對的Col1和Col2是標題,它們來自不同的文件,並且將被組合在另一個文件中形成一個表格。不幸的是,我們只需要在MS Word中找到解決方案。但是任何插件或者類似的東西也都適用。 – lamostreta

+0

組合的col應該在最終矩陣中形成笛卡爾積嗎?就像如果你在doc中找到標題2.1和3.1。 A和文檔中的標題4.1。 B,最終的矩陣是否應該包含2.1和4.1的行和3.1和4.1的行?總的來說,你能否詳細說明最終矩陣應該是什麼樣子? :) –

回答

1

現在我已經創造了這樣一個使用MS Word中互操作和C#實現的工作示例。

代碼包含應解釋最有趣部分的註釋。

樣品被實現爲使用C#控制檯應用程序:

  • .NET 4.5
  • 微軟Office對象庫版本15.0和
  • Microsoft Word對象庫版本15.0

...也就是MS Office 2013預覽版附帶的MS Word Interop API。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Office.Interop.Word; 
using Application = Microsoft.Office.Interop.Word.Application; 

namespace WordDocStats 
{ 
    internal class Program 
    { 
     private static void Main() 
     { 
      // Open word 
      var wordApplication = new Application() { Visible = true }; 

      // Open document A, get its headings, and close it again 
      var documentA = wordApplication.Documents.Open(@"C:\Users\MyUserName\Documents\documentA.docx", Visible: true); 
      var headingsA = GetHeadingsInDocument(documentA); 
      documentA.Close(); 

      // Same procedure for document B 
      var documentB = wordApplication.Documents.Open(@"C:\Users\MyUserName\Documents\documentB.docx", Visible: true); 
      var headingsB = GetHeadingsInDocument(documentB); 
      documentB.Close(); 

      // Open the target document (document C) 
      var documentC = wordApplication.Documents.Open(@"C:\Users\MyUserName\Documents\documentC.docx", Visible: true); 

      // Add a table to it (the traceability matrix) 
      // The number of rows is the number of headings + one row reserved for a table header 
      documentC.Tables.Add(documentC.Range(0, 0), headingsA.Count+1, 3); 

      // Get the traceability matrix 
      var traceabilityMatrix = documentC.Tables[1]; 

      // Add a table header and border 
      AddTableHeaderAndBorder(traceabilityMatrix, "Headings from document A", "Headings from document B", "My Description"); 

      // Insert headings from doc A and doc B into doc C's traceability matrix 
      for (var i = 0; i < headingsA.Count; i++) 
      { 
       // Insert headings from doc A 
       var insertRangeColOne = traceabilityMatrix.Cell(i + 2, 1).Range; 
       insertRangeColOne.Text = headingsA[i].Trim(); 

       // Insert headings from doc B 
       var insertRangeColTwo = traceabilityMatrix.Cell(i + 2, 2).Range; 
       insertRangeColTwo.Text = headingsB[i].Trim(); 
      } 

      documentC.Save(); 
      documentC.Close(); 

      wordApplication.Quit(); 
     } 

     // Based on: 
     // -> http://csharpfeeds.com/post/5048/Csharp_and_Word_Interop_Part_4_-_Tables.aspx 
     // -> http://stackoverflow.com/a/1817041/700926 
     private static void AddTableHeaderAndBorder(Table table, params string[] columnTitles) 
     { 
      const int headerRowIndex = 1; 

      for (var i = 0; i < columnTitles.Length; i++) 
      { 
       var tableHeaderRange = table.Cell(headerRowIndex, i+1).Range; 
       tableHeaderRange.Text = columnTitles[i]; 
       tableHeaderRange.Font.Bold = 1; 
       tableHeaderRange.Font.Italic = 1; 
      } 

      // Repeat header on each page 
      table.Rows[headerRowIndex].HeadingFormat = -1; 

      // Enable borders 
      table.Borders.Enable = 1; 
     } 

     // Based on: 
     // -> http://stackoverflow.com/q/7084270/700926 
     // -> http://stackoverflow.com/a/7084442/700926 
     private static List<string> GetHeadingsInDocument(Document document) 
     { 
      object headingsAtmp = document.GetCrossReferenceItems(WdReferenceType.wdRefTypeHeading); 
      return ((Array)(headingsAtmp)).Cast<string>().ToList(); 
     } 
    } 
} 

基本上,代碼首先加載兩個給定文檔中的所有標題並將它們存儲在內存中。然後打開目標文檔,創建並設置可追溯性矩陣的樣式,最後將標題插入到矩陣中。

的代碼是基於以下假設:

  • 目標文檔(documentC.docx)是否存在。
  • 兩個輸入文檔(documentA.docx和documentB.docx)中標題的數量包含相同數量的標題 - 此假設是根據您對不想使用笛卡爾產品的評論作出的。

我希望這能滿足您的要求:)

相關問題