在Excel中的CellValue中更改文本的字体颜色-OpenXml

时间:2018-11-08 19:14:22

标签: c# spreadsheet openxml

我如何在Excel中更改CellValue的文本颜色,我能够更改Cell的复杂颜色,但是它更改了我不想要的单元格内存在的所有文本的颜色,我只想突出显示Cell旁边的特定文本即CellValue文本。

我正在使用下面的代码将“单元格文本”突出显示为,如何为CellValue完成它? -

DeletePage

我在CellValue中看不到Style的任何属性

//.....
$pdf = new TCPDF_HELPER('L', 'pt',
array(8*72,5*72), true, 'UTF-8', false);

// set auto page breaks
$pdf->SetAutoPageBreak(FALSE, 0);

// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->setFontSubsetting(true);

$fontname = TCPDF_FONTS::addTTFfont(dirname(__FILE__).'/playtime.ttf', 'TrueTypeUnicode', '', 96);
$pdf->setFont($fontname, '', 16);

//I'm using a points and a ridiculous 19 inch by 19 inch custom size.
//We'll use this one to get the proper offset with `GetY`
$pdf->AddPage('L', array(19*72, 19*72));

$pdf->SetXY(1, 45);
$pdf->setFillColor(255,255,230);

$column = <<<EOT
<p>WHITE APPLE COUNTRY HORSE STABLE BATTERY PIG SHEEP KANE CICI LOLIPOP</p>
<p>WHITE APPLE COUNTRY HORSE STABLE BATTERY PIG SHEEP KANE CICI LOLIPOP</p>
<p>WHITE APPLE COUNTRY HORSE STABLE BATTERY PIG SHEEP KANE CICI LOLIPOP ioj</p>
<p>WHITE APPLE COUNTRY HORSE STABLE BATTERY PIG SHEEP KANE CICI LOLIPOP ioj</p>
EOT;

//Get our multicell's final offset.
$pdf->WriteHTMLCell(80, '', '', 40, $column, 1, 2, 1, false, 'J', true);
$stopposition = $pdf->GetY();

//Now that we have our needed coordinates,
//Add a new page in our desired format.
$pdf->AddPage('L', array(8*72,5*72));
$pdf->StartTransform();
$pdf->Rotate(90, 40, 70);
$pdf->WriteHTMLCell(80, '', '', 40, $column, 1, 0, 1, true, 'J', true);
$pdf->StopTransform();

$pdf->SetX(20);
$pdf->SetY(-20);
$pdf->Write('', "End of column, pre-rotation: $stopposition pt");

//Delete our larger calculation page.
$pdf->DeletePage(1);
//.....

OpenXML工具生成的代码-

foreach (DocumentFormat.OpenXml.Spreadsheet.Cell currentCell in allCells)
{    
Fill fill = new Fill()
    {
         PatternFill = new PatternFill
         {
             PatternType = PatternValues.Solid,
             ForegroundColor = new ForegroundColor() { Rgb = "FFFF00" }
          }
    };
    styleSheet.Fills.AppendChild(fill);

   //Adding the  CellFormat which uses the Fill element 
    CellFormats cellFormats = styleSheet.CellFormats;
    CellFormat cf = new CellFormat();
    cf.FillId = styleSheet.Fills.Count;
    cellFormats.AppendChild(cf);
    currentCell.StyleIndex = styleSheet.CellFormats.Count;
}

1 个答案:

答案 0 :(得分:1)

您必须通过SharedStringItem元素。
这样的SharedStringItem 可以包含Run个元素。
您可以在此Run元素上应用样式。

重要的是,您的代码还应涵盖SharedStringItem不包含任何Run子元素的情况。 当单元格仅保存文本而没有任何格式化的子元素时,就是这种情况。
在这里,您必须创建一个新的Run才能应用样式。

下面的代码使用Excel文件将第一行中单元格的单词RED的颜色设置为红色,如下图所示。
单元格A1包含Run个元素,单元格B1不包含。

input

最终结果看起来像

result

String pathToYourExcelFile = @"C:\Folder\ExcelFile.xlsx";
using (SpreadsheetDocument document = SpreadsheetDocument.Open(pathToYourExcelFile, true))
{
    WorkbookPart workbook =  document.WorkbookPart;                
    WorksheetPart firstWorksheet = document.WorkbookPart.WorksheetParts.FirstOrDefault();
    SharedStringTablePart stringTable = workbook.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();                              

    IEnumerable<Row> rows = firstWorksheet.Worksheet.GetFirstChild<SheetData>().Elements<Row>();
    Row firstRow = rows.FirstOrDefault();

    foreach (Cell cell in firstRow.Elements<Cell>())
    {                    
        foreach (CellValue cellValue in cell.Elements<CellValue>())
        {   
            IEnumerable<SharedStringItem> sharedStrings = 
                stringTable.SharedStringTable.Elements<SharedStringItem>()
                    .Where((o, i) => i == Convert.ToInt32(cellValue.InnerText));

            foreach (SharedStringItem sharedString in sharedStrings)
            { 
                IEnumerable<Run> runs = sharedString.Elements<Run>();
                if (runs.Count() > 0)
                {                                
                    foreach (Run run in runs)
                    {
                        if (run.InnerText == "RED")
                        {
                            RunProperties properties = run.RunProperties ?? new RunProperties();
                            Color color = properties.Elements<Color>().FirstOrDefault();
                            if (color != null)
                            {
                                properties.RemoveChild<Color>(color);
                            }

                            properties.Append(new Color { Rgb = "FFFF0000" }) ;
                        }
                    }
                }
                else
                {       
                    // No Runs, only text; create a Run.                                                     
                    Text text = new Text(sharedString.InnerText);                                
                    sharedString.RemoveAllChildren();
                    Run run = new Run();
                    run.Append(text);
                    run.RunProperties = new RunProperties();
                    run.RunProperties.Append(new Color { Rgb = "FFFF0000" }) ;
                    sharedString.Append(run);
                }
            }
        }
    }

    document.Save();

我将上面代码中的清理和异常处理留给您...


编辑

对于您的特定情况,单元格值为“ Microsoft很棒”, 您必须将此字符串拆分为单独的部分,并为每个部分创建一个Run。 仅在文本值为“ Microsoft”的部分上应用自定义字体颜色。

下面的简约代码显示了这一概念。

此代码可以使用一些改进,因为最好不要拆分成单独的单词,但是您会明白...
// No Runs, only text.              

const String MS = "Microsoft";
String innerText = sharedString.InnerText;
if (innerText.IndexOf(MS, StringComparison.OrdinalIgnoreCase) >= 0)
{ 
    sharedString.RemoveAllChildren();

    String[] parts = innerText.Split(' ');
    for (Int32 i = 0; i < parts.Length; i++)
    {
        String part = parts[i];
        Text text = new Text((i > 0 ? " " : String.Empty) + part);
        text.Space = SpaceProcessingModeValues.Preserve;         

        Run run = new Run();                                        
        run.Append(text);

        if (part.Equals(MS, StringComparison.OrdinalIgnoreCase))
        {
            run.RunProperties = new RunProperties();
            run.RunProperties.Append(new Color { Rgb = "FFFF0000" }) ;
        }

        sharedString.Append(run);                                        
    }

下图显示了之前和之后。

Before and after


编辑

针对您对如何遍历Excel文档中所有单元格的评论;参见下面的代码。

String pathToYourExcelFile = @"C:\Folder\ExcelFile.xlsx";
using (SpreadsheetDocument document = SpreadsheetDocument.Open(pathToYourExcelFile, true))
{
    WorkbookPart workbook =  document.WorkbookPart;

    // Loop over all worksheets.
    IEnumerable<WorksheetPart> worksheets = document.WorkbookPart.WorksheetParts;
    foreach (WorksheetPart worksheet in worksheets)
    {
        // Loop over all rows.
        IEnumerable<Row> rows = worksheet.Worksheet.GetFirstChild<SheetData>().Elements<Row>();   
        foreach (Row row in rows) 
        {
            // Loop over all cells.
            foreach (Cell cell in row.Elements<Cell>())
            {
                // Loop over all cell values.
                foreach (CellValue cellValue in cell.Elements<CellValue>())
                {
                    // Apply content formatting as in code above ...
                }
            }
        }
    }
}
相关问题