【问题标题】:Change font color in OpenXML word document (C#)更改 OpenXML Word 文档中的字体颜色(C#)
【发布时间】:2012-10-30 22:45:04
【问题描述】:

我一直在寻找几个小时,但我似乎无法找到一个可靠的答案。我有一个包含内容控件的现有文档,我需要使用外部数据编辑文本。如果其中一个控件的数据不存在,那么我需要用适当的通知替换文本并更改字体颜色。

我的文本输入和所有工作都很好,唯一似乎无法完成工作的部分是更改字体颜色。我当前的代码没有给我任何错误,并且可以很好地运行此方法,但是当我查看完成的文档时,它仍然是纯黑色文本。

我的换色方法:(输入的是所有同标签的内容控件的列表)

public void SetBlueText(List<SdtElement> sdtElement)
{
    foreach (SdtElement element in sdtElement)
    {
        if (element != null)
        {
            RunProperties runProperties = element.Descendants<RunProperties>().FirstOrDefault();
            runProperties.Color = new DocumentFormat.OpenXml.Wordprocessing.Color() { Val = "0EBFE9" };
        }
    }
}

此外,将这两行简化为仅此 / 具有相同的效果

element.Descendants<RunProperties>().FirstOrDefault().Color = 
                        new DocumentFormat.OpenXml.Wordprocessing.Color() { Val = "0EBFE9" };

【问题讨论】:

    标签: c# openxml


    【解决方案1】:

    我遇到了类似的问题,发现由于某种原因,您将对象附加到 RunProperties 对象的顺序实际上会影响格式更新是否有效(我注意到的模式是,如果您在执行之前附加文本格式,该文本的格式不会粘住)。

    例如这可行(文本变为粗体,Cambria 标题,颜色设置为蓝色)

    Run formattedRun = new Run();
    RunProperties runPro = new RunProperties();
    RunFonts runFont = new RunFonts() { Ascii = "Cambria(Headings)", HighAnsi = "Cambria(Headings)" };
    Bold bold = new Bold();
    Text text = new Text("TESTING");
    Color color = new Color() { Val = "365F91", ThemeColor = ThemeColorValues.Accent1, ThemeShade = "BF" };
    runPro.Append(runFont);
    runPro.Append(bold);
    runPro.Append(color);
    runPro.Append(text);
    formattedRun.Append(runPro);
    

    但这不是(文本变为 Cambria Headings 和 Bold,但颜色保持标准黑色)

    Run formattedRun = new Run();
    RunProperties runPro = new RunProperties();
    RunFonts runFont = new RunFonts() { Ascii = "Cambria(Headings)", HighAnsi = "Cambria(Headings)" };
    Text text = new Text("TESTING");
    Bold bold = new Bold();
    Color color = new Color() { Val = "365F91", ThemeColor = ThemeColorValues.Accent1, ThemeShade = "BF" };
    runPro.Append(runFont);
    runPro.Append(bold);
    runPro.Append(text);
    runPro.Append(color);
    formattedRun.Append(runPro);
    

    【讨论】:

      【解决方案2】:

      好吧,我有点粗暴地强迫自己找到答案,但它确实有效。

      List<RunProperties> runProps = element.Descendants<RunProperties>().ToList();
      foreach (RunProperties rp in runProps)
      {
          rp.Color = new DocumentFormat.OpenXml.Wordprocessing.Color() { Val = "0EBFE9" };
      }
      

      如果有人有更优雅的解决方案,请添加它,我会支持它。

      【讨论】:

        【解决方案3】:

        我需要与 OP 非常相似的东西,因为我在运行时填充的 word 文档模板中有一大堆纯文本和其他控件。我创建了一个扩展方法来设置文本和其他格式设置。希望这会帮助像我一样来到这里有需要的人:

            public static void ReplaceText(this SdtElement element, string replacementText, bool? isBold = null, bool? isItalic = null, System.Drawing.Color? color = null, VerticalPositionValues? textVerticalType = null, int? fontSizeComplexScript = null)
            {
        
                // First try to get content blocks from the element
                IEnumerable<SdtContentBlock> childContentBlocks = element.ChildElements.OfType<SdtContentBlock>();
        
                //Function to generate the new run properties
                RunProperties SetupNewRunProperties(RunProperties oldRunProps) { 
        
                    var props = new RunProperties();
        
                    if (fontSizeComplexScript.HasValue && fontSizeComplexScript.HasValue)
                        props.FontSizeComplexScript.Val = fontSizeComplexScript.ToString();
                    else if (oldRunProps?.FontSizeComplexScript != null)
                        props.FontSizeComplexScript = (FontSizeComplexScript)oldRunProps.FontSizeComplexScript.CloneNode(true);
        
                    if (isBold.HasValue) 
                        props.Bold.Val = OnOffValue.FromBoolean(isBold.Value);
                    else if(oldRunProps?.Bold != null)
                        props.Bold = (Bold)oldRunProps.Bold.CloneNode(true);
        
                    if (isItalic.HasValue)
                        props.Italic.Val = OnOffValue.FromBoolean(isItalic.Value);
                    else if (oldRunProps?.Italic != null)
                        props.Italic = (Italic)oldRunProps.Italic.CloneNode(true);
        
                    if (textVerticalType.HasValue)
                        props.VerticalTextAlignment.Val = textVerticalType.Value;
                    else if (oldRunProps?.VerticalTextAlignment != null)
                        props.VerticalTextAlignment = (VerticalTextAlignment)oldRunProps.VerticalTextAlignment.CloneNode(true);
        
                    if (color.HasValue)
                    {
                        if (props.Color != null)
                            props.Color.Val = color.Value.ToHexString();
                        else
                            props.Color = new Color() { Val = color.Value.ToHexString() };
                    }
                    else if (oldRunProps?.Color != null)
                    {
                        props.Color = (Color)oldRunProps?.Color.CloneNode(true);
                    }
        
                    return props;
                }
        
                if (childContentBlocks.Count() > 0)
                {
                    SdtContentBlock contentBlock = childContentBlocks.First();
                    Paragraph para = contentBlock.ChildElements.OfType<Paragraph>().First();
                    if (para != null)
                    {
                        Run run = para.GetFirstChild<Run>();
        
                        run.RunProperties = SetupNewRunProperties(run.RunProperties);
        
                        Text text = run.GetFirstChild<Text>();
                        text.Text = replacementText;
                    }
                }
                else
                {
                    // Instead, try to get content runs from the element
                    IEnumerable<SdtContentRun> childContentRuns = element.ChildElements.OfType<SdtContentRun>();
        
                    if (childContentRuns.Count() > 0)
                    {
                        Run run = childContentRuns.First().GetFirstChild<Run>();
        
                        run.RunProperties = SetupNewRunProperties(run.RunProperties);
        
                        Text text = run.GetFirstChild<Text>();
                        text.Text = replacementText;
                    }
                }
        
            }
        

        【讨论】:

          【解决方案4】:

          颜色值应为 8 位。例如 Color.Val="FFFF0000" 以红色显示字符串。

          【讨论】:

          • 这不是问题的答案。颜色可以用 6 个十六进制数字表示。仅当 alpha 应小于 100% 时才需要 8 位数字。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-04-19
          • 1970-01-01
          • 1970-01-01
          • 2015-03-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多