2013-08-01 32 views
0

我是一個新手,隨時向我傾訴。 對不起,太模糊了;該代碼執行並寫入損壞的文件。我無法進入損壞的文件來觀察任何錯誤/異常。大小確實看起來像是合併文件的總和。爲什麼此代碼寫入Word無法打開的「損壞文件」(甚至沒有「打開並修復」)?

我已經把鼻涕這個搜索引擎google出去了,找不到任何我能理解如何實現的東西。

的字錯誤開放是:因爲有與內容

話語裏找到不可讀的內容中的問題,你要繼續 文件無法打開?

當我點擊是,我再次得到第一個錯誤&然後我出去了。

該文件具有相同名稱的內容控件,但我已將其修改爲僅添加1個文檔,以查看是否存在重複內容類型是一個問題;相同的損壞文件結果。

順便說一句....我最終的意圖是覆蓋「模板」(... Aggregate Report.dotx)到位。但我不能隨時隨地保存有效的文件,所以......: -/

using System; 
using System.IO; 
using System.ComponentModel; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using Microsoft.SharePoint; 
using Microsoft.SharePoint.WebControls; 
using System.Linq; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Wordprocessing; 
using Word = DocumentFormat.OpenXml.Wordprocessing; 


namespace BobsDocMerger.VisualWebPart1 
{ 
[ToolboxItemAttribute(false)] 
public class VisualWebPart1 : WebPart 
{ 
    // Visual Studio might automatically update this path when you change the Visual Web Part project item. 
    private const string _ascxPath = @"~/_CONTROLTEMPLATES/BobsDocMerger/VisualWebPart1/VisualWebPart1UserControl.ascx"; 

    protected override void CreateChildControls() 
    { 
     System.Web.UI.Control control = this.Page.LoadControl(_ascxPath); 
     Controls.Add(control); 
     base.CreateChildControls(); 
     Button btnSubmit = new Button(); 
     btnSubmit.Text = "Assemble Documents"; 
     btnSubmit.Click += new EventHandler(btnSubmit_Click); 
     Controls.Add(btnSubmit); 
    } 

    void btnSubmit_Click(object sender, EventArgs e) 
    { 
     SPFolder folder = SPContext.Current.ListItem.Folder; 
     char[] splitter = { '/' }; 
     string[] folderName = folder.Name.Split(splitter); 
     string filePrefix = @"Weekly/" + folderName[0] + "/" + folderName[0]; 

     SPFile template = folder.Files[filePrefix + " - Aggregate Report.dotx"]; 
     SPFile file; 
     byte[] byteArray = template.OpenBinary(); 

     using (MemoryStream mem = new MemoryStream()) 
     { 
      mem.Write(byteArray, 0, (int)byteArray.Length); 

      using (WordprocessingDocument myDoc = WordprocessingDocument.Open(mem, true)) 
      { 
       MainDocumentPart mainPart = myDoc.MainDocumentPart; 
       //Loop thru content controls 
       foreach (Word.SdtElement sdt in mainPart.Document.Descendants<Word.SdtElement>().ToList()) 
       { 
        Word.SdtAlias alias = sdt.Descendants<Word.SdtAlias>().FirstOrDefault(); 
        if (alias != null) 
        { 
         //The 2 tags in the Report are AggregateHeader and AggregateBody 
         string sdtTitle = alias.Val.Value; 
         string sdtTag = sdt.GetFirstChild<SdtProperties>().GetFirstChild<Tag>().Val; 
         if (sdtTitle == "Merge") 
         { 
          for (int i = 0; i < folder.Files.Count; i++) 
          { 
           file = folder.Files[i]; 
           //Do all files that are NOT the Aggregate Report 
           if (file.Name.IndexOf("Aggregate Report") == -1) 
           { 
            if (i == folder.Files.Count-1) 
            { 
             AddAltChunk(mainPart, sdt, file, true); 
            } 
            else 
            { 
             AddAltChunk(mainPart, sdt, file, false); 
            } 
           } 
          } 
         } 
        } 
       } 

       HttpResponse resp = HttpContext.Current.Response; 
       resp.ClearContent(); 
       resp.ClearHeaders(); 
       resp.AddHeader("Content-Disposition", "attachment; filename=Assembled Document.docx"); 
       //resp.ContentEncoding = System.Text.Encoding.UTF8; 
       resp.ContentType = "application/msword"; 
       resp.OutputStream.Write(mem.ToArray(), 0, (int)mem.Length); 
       resp.Flush(); 
       resp.Close(); 
       HttpContext.Current.ApplicationInstance.CompleteRequest(); 
      } 
     } 
    } 

    protected int id = 1; 

    void AddAltChunk(MainDocumentPart mainPart, Word.SdtElement sdt, SPFile filename,bool LastPass) 
    { 
     string altChunkId = "AltChunkId" + id; 
     id++; 
     byte[] byteArray = filename.OpenBinary(); 

     AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
     AlternativeFormatImportPartType.WordprocessingML, altChunkId); 

     using (MemoryStream mem = new MemoryStream()) 
     { 
      mem.Write(byteArray, 0, (int)byteArray.Length); 
      mem.Seek(0, SeekOrigin.Begin); 
      chunk.FeedData(mem); 
     } 

     Word.AltChunk altChunk = new Word.AltChunk(); 
     altChunk.Id = altChunkId; 
     //Replace content control with altChunk information 

     DocumentFormat.OpenXml.OpenXmlElement parent = sdt.Parent; 
     parent.InsertBefore(altChunk, sdt); 
     if (LastPass) { sdt.Remove(); } 
    } 
} 
} 
+2

'BobsDocMerger' :) –

+0

heh ....更容易找到我的東西在荒謬的沼澤。 :) – jazaddict

+3

我注意到'.Open()'你從一個「二進制」文件讀取的流。你爲什麼不開始使用接受文件名並直接讀取文件的'WordprocessingDocument.Open()'版本? – 2013-08-01 19:09:01

回答

1

它看起來像你不是在主內存流調用.Seek()得當,你也似乎是可能同時使用該單個存儲器流同時用於輸入和輸出。 (也許是正確的,但它只是非常混亂,我當它是混合模式)

我假設你不能訪問原始文件名和文件系統:

using(Stream t = template.OpenBinaryStream()) 
{ 
    using (WordprocessingDocument myDoc = WordprocessingDocument.Open(t, true)) 
    { 
     using (XmlWriter writer = XmlWriter.Create(resp.OutputStream)) 
     { 
      // TODO re-add merge logic here once it works 

      HttpResponse resp = HttpContext.Current.Response; 
      resp.ClearContent(); 
      resp.ClearHeaders(); 
      resp.AddHeader("Content-Disposition", 
       "attachment; filename=Assembled Document.docx"); 
      //resp.ContentEncoding = System.Text.Encoding.UTF8; 
      resp.ContentType = "application/msword"; 
      // resp.OutputStream.Write(mem.ToArray(), 0, (int)mem.Length); 
/* new */ myDoc.MainDocumentPart.Document.WriteTo(writer); 
      resp.Flush(); 
      resp.Close(); 
      HttpContext.Current.ApplicationInstance.CompleteRequest(); 
     } 
    } 
} 

PS - 我建議在獲得原始模板首先輸出正確。然後在重新添加合併邏輯之前進行一次微小的更改並查看該輸出。

+0

Aight ....我有線索:PART問題是我打開的文檔類型是TEMPLATE(dotx),但是我保存的類型是DOCUMENT(docx)。我將開放文檔更改爲docx。所以現在腐敗仍然存在(???),但開放式維修工程。 – jazaddict

+0

但是,沒有任何一個altchunk數據會被寫入,並且最後一次移除內容控制(sdt)時會執行,但不會將其刪除。我在結果文件中得到的是原始模板的不變副本(不再是模板,但現在是docx)....呃。這可能是「沒有調用.Seek()正確??? – jazaddict

+0

更多的線索:parent.InnerText.Length 164然後Parent.InsertBefore(altchunk,sdt);然後parent.InnerText.Length 164,所以沒有數據在altchunk!? !....我驗證mem.length爲0,然後在mem.write之後更大,但我找不到塊的大小或長度以驗證chunk.feeddata將任何內容放入塊(不出現)....:/ – jazaddict

相關問題