2012-07-11 109 views
2

我正在做的是試圖更改Microsoft Office Word文檔XML的值並將其另存爲新文件。我知道我可以使用SDK來簡化這個過程,但我負責維護的項目是這樣做的,我被告知我也必須這樣做。更改Word文檔XML

我有映射到以下XML兩個佔位符的基本測試文檔:

<root> 
    <element> 
    Fubar 
    </element> 
    <second> 
    This is the second placeholder 
    </second> 
</root> 

在我的測試項目中,我有以下幾點:

string strRelRoot = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"; 
//the word template 
byte[] buffer = File.ReadAllBytes("dev.docx"); 
MemoryStream stream = new MemoryStream(buffer, true); 
Package package = Package.Open(stream, FileMode.Open, FileAccess.ReadWrite); 
//get the document relationship 
PackageRelationshipCollection pkgrcOfficeDocument = package.GetRelationshipsByType(strRelRoot); 
//iterate through relationship 
foreach (PackageRelationship pkgr in pkgrcOfficeDocument) 
{ 
    if (pkgr.SourceUri.OriginalString == "/") 
    { 
     //uri for the custom xml 
     Uri uriData = new Uri("/customXML/item1.xml", UriKind.Relative); 
     //delete the existing xml if it exists 
     if (package.PartExists(uriData)) 
     { 
      // Delete template "/customXML/item1.xml" part 
      package.DeletePart(uriData); 
     } 
     PackagePart pkgprtData = package.CreatePart(uriData, "application/xml"); 
      //hard coded test data 
      string xml = @"<root> 
         <element> 
          Changed 
         </element> 
         <second> 
           The second placeholder changed 
         </second> 
        </root>"; 
     Stream fromStream = pkgprtData.GetStream(); 
     //write the string 
     fromStream.Write(Encoding.UTF8.GetBytes(xml),0,xml.Length); 
     //destination file 
     Stream dest = File.Create("test.docx"); 
     //write to the destination file 
     for (int a = fromStream.ReadByte(); a != -1; a = fromStream.ReadByte()) 
     { 
      dest.WriteByte((byte)a); 
     } 

    } 
} 

什麼,現在的情況是文件test.docx正在創建,但它是一個空白的文檔。我不知道爲什麼會發生這種情況。任何人都可以提供這種方法和/或我做錯了什麼建議將非常感激。非常感謝!

回答

2

調用fromStream.Write之後,流指針位於剛剛寫入的數據之後。所以你的第一個電話fromStream.ReadByte已經在流的末尾,你讀(寫)什麼都沒有。

在寫入之後(如果程序包返回的流支持查找),需要將Seek添加到流的開頭,或者關閉fromStream(以確保寫入的數據已刷新)並重新打開以供讀取。

fromStream.Seek(0L, SeekOrigin.Begin); 
+0

感謝您的回覆!你需要重置指針是正確的。我已經稍微修改了我的代碼和目標,併發布了修改內容,如果您可以看看,我會很感激,謝謝! – TheMethod 2012-07-11 13:19:16

+1

@TheMethod這對你的目標來說是一個非常重要的修改:P簡而言之,在刪除包含它的部分之前(或者不是)刪除原始XML,然後在寫入之前使用其中一個XML API替換你想要的值回來了。爲了避免讓任何沒有看過它的歷史的人不能理解這個問題,最好回滾你的編輯並提出一個新問題。 – shambulator 2012-07-11 13:38:24