2012-05-25 33 views
6

我想要在Excel電子表格中獲取單元格的背景顏色。我使用的是Open XML 2.0 SDK,我可以打開* .xlsx文件並獲取單元格值。我對獲得背景顏色代碼如下:使用Open XML 2.0在Excel中獲取cell-backgroundcolor

public BackgroundColor GetCellBackColor(Cell theCell, SpreadsheetDocument document) 
    { 
     BackgroundColor backGroundColor = null; 
     WorkbookStylesPart styles = SpreadsheetReader.GetWorkbookStyles(document); 
     int cellStyleIndex = (int)theCell.StyleIndex.Value; 
     CellFormat cellFormat = (CellFormat)styles.Stylesheet.CellFormats.ChildElements[cellStyleIndex]; 
     Fill fill = (Fill)styles.Stylesheet.Fills.ChildElements[(int)cellFormat.FillId.Value]; 
     backGroundColor = fill.PatternFill.BackgroundColor; 

     return backGroundColor; 
    } 

我這裏的問題,即PatternFill.BackgroundColor回報只是一個自然數,我認爲這是風格的ID。我的問題是,代碼

DocumentFormat.OpenXml.Spreadsheet.Color c = (DocumentFormat.OpenXml.Spreadsheet.Color)styles.Stylesheet.Colors.ChildElements[Int32.Parse(backGroundColor.InnerText)]; 

返回一個錯誤的路線,因爲Stylesheet.Colorsnull ......也許是因爲我使用了「中建」顏色在Excel中 - 而不是一個自定義的顏色?!

任何想法如何「計算」從「backGroundColor-Value」真實的顏色數?

+0

類SpreadsheetReader不存在的OpenXML 2.5 – Elmue

回答

10

excel電子表格中單元格的填充圖案是由兩種顏色組成的 :背景顏色和前景色。 術語前景色在這裏有點誤導。它不是字體的 顏色,而是圖案填充的前景顏色。

例如,如果你填充單元格的背景以純色 被設定爲,其中作爲BackgroundColor對象 被設置爲系統已選定固體色值的小區的相關型號PatternFill對象的ForegroundColor屬性前景色。對象的PatternType屬性 PatternFill對象設置爲PatternValues.Solid

因此,要獲取您的單元格背景的顏色值(實心填充),您必須分析PatternFill對象的 ForegroundColor屬性。你必須 確定「型色」的實例表示:

  1. 的自動色彩和系統相關的顏色
  2. 的索引顏色。
  3. ARGB顏色(alpha,紅色,綠色和藍色)
  4. 基於主題的顏色。
  5. 應用於顏色的色調值。

有關不同「顏色類型」的更多信息,請參閱以下 link

請注意,ForegroundColorBackgroundColor 類的InnerText屬性的含義取決於顏色類型。例如,在基於主題的顏色的情況下,InnerText屬性 被設置爲ColorScheme集合的索引。

下面的例子打印的電子表格文檔中的所有單元中的所有背景顏色信息:

public static PatternFill GetCellPatternFill(Cell theCell, SpreadsheetDocument document) 
{ 
    WorkbookStylesPart styles = SpreadsheetReader.GetWorkbookStyles(document); 

    int cellStyleIndex; 
    if (theCell.StyleIndex == null) // I think (from testing) if the StyleIndex is null 
    {        // then this means use cell style index 0. 
    cellStyleIndex = 0;   // However I did not found it in the open xml 
    }        // specification. 
    else 
    { 
    cellStyleIndex = (int)theCell.StyleIndex.Value; 
    }  

    CellFormat cellFormat = (CellFormat)styles.Stylesheet.CellFormats.ChildElements[cellStyleIndex]; 

    Fill fill = (Fill)styles.Stylesheet.Fills.ChildElements[(int)cellFormat.FillId.Value]; 
    return fill.PatternFill; 
} 

private static void PrintColorType(SpreadsheetDocument sd, DocumentFormat.OpenXml.Spreadsheet.ColorType ct) 
{ 
    if (ct.Auto != null) 
    { 
    Console.Out.WriteLine("System auto color"); 
    } 

    if (ct.Rgb != null) 
    { 
    Console.Out.WriteLine("RGB value -> {0}", ct.Rgb.Value); 
    } 

    if (ct.Indexed != null) 
    { 
    Console.Out.WriteLine("Indexed color -> {0}", ct.Indexed.Value); 

    //IndexedColors ic = (IndexedColors)styles.Stylesheet.Colors.IndexedColors.ChildElements[(int)bgc.Indexed.Value];   
    } 

    if (ct.Theme != null) 
    { 
    Console.Out.WriteLine("Theme -> {0}", ct.Theme.Value); 

    Color2Type c2t = (Color2Type)sd.WorkbookPart.ThemePart.Theme.ThemeElements.ColorScheme.ChildElements[(int)ct.Theme.Value]; 

    Console.Out.WriteLine("RGB color model hex -> {0}", c2t.RgbColorModelHex.Val); 
    } 

    if (ct.Tint != null) 
    { 
    Console.Out.WriteLine("Tint value -> {0}", ct.Tint.Value); 
    } 
} 

static void ReadAllBackgroundColors() 
{ 
    using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open("c:\\temp\\bgcolor.xlsx", false)) 
    { 
    WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart; 
    foreach(WorksheetPart worksheetPart in workbookPart.WorksheetParts) 
    { 
     SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First(); 

     foreach (Row r in sheetData.Elements<Row>()) 
     { 
     foreach (Cell c in r.Elements<Cell>()) 
     {    
      Console.Out.WriteLine("----------------"); 
      PatternFill pf = GetCellPatternFill(c, spreadsheetDocument);   

      Console.Out.WriteLine("Pattern fill type -> {0}", pf.PatternType.Value); 

      if (pf.PatternType == PatternValues.None) 
      { 
      Console.Out.WriteLine("No fill color specified"); 
      continue; 
      } 

      Console.Out.WriteLine("Summary foreground color:"); 
      PrintColorType(spreadsheetDocument, pf.ForegroundColor); 
      Console.Out.WriteLine("Summary background color:"); 
      PrintColorType(spreadsheetDocument, pf.BackgroundColor);       
     } 
     }  
    } 
    } 
} 

static void Main(string[] args) 
{ 
    ReadAllBackgroundColors(); 
} 
+0

謝謝你的偉大的答案。只需要添加一點:如果我不更改單元格的樣式,那麼'int cellStyleIndex =(int)theCell.StyleIndex.Value;'行會導致null異常。我怎麼能確定地知道它實際上是默認樣式和「什麼」樣式(顏色等)? Thx提前! – basti

+1

@chiffre:我認爲(我做了一些測試)如果StyleIndex爲null,您必須使用單元格樣式索引0.但是,我沒有在open xml規範中找到關於它的註釋。 – Hans

+0

感謝您的信息。真的需要一個好的完整的包裝 - 在這裏你可以簡單地調用「cell.GetColor」等。(和那實際上工作;)) – basti

相關問題