在F#中读取和更新OpenXML

时间:2014-10-13 21:58:51

标签: f#

我无法获取此F#代码来读取和更新Word文档中的内容控制文本字段。 第二个函数绝对没有任何内容,第一个函数产生了这个错误:类型为#System; InvalidOperationException'的未处理异常。发生在System.Core.dll中 附加信息:序列不包含任何元素

namespace OpenXML

open DocumentFormat.OpenXml
open DocumentFormat.OpenXml.Packaging
open DocumentFormat.OpenXml.Wordprocessing
open System.Linq
// Add the DocumentFormat.OpenXml assembly
// Add the WindowsBase assembly

module public Word =

    let query_plain_text_content_control document_path_and_file_name content_control_tag =
        use theDoc = WordprocessingDocument.Open((document_path_and_file_name :string), true)
        let mainPart = theDoc.MainDocumentPart
        let block = mainPart.Document.Body.Descendants<SdtElement>().Where(fun r -> r.SdtProperties.GetFirstChild<Tag>().Val = content_control_tag).Single()
        let t = block.Descendants<Text>().FirstOrDefault()
        t.Text

    let update_plain_text_content_control document_path_and_file_name content_control_tag new_text = async {
        use theDoc = WordprocessingDocument.Open((document_path_and_file_name :string), true)
        let mainPart = theDoc.MainDocumentPart
        let block = mainPart.Document.Body.Descendants<SdtElement>().Where(fun r -> r.SdtProperties.GetFirstChild<Tag>().Val = content_control_tag).Single()
        let t = block.Descendants<Text>().FirstOrDefault()
        t.Text <- new_text
        mainPart.Document.Save() |> ignore
    }

1 个答案:

答案 0 :(得分:1)

似乎工作正常,只需进行一些调整:

#r@"DocumentFormat.OpenXml.dll"
#r"WindowsBase.dll"
open DocumentFormat.OpenXml
open DocumentFormat.OpenXml.Packaging
open DocumentFormat.OpenXml.Wordprocessing
open System.Linq
// Add the DocumentFormat.OpenXml assembly
// Add the WindowsBase assembly

module public Word =

    let query_plain_text_content_control document_path_and_file_name content_control_tag =
        use theDoc = WordprocessingDocument.Open((document_path_and_file_name :string), true)
        let mainPart = theDoc.MainDocumentPart
        let block = mainPart.Document.Body.Descendants<SdtElement>().Where(fun r -> r.SdtProperties.GetFirstChild<Tag>().Val.ToString() = content_control_tag).Single()
        let t = block.Descendants<Text>().FirstOrDefault()
        t.Text

    let update_plain_text_content_control document_path_and_file_name content_control_tag new_text = async {
        use theDoc = WordprocessingDocument.Open((document_path_and_file_name :string), true)
        let mainPart = theDoc.MainDocumentPart
        let block = mainPart.Document.Body.Descendants<SdtElement>().Where(fun r -> r.SdtProperties.GetFirstChild<Tag>().Val.ToString() = content_control_tag).Single()
        let t = block.Descendants<Text>().FirstOrDefault()
        t.Text <- new_text
        mainPart.Document.Save() |> ignore
    }
    let oldtext = query_plain_text_content_control @".\text.docx" "ctrltag"

    let update = update_plain_text_content_control @".\text.docx" "ctrltag" "new text"
    Async.RunSynchronously(update)
    let newtext = query_plain_text_content_control @".\text.docx" "ctrltag"

..在包含单个纯文本内容控件的文档中,标记为“ctrltag”,内容为“旧文本”,我得到:

val oldtext : string = "Old text"
val update : Async<unit>
val newtext : string = "new text"

在'r.SdtProperties.GetFirstChild()。Val'上没有调用.ToString(),我收到了这个错误:

The type 'string' is not compatible with the type 'StringValue'.

您的文档可能存在问题?您收到的错误似乎表明没有指定标记的内容控件。