利用OpenXML获取Excel单元格背景色

  • 利用OpenXML获取Excel单元格背景色已关闭评论
  • 85 次浏览
  • A+
所属分类:.NET技术
摘要

最近项目上遇到了关于Excel获取处理的问题,关于Excel单元格背景色的获取,水的文章都大同小异,都没注意到Excel单元格背景色是怎么赋值,这会导致出现有些背景色无法获取的情况。(PS:其实应该叫做前景色)
关于这点我们可以先来看一下,一个Excel文档的内部有关背景色样式代码。


利用OpenXML获取Excel单元格背景色

最近项目上遇到了关于Excel获取处理的问题,关于Excel单元格背景色的获取,水的文章都大同小异,都没注意到Excel单元格背景色是怎么赋值,这会导致出现有些背景色无法获取的情况。(PS:其实应该叫做前景色)
关于这点我们可以先来看一下,一个Excel文档的内部有关背景色样式代码。

Excel背景色样式解析

  • 这是一个样例Excel,我们给它赋上了一些背景色样式,如下图所示。
    利用OpenXML获取Excel单元格背景色
  • 但是在Excel的style.xml文件中,这些颜色的表现形式不尽相同。
    利用OpenXML获取Excel单元格背景色
 -<fill>  <patternFill patternType="none"/>  </fill>   -<fill>  <patternFill patternType="gray125"/>  </fill> 

这两种为excel自带的默认填充样式

  • 因此我们可以发现,前三种背景色,Excel中是直接赋予了RGB的色值。然而最后一种颜色却是使用了theme(主题色)和tint(插值)来表示。
    通过以上分析,我们可以得出Excel单元格背景色的两种表现方式:rgbtheme + tint。(PS:关于有的颜色为什么可以直接用rgb,有的颜色用theme加tint的方式表示,本人在微软官方下面提问了,但是没人鸟窝。)

代码实现

  • OK分析完了,上代码。
public string GetCellBackgroundColor(WorkbookPart workbookPart, Cell cell) {     if (cell == null || cell.StyleIndex == null) return null;     CellFormat cellFormat = (CellFormat)workbookPart.WorkbookStylesPart.Stylesheet.CellFormats.ElementAt((int)cell.StyleIndex.Value);     Fill fill = (Fill)workbookPart.WorkbookStylesPart.Stylesheet.Fills.ElementAt((int)cellFormat.FillId.Value);     PatternFill patternFill = (PatternFill)fill.PatternFill;     ThemePart themePart = workbookPart.ThemePart;     Theme theme = themePart?.Theme;     if (patternFill != null && patternFill.PatternType != null && patternFill.PatternType.Value == PatternValues.Solid)     {         if (patternFill.ForegroundColor != null)         {             if (patternFill.ForegroundColor.Rgb != null)             {                 return "#" + patternFill.ForegroundColor.Rgb.Value;             }             else if (patternFill.ForegroundColor.Theme != null)             {                 // 主题色获取                 string originalColor = ((Color2Type)theme.ThemeElements.ColorScheme.ElementAt((int)patternFill.ForegroundColor.Theme.Value)).RgbColorModelHex.Val;                 if (patternFill.ForegroundColor.Tint != null)                 {                     // 颜色计算                     return CalculateTintedColor(originalColor, patternFill.ForegroundColor.Tint);                 }                 else                 {                     return "#" + originalColor;                 }             }         }     }     return null; }  ublic static string CalculateTintedColor(string originalColor, double tint) {     // RGB转换     int red = Convert.ToInt32(originalColor.Substring(0, 2), 16);     int green = Convert.ToInt32(originalColor.Substring(2, 2), 16);     int blue = Convert.ToInt32(originalColor.Substring(4, 2), 16);     int interpolatedRed = 0;     int interpolatedGreen = 0;     int interpolatedBlue = 0;     // 基于tint正负值的颜色计算     if (tint > 0)     {         // 白色         int white = 255;         // 插值计算         interpolatedRed = (int)Math.Round(red * (1 - tint) + white * tint);         interpolatedGreen = (int)Math.Round(green * (1 - tint) + white * tint);         interpolatedBlue = (int)Math.Round(blue * (1 - tint) + white * tint);     }     else     {         // 黑色         int black = 0;         // 插值计算         interpolatedRed = (int)Math.Round(red * (1 + tint));         interpolatedGreen = (int)Math.Round(green * (1 + tint));         interpolatedBlue = (int)Math.Round(blue * (1 + tint));         // 防止出现计算结果小于0的情况         interpolatedRed = Math.Max(interpolatedRed, black);         interpolatedGreen = Math.Max(interpolatedGreen, black);         interpolatedBlue = Math.Max(interpolatedBlue, black);     }     // 计算结束后转化为16进制颜色     string interpolatedColor = $"#{interpolatedRed:X2}{interpolatedGreen:X2}{interpolatedBlue:X2}";     return interpolatedColor; } 

分享结束,如果这个分享对您有所帮助的话,请点个赞吧!