Advanced Macromedia ColdFusion MX 7 Application Development
Microsoft Excel, PowerPoint, and Word files are natively stored in a binary format referred to as an OLE Compound Document. In this hierarchical structured format, programs that understand even a small part of the hierarchy can interact with that data while ignoring the rest without fear of corrupting the document. This allows us to manipulate Microsoft Office files through ColdFusion safely and efficiently. One part of the document data associated with every OLE Compound Document, including Office files, is the Document Summary Properties. These properties are commonly known as the built-in properties users occasionally set through the Office user interface, such as the title, subject, and author, as shown in Figure 27.1. Figure 27.1. Manually editing the built-in summary properties in a Microsoft Word document through the user interface.
NOTE All of the examples in this chapter use DSOFile to read and write document properties. DSOFile is a COM object and thus these examples are targeted at ColdFusion servers installed on Microsoft Windows servers. Document properties can also be read and written using Apache POI, as discussed later in this chapter. The concepts discussed here apply equally to POI-based integrationonly the code has been changed. In order to run these samples and use DSOFile in ColdFusion, applications download the COM object from Microsoft and install it on the server. It is available at: http://www.microsoft.com/downloads/details.aspx?familyid=9ba6fac6-520b-4a0a-878a-53ec8300c4c2.
Review Listing 27.1 for an example of reading Document Properties. This example lists all of the files in a directory along with their author. Listing 27.1. ListAuthors.cfmList Files with Authors Using Summary Properties
<!--- Filename: ListAuthors.cfm Purpose: List files in a directory along with the author property. Depends on: DSOFile COM object installed on server. ---> <!--- get a list of files in the target directory ---> <cfset dir=ExpandPath("files")> <cfdirectory action="list" directory="#dir#" name="files"> <!--- Instantiate a Document Properties object ---> <cfobject action="create" type="com" name="props"> <!--- display headings for our table ---> <h1>Directory Listing with Author</h1> <table border="0" cellpadding="0" cellspacing="0"> <tr> <th>File</th> <th>Modified</th> <th>Author</th> </tr> <!--- loop through files and read their summary properties ---> <cfoutput query="files"> <cfset props.Open(dir & "/" & files.name)> <cfset summary = props.SummaryProperties> <!--- display data from cfdirectory and the property reader ---> <tr> <td>#files.name#</td> <td>#DateFormat(files.dateLastModified)#</td> <td>#summary.author#</td> </tr> <!--- we're done with this file ---> <cfset props.Close()> </cfoutput> </table> <!--- we're done with the reader, release it ---> <cfset ReleaseComObject(props)> This example starts with a standard directory listing and includes information provided by ColdFusionthe filename and the last modified date. In addition, it instantiates a DSOFile.OleDocumentProperties object that is used to read the properties of each file in order to display the author. To accomplish this, the PropertyReader provides an Open method and then a SummaryProperties object, which in turn includes an Author property. The SummaryProperties object includes all the built-in properties listed in Table 27.1.
Figure 27.2. Output from ListAuthors.cfmthe files along with author names.
Besides these built-in properties, all documents can have an unlimited number of custom properties. This is where true integration begins. Through these custom properties we can provide updated data to an existing document and provide a customized document to the user. Listing 27.2 is an example that customizes an existing Word document with the name and address of a customer. Listing 27.2. MailMerge.cfmServe a Word Document with Custom Information
<!--- Filename: MailMerge.cfm Purpose: Merge data into a Word document via custom properties Requires: Existing word document as template and DSOFile installed ---> <!--- create a copy of our source document ---> <cfset source=ExpandPath("files\merge.doc")> <cfset tempFile=GetTempFile(GetTempDirectory(),"doc")> <cffile action="copy" source="#source#" destination="#tempFile#"> <cfscript> // Open the temp file properties props = createObject("COM","DSOFile.OleDocumentProperties"); props.Open(tempFile); customProps = props.CustomProperties; // set custom property values. In a real application, these // would come from a form or database. customProps.Item("OrderDate").Value = "November 23, 2004"; customProps.Item("FirstName").Value = "Samuel"; customProps.Item("LastName").Value = "Neff"; customProps.Item("Address").Value = "215 East Road"; customProps.Item("City").Value = "Rockville"; customProps.Item("State").Value = "MD"; customProps.Item("Zip").Value = "20850"; // save and close the document props.Save(); props.Close(); ReleaseComObject(props); </cfscript> <!--- send the document to the user. Specify that the file is an attachment to prevent Internet Explorer from opening it through automation. ---> <cfheader name="Content-Disposition" value="attachment; filename=""Confirmation.doc"""> <cfcontent reset="yes" type="application/msword" file="#tempFile#" deleteFile="true">
MailMerge.cfm starts by copying the template document to a new temporary file and then opening the custom document properties for that file. The custom properties are each updated by referencing the existing property objects by name and changing their values. Finally, the properties are saved and closed and the document is sent to the user. Notice the use of both the <cfheader> and <cfcontent> tags. The <cfheader> tag instructs the browser to treat the document as a downloaded file to be opened outside the browserwithout this tag Internet Explorer would open the file internally using Microsoft Word as an automation server. The <cfcontent> tag specifies the file type, which is how the browser knows the document is a Microsoft Word documentbrowsers always ignore filename extensions. This example uses a Word document that is already set up with custom properties as placeholders. Word provides developers with the ability to create fields within the document that are linked to custom properties and will show the updated data when the document is loaded. Figure 27.3 shows the field editor creating a DocProperty field pointing to a custom OrderDate property. Figure 27.3. Setting up a Word document to be used as a template by linking fields to custom properties.
NOTE Microsoft Excel and PowerPoint both support custom document properties but do not provide the same automatic linking mechanism provided by Word. To use Document Properties to customize Excel and PowerPoint documents, they must include Visual Basic for Applications (VBA) code, which runs when the document is opened, extracts the properties, and updates the document based on the information. A discussion of the VBA code to accomplish this is outside the scope of this book.
Document Properties represents and easy-to-use and very efficient technology for reading and writing small amounts of information from and to Microsoft Excel, PowerPoint, and Word documents. Although this technique does not work well with many integration requirements, it is ideal for some solutions (such as mail merge). |