Building an OpenXML Document in WinDev – Part 1

This week I had a requirement to generate formatted document for Word 2007 and thought now would be a great time to learn the new OpenXML format.

This means I don’t have to use the automation process and it gives me full control over how the document looks, without concerning myself with any future changes Microsoft Word will build.

It also means that with some minor changes the document can be opened in other products, including Open Office and Pages on the Mac.

The document that I need to create is basically a zip file containing a specific structure and number of files.

For this simple example I will create 3 files, which are the basic building blocks of the document. These are:

document.xml, which contains the core text of my document.
[Content_Types].xml, describing the type of content I am using.
.rels, which describes the relationships of the files in the zip.

If you want to learn all about the architecture of Open XML, then I would recommend watching some great videos at http://msdn2.microsoft.com/en-us/office/bb738430.aspx.

So here we go…

Creating the zip archive

So the first part is to create a zip file. We actually need a .docx to be created but WinDev requires that we call it a .zip, so it’s easy enough to rename the file when we have finished.

sArchive is string = "Proposal.docx"
sArchiveZip is string = "Proposal.zip"
sDocx is string = "Proposal"
sDocument is string = "Document"
sContent is string = "Content"

 

// Create the docx file
IF fFileExist("Proposal.zip") THEN
 
fDelete("Proposal.zip")
END

IF fFileExist("Proposal.docx") THEN
 
fDelete("Proposal.docx")
END

IF

zipCreate(sDocx,sArchiveZip) <> 0 THEN
 
Error("Unable to create the Open XML Document")
END

Creating document.xml

Next we need to create the document.xml file and add it to the archive. You can learn more about the different elements used to format the document in future posts.

// Create the xml document body

XMLDocument(sDocument)
XMLParent(sDocument)
XMLAddChild(sDocument,"w:document","",True)
XMLAddAttribute(sDocument,"xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main",True)
XMLAddChild(sDocument,"w:body","",True)
XMLAddChild(sDocument,"w:p","",True)
XMLAddChild(sDocument,"w:r","", True)
XMLAddChild(sDocument,"w:t","Promotion Proposal")
sDocumentXML is string = XMLBuildString(sDocument,XMLDocumentDefault,XMLEncodingUTF8)
fSaveText("document.xml",sDocumentXML)

// Add it to Docx

zipAddFile(sDocx,"document.xml")

The xml file was created first and then this file was added to the archive.

Describe the type of Content

The next file describes the type of content used in the document.

// Create the content xml

XMLDocument

(sContent)
XMLParent(sContent)
XMLAddChild(sContent,"Types","",True)
XMLAddAttribute(sContent,"xmlns",http://schemas.openxmlformats.org/package/2006/content-types)
XMLAddChild(sContent,"Default","", True)
XMLAddAttribute(sContent,"Extension","xml")
XMLAddAttribute(sContent,"ContentType","application/xml")
XMLRoot(sContent)
XMLFind(sContent,"Types",XMLElement)
XMLAddChild(sContent,"Override","",True)
XMLAddAttribute(sContent,"PartName","/document.xml")
XMLAddAttribute(sContent,"ContentType","application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")
XMLRoot(sContent)
XMLFind(sContent,"Types",XMLElement)
XMLAddChild(sContent,"Default", "", True)
XMLAddAttribute(sContent,"Extension", "rels")
XMLAddAttribute(sContent,"ContentType","application/vnd.openxmlformats-package.relationships+xml")
sContentXML is string = XMLBuildString(sContent,XMLDocumentDefault,XMLEncodingUTF8)

 

fSaveText("[Content_Types].xml",sContentXML)

zipAddFile(sDocx,"[Content_Types].xml")

Define the file Relationships

In this final file we define the relationships of the xml documents in the archive. So here I have defined a relationship for document.xml.

// Relationships xml document

sRels is string = "Relationships"
XMLDocument(sRels)
XMLAddChild(sRels,"Relationships","",True)
XMLAddAttribute(sRels,"xmlns","http://schemas.openxmlformats.org/package/2006/relationships",True)
XMLAddChild(sRels,"Relationship","",True)
XMLAddAttribute(sRels,"Id","MyRelationship",True)
XMLAddAttribute(sRels,…
"Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",True)
XMLAddAttribute(sRels,"Target","document.xml")
sRelsXML is string = XMLBuildString(sRels,XMLDocumentDefault,XMLEncodingUTF8)

IF fDirectoryExist("_rels") = False
 
fMakeDir
("_rels")
ELSE
 
fDelete("_rels/*.*")
END

fSaveText

("_rels/.rels",sRelsXML)
zipAddDirectory(sDocx, "_rels")

All the relationship files need to sit inside a _rels directory. So I create the file inside the _rels directory and then ad this directory to the archive

Final Lap

Finally I just rename the .zip file to a .docx and we are ready to open it in Word 2007.

In future posts I will show how you apply formatting and images to the document. The great thing about this specification is that you just include the images you need in the archive and reference them. No more binary data of the image in the document.

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright FUNCODER – DEVELOPER & TECHNOLOGY ENTHUSIAST 2017
Shale theme by Siteturner