【问题标题】:Parse colors used in Word document, use as backcolor for ListViewItem - wrong color解析 Word 文档中使用的颜色,用作 ListViewItem 的背景颜色 - 颜色错误
【发布时间】:2016-02-07 18:12:36
【问题描述】:

我正在尝试列出 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。

不幸的是,这适用于已经包含彩色文本且颜色不受我控制的文档。所以我需要一种将“主题颜色”包含在其中的方法。

Edit2: 看起来我的问题的答案就在这里:Office 2007 [and higher] interop: retrieve RGB-color 或者基本上在链接的页面中:http://www.wordarticles.com/Articles/Colours/2007.php#UIConsiderations

我会自己解决这个问题,希望能从主题颜色中获得正确的颜色值。

【问题讨论】:

  • 试试:Font.TextColor.RGB
  • @CindyMeister 没有区别。不适用于主题颜色。而且我发现的 VBA 代码很难筛选。
  • 有趣,对我来说,它同时选择了“色轮”和主题颜色...无论如何,很高兴您找到了解决方案,而且看起来不错:-)
  • @CindyMeister 接电话?是的。但正确吗?尝试使用 Word 中的读取值来查找该颜色的文本。 that 是否适用于主题颜色?如果是:您使用的是哪个 Word 版本?一旦我们升级到更高的 Office 版本可能会很有趣。
  • 如果我理解正确,那么是的,它确实有效。 Word 2010。这是相关的代码行(宏记录)。颜色值与 TextColor.RGB 返回的值相匹配,运行录制的宏有效:.Find.Font.Color = -603923969

标签: c# ms-word office-interop


【解决方案1】:

现在得到了令人满意的结果。 我首先做的是

  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

编辑 唉,这似乎不适用于某些灰色主题。但是我需要它来处理这些。

因此:使用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);
                    }
                }
            }
        }
    }
}

【讨论】:

  • @CindyMeister 感谢您迄今为止的想法。我想我最好尝试一种使用 Open XML SDK 的新方法。我将更容易访问使用的主题并使用自定义 ListViewItem 类来存储所有必要的值。毕竟我需要对彩色项目做点什么,而我一直遇到主题灰色的问题,因为它们后来顽固地拒绝在文档中找到。 Grrrr ... :)
猜你喜欢
  • 1970-01-01
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-07
  • 2012-07-10
相关资源
最近更新 更多