【问题标题】:Better way of getting Font info from openxml从 openxml 获取字体信息的更好方法
【发布时间】:2013-03-28 02:06:57
【问题描述】:

我正在使用 OpenXML 填写一种模板 Word 文件(不是 .dot)。我遇到的问题是,当我向文档添加新文本时,会使用 Word 文档的默认字体和字体大小。 我希望它使用我要添加到的段落的字体和大小,或者我要添加到的现有表格中的格式。

我找到了一种方法,但我认为它不是一个好方法。 那么...有没有更好的方法呢?

这是一段话

    private RunProperties GetRunPropertyFromParagraph(Paragraph paragraph)
    {
        var runProperties = new RunProperties();
        var fontname = "Calibri";
        var fontSize = "18";
        try
        {
            fontname =
                paragraph.GetFirstChild<ParagraphProperties>()
                         .GetFirstChild<ParagraphMarkRunProperties>()
                         .GetFirstChild<RunFonts>()
                         .Ascii;
        }
        catch
        {
            //swallow
        }
        try
        {
            fontSize =
                paragraph.GetFirstChild<Paragraph>()
                         .GetFirstChild<ParagraphProperties>()
                         .GetFirstChild<ParagraphMarkRunProperties>()
                         .GetFirstChild<FontSize>()
                         .Val;
        }
        catch
        {
            //swallow
        }
        runProperties.AppendChild(new RunFonts() { Ascii = fontname });
        runProperties.AppendChild(new FontSize() { Val = fontSize });
        return runProperties;
    }

这个来自 TableCell

    private RunProperties GetRunPropertyFromTableCell(TableRow rowCopy, int cellIndex)
    {
        var runProperties = new RunProperties();
        var fontname = "Calibri";
        var fontSize = "18";
        try
        {
            fontname =
                rowCopy.Descendants<TableCell>()
                       .ElementAt(cellIndex)
                       .GetFirstChild<Paragraph>()
                       .GetFirstChild<ParagraphProperties>()
                       .GetFirstChild<ParagraphMarkRunProperties>()
                       .GetFirstChild<RunFonts>()
                       .Ascii;
        }
        catch
        {
            //swallow
        }
        try
        {
            fontSize =
                   rowCopy.Descendants<TableCell>()
                          .ElementAt(cellIndex)
                          .GetFirstChild<Paragraph>()
                          .GetFirstChild<ParagraphProperties>()
                          .GetFirstChild<ParagraphMarkRunProperties>()
                          .GetFirstChild<FontSize>()
                          .Val;
        }
        catch
        {
            //swallow
        }
        runProperties.AppendChild(new RunFonts() { Ascii = fontname });
        runProperties.AppendChild(new FontSize() { Val = fontSize });
        return runProperties;
    }

代码有效。至少在我尝试过的文件中。 但这似乎是一种糟糕的方法,但我还没有找到更好的解决方案,所以如果你有,请分享:)

【问题讨论】:

    标签: c# openxml openxml-sdk


    【解决方案1】:

    我这样做: 当我更新或替换一个 Run 时,我确保检查何时删除旧的东西,一个元素是否有子元素,然后它是否有一个子元素是“RunProperties”。 如果是这样,我只需保存这些属性并在删除旧内容后将它们添加到我的新 Run 中。

    还没有让我失望。

    var bkms = YourBookmarkStart;
    OpenXmlElement elem = bkms.NextSibling();
    RunProperties oldRunProperties = null;
    while (elem != null && !(elem is BookmarkEnd))
    {
        OpenXmlElement nextElem = elem.NextSibling();
        if (elem.HasChildren)
        {
            try
            {
                 oldRunProperties = (RunProperties)elem.GetFirstChild<RunProperties>().Clone();
            }
            catch { }
        }
        if (!(elem is BookmarkStart))
            elem.Remove();
        elem = nextElem;
    }
    
    Run r = new Run(new Text(newText));
    if (oldRunProperties != null) r.PrependChild<RunProperties>(oldRunProperties);
    bkms.Parent.InsertAfter<Run>(r, bkms);
    

    它应该抓取给定段落的任何运行属性,除非它没有任何属性,在这种情况下它不会添加任何内容,因此使用文档中的任何默认值。

    【讨论】:

    • 这种方法的问题是 RunProperties 只有在运行时才存在。可能有一个没有运行的段落,在这种情况下,我认为您需要 ParagraphMarkRunProperties,但不确定如何在您向该段落添加运行时使用它。
    猜你喜欢
    • 2019-05-28
    • 2015-04-27
    • 2011-10-11
    • 1970-01-01
    • 2010-11-19
    • 2010-09-20
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多