解析Word文档中使用的颜色,用作ListViewItem的背景颜色 - 颜色错误

时间:2015-11-06 14:52:16

标签: c# ms-word office-interop

我试图列出Word文档中使用的所有字体颜色,将它们显示为彩色ListViewItems。

我可以解析文档并获得所有独特的字体颜色。

什么不起作用? - 使ListViewItems以正确的颜色。 Grey35显示为黄色,绿色显示为深绿色。

以下是我的有效代码部分

var maxnum = doc.Words.Count;
var ind = 0;
foreach (Word.Range wd in doc.Content.Words)
{
    if (!string.IsNullOrEmpty(wd.Text.Trim('\r', '\n', ' ')))
    {
        ind++;
        bkwParseColors.ReportProgress(100*ind/maxnum, wd.Font.Color);
    }
}

这就是我用它做的事情:

private void bkwParseColors_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
    var color = (Word.WdColor)e.UserState;
    var drin = lstColors.FindItemWithText(color.GetHashCode().ToString());
    if(drin==null)
    {
        var li = new ListViewItem(color.GetHashCode().ToString());
        li.BackColor = ColorTranslator.FromOle((int) color);
        lstColors.Items.Add(li);
    }
}
唉,而不是灰色,我变黄了,而不是Word的绿色,我得到一个黑暗,全绿色,而不是浅灰色,我得到一个黑色的50%灰色(至少更暗)。唯一正确的颜色是黑色。

在调试过程中,我还发现第一个灰色(在ListView中转换为黄色)列为wdWhite。 : - ??

它几乎看起来我只是得到了全彩色"缺少一些价值(轻盈)。 有人能告诉我如何获得正确的颜色吗?

使用Word 2010,VS Community 2013,Framework 4.0。

编辑:我似乎越来越近了!

==>行为是不同的取决于我是否使用"主题颜色"单击文本颜色时直接出现,或者是否单击"更多颜色"然后从色轮中选择一个!如果我从色轮上着色文字,我似乎得到了正确的值,包括灰色。如果我使用首先出现的默认调色板中的灰色,则灰色表示为"白色,背景1,较暗的xx%",这将解释wdWhite。

不幸的是,这适用于已经包含彩色文本的文档,并且着色不在我的控制之下。所以我需要一种方法来包含"主题颜色"进入这个。

编辑2:我的问题的答案似乎在于:Office 2007 [and higher] interop: retrieve RGB-color 或者基本上在链接的页面中http://www.wordarticles.com/Articles/Colours/2007.php#UIConsiderations

我将通过这个工作,希望从主题颜色中获得正确的颜色值。

1 个答案:

答案 0 :(得分:2)

现在获得满意的结果。 我最初做的是

  1. 使用pkuderov的RgbColorRetriever类作为链接 接受了这个主题的回答:Office 2007 [and higher] interop: retrieve RGB-color
  2. 由于生成的系统颜色比Word颜色稍暗,我还应用了Pavel Vladov在此主题中提出的闪电效果(第二个答案,不是接受的答案):C#: Create a lighter/darker color based on a system color
  3. 编辑唉,这似乎不适用于某些主题灰色。但是我需要它也可以使用它们。

    因此:使用Open XML SDK的替代解决方案:

    private void bkwParseColors_DoWork(object sender, DoWorkEventArgs e)
    {
        var docItem = (string) e.Argument;
        using (var docx = WordprocessingDocument.Open(docItem, false))
        {
            var ind = 0;
            var maxnum = docx.MainDocumentPart.Document.Descendants<Run>().Count();
            foreach (Run rText in docx.MainDocumentPart.Document.Descendants<Run>())
            {
                if (rText.RunProperties != null)
                {
                    if (rText.RunProperties.Color != null)
                    {
                        ind++;
                        bkwParseColors.ReportProgress(100*ind/maxnum, rText.RunProperties.Color);
                    }
                }
            }
        }
    }
    

    以正确的颜色创建ListViewItem并存储Word颜色值和主题颜色的进度更改方法:

    private void bkwParseColors_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    
        var color = (DocumentFormat.OpenXml.Wordprocessing.Color)e.UserState;
        var thema = "";
        if (color.ThemeColor!=null)
            thema = color.ThemeColor.Value.ToString();
    
        var farbe = color.Val.Value; //hex RGB
        var drin = lstColors.FindItemWithText(farbe);
        if(drin==null)
        {
            var li = new myListItem
            {
                Design = thema,
                Farbe = farbe,
                Text = farbe,
                BackColor = ColorTranslator.FromHtml("#" + farbe)
            };
            lstColors.Items.Add(li);
        }
    }
    

    一些额外的信息:我需要所有这些因为我需要隐藏/取消隐藏某种颜色的文本,但这种颜色永远不会确定,即取决于客户的想法和/或文档中已经使用的颜色。 ..

    因此,为了完成,我将隐藏文档中的所有文本,除了所选颜色的文本外:

    private void bkwEinblenden_DoWork(object sender, DoWorkEventArgs e)
    {
        var args = (List<object>) e.Argument;
        var pfad = (string) args[0];
        var color = (myListItem) args[1];
        using (var docx = WordprocessingDocument.Open(pfad, true))
        {
            var ind = 0;
            var maxnum = docx.MainDocumentPart.Document.Descendants<Run>().Count();
            foreach (Run rText in docx.MainDocumentPart.Document.Descendants<Run>())
            {
                bkwEinblenden.ReportProgress(100*ind/maxnum);
                var vanish = new Vanish() { Val = OnOffValue.FromBoolean(true) };
                if (rText.RunProperties == null)
                {
                    var runProp = new RunProperties {Vanish = vanish};
                    rText.RunProperties = runProp;
                }
                else
                {
                    if (rText.RunProperties.Vanish == null)
                        rText.RunProperties.Vanish = vanish;
                    else
                    {
                        rText.RunProperties.Vanish.Val = OnOffValue.FromBoolean(true);
                    }
                }
                if (rText.RunProperties.Color != null)
                {
                    if (rText.RunProperties.Color.Val == color.Farbe)
                    {
                        if (!string.IsNullOrEmpty(color.Design))
                        {
                            if (rText.RunProperties.Color.ThemeColor.Value.ToString() == color.Design)
                            {
                                rText.RunProperties.Vanish.Val = OnOffValue.FromBoolean(false);
                            }
                        }
                        else
                        {
                            rText.RunProperties.Vanish.Val = OnOffValue.FromBoolean(false);
                        }
                    }
                }
            }
        }
    }