I have created a small function in F# to update the content of a word document.
//reference to the package
#r "WindowsBase"
//reference to the Xml and Linq
#r "System.Xml"
#r "System.Xml.Linq"
open System
open System.IO
open System.IO.Packaging
open System.Xml
open System.Xml.Linq
//helper to create XName with a namespace
let xname str =
XName.Get(str, "http://schemas.openxmlformats.org/wordprocessingml/2006/main")
// the main function
// changeDoc copies a word .docx document and updates the content by changing the xml that represents the content
let changeDoc oldPath newPath (updateDocument:XDocument -> XDocument) =
//update the package part
let updatePart (part:PackagePart) =
using (part.GetStream(FileMode.Open, FileAccess.Read)) (fun stream ->
let xDocumentOut = stream |> XDocument.Load |> updateDocument
xDocumentOut.Save(part.GetStream(FileMode.Create, FileAccess.Write))
)
File.Copy(oldPath, newPath, true)
using (Package.Open(newPath, FileMode.Open, FileAccess.ReadWrite)) (fun package ->
let uri = new Uri("/word/document.xml", UriKind.Relative )
uri |> package.GetPart|> updatePart
)
// test function to update the document
// adds "_test" to every text in the document.
let updateText (xDoc:XDocument) =
"t" |> xname |> xDoc.Descendants |> Seq.iter (fun x -> x.Value <- x.Value + "_test")
xDoc
//test
changeDoc @"D:\Tmp\test.docx" @"D:\Tmp\test_copy.docx" updateText;;
Before "D:\Tmp\test.docx":
After "D:\Tmp\test_copy.docx":
No comments:
Post a Comment