none
Generate word docx from template by updating the item1.xml file RRS feed

  • Question

  • hi

     

     public void CreateDocument()

        {

            // Get the template file and create a stream from it

            const string TemplateFile = @"~/App_Data/Template.docx";

            const string documentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";

           // Read the file into memory

            byte[] buffer = File.ReadAllBytes(Server.MapPath(TemplateFile));

            MemoryStream memoryStream = new MemoryStream();

            memoryStream.Write(buffer, 0, buffer.Length);

            buffer = null;

     

            // Open the document in the stream and replace the custom XML part

            Package pkgFile = Package.Open(memoryStream, FileMode.Open, FileAccess.ReadWrite);

            PackageRelationshipCollection pkgrcOfficeDocument = pkgFile.GetRelationshipsByType(strRelRoot);

            foreach (PackageRelationship pkgr in pkgrcOfficeDocument)

            {

                if (pkgr.SourceUri.OriginalString == "/")

                {

                    // Add a custom XML part to the package

                    Uri uriData = new Uri("/customXML/item1.xml",  UriKind.Relative);

                    if (pkgFile.PartExists(uriData))

                    {

                        // Delete template "/customXML/item1.xml" part

                        pkgFile.DeletePart(uriData);

                    }

     

                    // Load the custom XML data

                    PackagePart pkgprtData = pkgFile.CreatePart(uriData, "application/xml");

                    GetData(pkgprtData.GetStream());

                    StreamReader ms = new StreamReader(pkgprtData.GetStream());

                    string text=ms.ReadToEnd();

                }

            }

     

            // Close the file

            pkgFile.Close();

     

            // Return the result  

            Response.ClearContent();

            Response.ClearHeaders();

            Response.AddHeader("content-disposition", "attachment;filename=PositiveImportCertification.docx");

            Response.ContentEncoding = System.Text.Encoding.UTF8;

            memoryStream.WriteTo(Response.OutputStream);

            memoryStream.Close();

            Response.End();

        }

     

    in the following the Final docx created still the same as it appear in the template. Since while deleting the "/customXML/item1.xml"

    it looses its relation ship with "/customXML/itemProps1.xml" can any one please help me out in this, to retain the relation ship in both the xml. or either /customXML/itemProps1.xml is deleted.

     

    thanks

    vimal

     


    regards Vimal
    Tuesday, January 11, 2011 3:26 AM

Answers

  • Hi Vimal,

    Looking at the code it appears that you are using Open XML SDK 1.0. You should consider using Open XML SDK 2.0 which allows achieving the same functionality in much more easier way.  It will take care of all your relationships appropriately.

    Instead of deleting your custom XML part and adding new one, you should update the content of the XML part. Following code snippet does the same: 

     public static void UpdateCustomXML()
      {
       string templatePath = @"D:\EmployeeControls.docx";
       string custXMLFilePath = @"D:\item2.xml";
    
       using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(templatePath, true))
       {
        MainDocumentPart mainPart = wdDoc.MainDocumentPart;
    
        // load custom XML
        XmlDataDocument custXML = new XmlDataDocument();
        custXML.Load(custXMLFilePath);
    
        // get the XML part that needs to be updated
        CustomXmlPart custXMLPart = mainPart.CustomXmlParts.ElementAtOrDefault(1);
    
        // update the content of the custom XML part
        using (Stream myStream = custXMLPart.GetStream(FileMode.Create))
        {    
         custXML.Save(myStream);
        }
       }
      }
    

    Thanks !

    Pradip

    Friday, January 21, 2011 6:24 PM

All replies

  • hi

    some change in code to create the item1.xml relation

     

    protected static void CreateDocument()

    {

     

    // Get the template file and create a stream from it

     

    const string TemplateFile = @"C:\Documents and Settings\vimalkumar_s\Desktop\New Folder (3)/TemplateTEst.docx";

     

    // Read the file into memory

     

    byte[] buffer = File.ReadAllBytes(TemplateFile);

     

    MemoryStream memoryStream = new MemoryStream();

    memoryStream.Write(buffer, 0, buffer.Length);

    buffer =

    null;

     

    // Open the document in the stream and replace the custom XML part

     

    Package pkgFile = Package.Open(memoryStream, FileMode.Open, FileAccess.ReadWrite);

     

    PackageRelationshipCollection pkgrcOfficeDocument = pkgFile.GetRelationshipsByType(strRelRoot);

     

    foreach (PackageRelationship pkgr in pkgrcOfficeDocument)

    {

     

    if (pkgr.SourceUri.OriginalString == "/")

    {

     

    // Add a custom XML part to the package

     

    Uri uriData = new Uri("/customXML/item1.xml", UriKind.Relative);

     

    if (pkgFile.PartExists(uriData))

    {

     

    // Delete template "/customXML/item1.xml" part

     

    pkgFile.DeletePart(uriData);

    }

     

    // Load the custom XML data

     

    PackagePart pkgprtData = pkgFile.CreatePart(uriData, "application/xml");

    //newly added line

    pkgprtData.CreateRelationship(

    new Uri("/customXML/itemProps1.xml", UriKind.Relative), TargetMode.Internal,

     

    "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps");

    GetData(pkgprtData.GetStream());

     

    StreamReader ms = new StreamReader(pkgprtData.GetStream());

     

    string str = ms.ReadToEnd();

     

    break;

    }

    }

     

    // Close the file

    pkgFile.Close();

     

    FileStream filestream = new FileStream(@"C:\Documents and Settings\vimalkumar_s\Desktop\New Folder (3)\PositiveImportCertification.docx", FileMode.Create);

     

    byte[] memByte = memoryStream.ToArray();

    filestream.Write(memByte, 0, memByte.Length);

    filestream.Close();

     

    memoryStream.Close();

    }

     

    but still getting validation error in /custom/itemProps1.xml , and forming the required docx file from template


    regards Vimal
    Tuesday, January 11, 2011 7:59 AM
  • problem not solved, still not getting the required docx while updating the customXML.
    regards Vimal
    Tuesday, January 11, 2011 8:04 AM
  • Hi Vimal,

    Looking at the code it appears that you are using Open XML SDK 1.0. You should consider using Open XML SDK 2.0 which allows achieving the same functionality in much more easier way.  It will take care of all your relationships appropriately.

    Instead of deleting your custom XML part and adding new one, you should update the content of the XML part. Following code snippet does the same: 

     public static void UpdateCustomXML()
      {
       string templatePath = @"D:\EmployeeControls.docx";
       string custXMLFilePath = @"D:\item2.xml";
    
       using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(templatePath, true))
       {
        MainDocumentPart mainPart = wdDoc.MainDocumentPart;
    
        // load custom XML
        XmlDataDocument custXML = new XmlDataDocument();
        custXML.Load(custXMLFilePath);
    
        // get the XML part that needs to be updated
        CustomXmlPart custXMLPart = mainPart.CustomXmlParts.ElementAtOrDefault(1);
    
        // update the content of the custom XML part
        using (Stream myStream = custXMLPart.GetStream(FileMode.Create))
        {    
         custXML.Save(myStream);
        }
       }
      }
    

    Thanks !

    Pradip

    Friday, January 21, 2011 6:24 PM