Programmatically Access Document Properties for Word 2007 Documents

Is there a way that I can programmatically access the document properties of a Word 2007 document?

I'm open to using any language for this, but ideally it could be through a PowerShell script.

My overall goal is to move documents somewhere in the file system, parse some document properties from those documents, and then map all of these properties together into a new Word document.

I essentially want to automatically create a document that is a list of all documents under a specific folder in the file system; and this list will contain properties such as Title, Abstract and Author document properties; CreateDate field etc. for each document.

+2


a source to share


5 answers


Check Hello Writer! How do I get the custom properties of a Microsoft Word document? and maybe Hi Screenwriter! How do I add custom properties to a Microsoft Word document? ... It might help you, or at least give you an idea;)



+4


a source


I needed to do this in PowerShell running on a server with no MS Office applications installed. The trick, as suggested above, is to look inside the office file and examine the embedded XML files inside.

Here's a function that works like a cmdlet, which means you can simply save the script in the PowerShell scripts directory and call the function from any other PowerShell script.



# DocumentOfficePropertiesGet
# Example usage
#   From a PowerShell script:
#       $props = Invoke-Expression "c:\PowerShellScriptFolder\DocumentOfficePropertiesGet.ps1 -DocumentFullPathName ""d:\documents\my excel doc.xlsx"" -OfficeProperties ""dcterms:created;dcterms:modified"""

# Parameters

#    DocumentFullPathName -- full path and name of MS Office document
#    OfficeProperties -- semi-colon delimited string of property names as they
#              appear in the core.xml file. To see these names, rename any
#              MS Office document file to have the extension .zip, then look inside
#              the zip file. In the docProps folder open the core.xml file. The
#              core document properties are nodes under the cp:coreProperties node.

#         Example: dcterms:created;dcterms:modified;cp:lastModifiedBy

# Return value

#   The function returns a hashtable object -- in the above example, $props would contain
#   the name-value pairs for the requested MS Office document properties. In the calling script,
#   to get at the values:

#        $fooProperty = $props.'dcterms:created'
#        $barProperty = $props.'dcterms:modified'

[CmdletBinding()]
    [OutputType([System.Collections.Hashtable])]
    Param
    (
        [Parameter(Position=0,
            Mandatory=$false,
            HelpMessage="Enter the full path name of the document")]
            [ValidateNotNullOrEmpty()]
            [String] $DocumentFullPathName='e:\temp\supplier_List.xlsx',
        [Parameter(Position=1,
            Mandatory=$false,
            HelpMessage="Enter the Office properties semi-colon delimited")]
            [ValidateNotNullOrEmpty()]
            [String] $OfficeProperties='dcterms:created; dcterms:modified ;cp:lastModifiedBy;dc:creator'
    )
# We need the FileSystem assembly
Add-Type -AssemblyName System.IO.Compression.FileSystem

# This function unzips a zip file -- and it works on MS Office files directly: no need to
# rename them from foo.xlsx to foo.zip. It expects the full path name of the zip file
# and the path name for the unzipped files
function Unzip
{
    param([string]$zipfile, [string]$outpath)

    [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath) *>$null
}

# Remove spaces from the OfficeProperties parameter
$OfficeProperties = $OfficeProperties.replace(' ','')

# Compose the name of the folder where we will unzip files
$zipDirectoryName = $env:TEMP + "\" + "TempZip"

# delete the zip directory if present
remove-item $zipDirectoryName -force -recurse -ErrorAction Ignore | out-null

# create the zip directory
New-Item -ItemType directory -Path $zipDirectoryName | out-null

# Unzip the files -- i.e. extract the xml files embedded within the MS Office document
unzip $DocumentFullPathName $zipDirectoryName

# get the docProps\core.xml file as [xml]
$coreXmlName = $zipDirectoryName + "\docProps\core.xml"
[xml]$coreXml = get-content -path $coreXmlName

# create an array of the requested properties
$requiredProperties = $OfficeProperties -split ";"

# create a hashtable to return the values
$docProperties = @{}

# Now look for each requested property
foreach($requiredProperty in $requiredProperties)
{
    # We will be lazy and ignore the namespaces. We need the local name only
    $localName = $requiredProperty -split ":"
    $localName = $localName[1]
    # Use XPath to fetch the node for this property
    $thisNode = $coreXml.coreProperties.SelectSingleNode("*[local-name(.) = '$localName']")
    if($thisNode -eq $null)
    {
        # To the hashtable, add the requested property name and its value -- null in this case
        $docProperties.Add($RequiredProperty, $null)
    }
    else
    {
        # To the hashtable, add the requested property name and its value
        $docProperties.Add($RequiredProperty, $thisNode.innerText)
    }
}

#clean up
remove-item $zipDirectoryName -force -recurse

# return the properties hashtable. To do this, just write the object to the output stream
$docProperties

      

+2


a source


I guess your best bet is VB or C # and Carrier Meetings . I don't know how the native path (inside Powershell) does what you want.

However, if you are using VB or C #, you can write a commandhell ​​cmdlet for whatever you are building . But at this point, it would be easier to just write a console application that runs as a scheduled task.

+1


a source


I recently learned from watching an episode of DNRTV that Office 2007 documents are just XML encrypted. So you can change "Document.docx" to "Document.docx.zip" and see the XML files inside. You could probably get the properties through an interop assembly in .NET, but it might be more efficient to just look directly into the XML (perhaps with LINQ to XML or some other way that I don't know about).

+1


a source


I wrote how to do this in the beta version of Monad. I think it should still work.

+1


a source







All Articles