Office 2007 互操作:检索RGB颜色

更新:如果您需要在office文档(格式2007)中确定rgb-color,请查看下面的答案。

有:

  • 来自VS2010 PIA的Interop.Word.dll ver.14,
  • VS2010 Express Edition
  • MS Word 2010(第14版)
  • .docx文件在没有Interop的情况下手工制作。 文件包含几个带有彩色角单元格的表。

目的:使用Interop构建另一个.docx文件,其中包含基于角落颜色填充渐变颜色的表格。
问题出现的地方:我需要将表格角落中的颜色从WdColorSystem.Drawing.Color来计算渐变。 所以我使用单元格的Shading.BackgroundPatternColor属性。 我发现有时它包含正确的BGR 24位值,有时它不包含。
第二种情况仅在单元格具有主题调色板颜色之一时出现(标准和rgb调色板颜色效果很好,但主题调色板颜色会导致问题)。 例如,当我设置0x00F2F2F2 (最0x00F2F2F2的灰色)颜色时,它会在document.xml正确存储.docx文件存档,但Shading.BackgroundPatternColor属性设置为0xDC00F2FF 。 所以ColorTranslator.FromOle返回不同的颜色。
顺便说一句,这个灰色的枚举没有WdColor。 由于.Net Reflector,最硬的灰色wdColorGray05 = 0xF3F3F3 。 这意味着并非所有调色板默认颜色都对应于枚举颜色。
此外,如果我在Word中的RGB调色板中手动设置相同的颜色(即0x00F2F2F2 ),保存文件并通过Interop再次打开 – 颜色将正确设置为0x00F2F2F2
问:有人有这个问题吗? 如何从Shading.BackgroundPatternColor属性中正确检索RGB颜色? 为什么此属性与document.xml存储的值不对应?

这是我第二次从办公文档中检索RGB颜色时遇到问题。 第一次是Excel 2007 .xlsx文件格式,现在它是Word 2010 .docx(尽管仍然是2007格式)。 所以经过一番搜索,我决定回答所有那些会遇到同样麻烦的人的问题。

有关更深入的解释和示例,我将向您发送帮助我很多的文章 。 由于本文中使用的示例可能对于C#开发人员来说可能更难以阅读,因为它们是在VBA上编写的,因此我附加了链接到我的rgb颜色检索器的实现 。

所以。 如果您打开其中一个Office程序(特别是Excel或Word),您可以设置大多数对象,文本,背景等的颜色。还有一个对话框显示选择它。 在Office 2007或更高版本中,您将看到一组10种standard颜色和based on theme的60种颜色。 如果单击“更多颜色…”,您将能够从预定颜色集或RGB调色板中选择颜色。

从该对话框中选择颜色的方式决定了存储颜色的格式。 存储颜色值的属性是32位整数,其中第1个最重要的字节(我们称之为FormatByte )用于格式规范,而另一个24位用于颜色值或其他任何东西(让我们称之为24位ColorValue )。 这里有可能的格式规范:

  • FormatByte == 0x00
    ColorValue是常见的BGR值。 在C#中,您可以通过ColorTranslator.FromOle(ColorValue);检索RGB ColorTranslator.FromOle(ColorValue); 。 当您选择标准颜色或“更多颜色…”对话框(预定或调色板)中的一种颜色时,将使用此格式。

  • FormatByte == 0xFF
    ColorValue将为0x000000。 它是wdColorAutomatic值。 这是一种对比色,这就是我所知道的(在我的例子中,它总是白色为背景,黑色为字体)。 还没有研究过它。

  • FormatByte == 0x80
    ColorValue将在[0x000000,0x000018]范围内。 您可以在文档中的ActiveX控件中遇到这些颜色。 这是一个系统KnownColors (有KnownColorsSystem.Drawing.KnownColor ,它包含了这些值)。 如果我理解得对,你也可以通过ColorTranslator.FromOle(_color);检索RGB ColorTranslator.FromOle(_color); ,其中_color是所有32位属性值,因为由于ColorTranslator.FromOle()的反映实现,它检查颜色是否来自KnownColor枚举。 但在解析Office文件时,我从未遇到过这些值。

  • FormatByte in range [0xD4, 0xDF]
    在这种情况下,您将based on theme处理颜色。 它表示基色和色调或阴影偏移的指数。

让我们深入研究最后一个案例,因为存在更多困难。
如您所见, FormatByte的前半部分始终为0xD ,另一半从0x4变为0xF 。 下半部分是10种基色中的一种的指数。

在Word中有一个wdThemeColorIndex枚举用于该索引,它可以转换为更基本的Office msoThemeColorSchemeIndex枚举(它放在Microsoft.Office.Core.dll ,可以从tabPage .COM链接到Microsoft Office XX.0 Object Library ,其中XX。 0 – Office版本)。 您可以查看上面链接的文章,用于翻译表或VBA函数,或者我的实现到C#方法。 从这个msoThemeColorSchemeIndex我们可以通过ActiveDocument.DocumentTheme获得RGB属性。
然后我们从ColorValue检索色调或阴影,将ColorValue转换为HSL(色调,饱和度,亮度),对其应用色调或阴影并将结果转换回RGB。