2013-08-01 2 views
0

Я новичок, не стесняйтесь говорить со мной. Извините, что вы так расплывчаты; код выполняет и записывает поврежденный файл. Я не могу попасть в поврежденный файл, чтобы наблюдать за ошибками/аномалиями. Размер выглядит как сумма объединенных файлов.Почему этот код записывает «поврежденный файл», который Word не может открыть (даже «Открыть и восстановить»)?

Я искал сопли из этого и не могу найти ничего, что мог бы понять, как реализовать.

Погрешности Слова на открытом является: Файл не может быть открыт, потому что есть проблемы с содержанием

и

Слова найдены нечитаемые содержанием, вы хотите продолжить?

Когда я нажимаю «Да», я снова получаю первую ошибку &, после чего я ухожу.

В документах есть элементы управления содержимым с тем же именем, но я модифицировал это, чтобы добавить только один документ, чтобы увидеть, будут ли проблемы с типом содержимого проблемой; то же поврежденные результаты файла.

btw .... мое конечное намерение состоит в том, чтобы перезаписать «шаблон» (... Совокупный отчет.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

Хе-хе ... легче найти мои вещи в болоте глупостей. :) – jazaddict

+3

Я замечаю вас '.Open()' поток, который вы написали из «двоичного» файла, прочитанного. Почему бы вам не начать использовать версию 'WordprocessingDocument.Open()', которая принимает имя файла и читает файл напрямую? –

ответ

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 .... У меня есть ключи: ЧАСТЬ Проблема заключалась в том, что тип документа, который я открывал, был TEMPLATE (dotx), но тип, который я сохранял, был ДОКУМЕНТОМ (docx). Я сменил открывающий документ на docx. Итак, теперь коррупция STILL EXISTS (???), но Open-Repair работает. – 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

Смежные вопросы