Answered How to upload WordprocessingDocument to SP library?

  • Tuesday, February 28, 2012 2:04 PM
     
      Has Code

    Hi,

    what i want to do is to create a new WordprocessingDocument, put a couple of other documents within it(merge documents) and upload the final document to a SP library.(in my code I add the same file 5x for simplicity). This is what I have:

           static void Main(string[] args)
            {
                XNamespace w =
                    "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
                XNamespace r =
                    "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
    
                SPSite siteCollection = new SPSite("http://ukslazspdtst01:28696/");
                SPWeb site = siteCollection.OpenWeb();
                site.AllowUnsafeUpdates = true;
    
    
                using (MemoryStream memStream = new MemoryStream())
                {
                    //using (WordprocessingDocument myDoc =
                    //    WordprocessingDocument.Create("C:\\Users\\knwb360\\Desktop\\aaaaaaaa.docx", DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
                    using (WordprocessingDocument myDoc =
                    WordprocessingDocument.Create(memStream, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
                    {
                        MainDocumentPart mp = myDoc.AddMainDocumentPart();
                        SetMainDocumentContent(mp);
                        XDocument mainDocumentXDoc = GetXDocument(myDoc);
    
                        for (int i = 0; i <= 5; i++)
                        {
                            string altChunkId = "AltChunkId" + i;
                            MainDocumentPart mainPart = myDoc.MainDocumentPart;
                            AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
                              AlternativeFormatImportPartType.WordprocessingML,
                              altChunkId);
                            using (FileStream fileStream =
                                File.Open("C:\\Users\\knwb360\\Desktop\\TestDoc.docx", FileMode.Open))
                                chunk.FeedData(fileStream);
                            XElement altChunk = new XElement(w + "altChunk",
                                new XAttribute(r + "id", altChunkId)
                            );
                            XElement page = new XElement(w + "br",
                                new XAttribute(w + "type", "page")
                            );
    
                            // Add the altChunk element after the last paragraph.
    
                            mainDocumentXDoc.Root
                                .Element(w + "body")
                                .Elements(w + "p")
                                .Last()
                                .AddBeforeSelf(altChunk);
                            if (i != 5)
                            {
                                mainDocumentXDoc.Root
                                    .Element(w + "body")
                                    .Elements(w + "p")
                                    .Last()
                                    .AddBeforeSelf(page);
                            }
    
                        }
    
                        SaveXDocument(myDoc, mainDocumentXDoc);
                        myDoc.MainDocumentPart.Document.Save();
    
                        SPList docLib = siteCollection.RootWeb.Lists["mergeDocuments"];
                        SPFile file2 = docLib.RootFolder.Files.Add("aa.docx", memStream, true);
                        file2.Update();
                        
                        //SPFolder fldr = site.GetFolder(siteCollection.Url + "/mergeDocuments/");
                        //SPFileCollection files = fldr.Files;
                        //files.Add("NewDocument.docx", memStream, true);
                    }
                }
            }
    
            private static void SaveXDocument(WordprocessingDocument myDoc,
               XDocument mainDocumentXDoc)
            {
                // Serialize the XDocument back into the part
                using (Stream str = myDoc.MainDocumentPart.GetStream(
                    FileMode.Create, FileAccess.Write))
                using (XmlWriter xw = XmlWriter.Create(str))
                    mainDocumentXDoc.Save(xw);
            }
    
            private static XDocument GetXDocument(WordprocessingDocument myDoc)
            {
                // Load the main document part into an XDocument
                XDocument mainDocumentXDoc;
                using (Stream str = myDoc.MainDocumentPart.GetStream())
                using (XmlReader xr = XmlReader.Create(str))
                    mainDocumentXDoc = XDocument.Load(xr);
                return mainDocumentXDoc;
            }
    
            public static void SetMainDocumentContent(MainDocumentPart part)
            {
                const string docXml =
                             @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?> 
                <w:document xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
                <w:body>
                    <w:p>
                    </w:p>
                </w:body>
                </w:document>";
    
                using (Stream stream = part.GetStream())
                {
                    byte[] buf = (new System.Text.UTF8Encoding()).GetBytes(docXml);
                    stream.Write(buf, 0, buf.Length);
                }
            }

    If I use the code that is commented

    using (WordprocessingDocument myDoc = 
    WordprocessingDocument.Create("C:\\Users\\knwb360\\Desktop\\aaaaaaaa.docx", DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
    

    it saves the final file onto the local hard drive and the file opens fine. But when I use the MemoryStream instead and save the file to the Sp library, I get an error when trying to open the file: "The file is corrupt and cannot be opened". Could you guys please have a look what I'm doing wrong?

    Thanks for any help

    Dave

All Replies

  • Wednesday, February 29, 2012 8:51 AM
    Moderator
     
     
     

    Hi 11Dave11,

    You said when you use MemoryStream ,you get error like this “The file is corrupt and cannot be opened” . So, I suggest you should close then  MemoryStream.  You should add then following code in your project.

    memStream.Close();

    Thanks,

    Jack

  • Wednesday, February 29, 2012 10:16 AM
     
     Answered

    Solved, in case anyone else will have the same problem in the future, you need to dispose of the document before uploading the file:

    myDoc.Dispose();

    
    • Marked As Answer by 11Dave11 Wednesday, February 29, 2012 10:17 AM
    •  
  • Friday, December 14, 2012 3:41 PM
     
     

    Wow..this worked for me too. Thanks bro. I had this problem for two days and i was thinking something is wrong with the code that i have written using openxml.

    Thanks.

    Raj


    Rajan