如何更改Excel中CellValue的文本颜色?我可以更改单元格的前景色,但它会更改单元格内所有文本的颜色,这是我不想要的。我想仅突出显示单元格内的特定文本,即 CellValue 文本。
我使用下面的代码突出显示单元格文本,如何为 CellValue 完成此操作?
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;
}
Run Code Online (Sandbox Code Playgroud)
我在 CellValue 中没有看到 Style 的任何属性
CellValue currentCellValue = currentCell.GetFirstChild<CellValue>();
if (currentCell.DataType == CellValues.SharedString) // cell has a cell value that is a string, thus, stored else where
{
data = doc.WorkbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault().SharedStringTable.ElementAt(int.Parse(currentCellValue.Text)).InnerText;
}
Run Code Online (Sandbox Code Playgroud)
从 OpenXML 工具生成的代码 -
SharedStringTable sharedStringTable1 = new SharedStringTable(){ Count = (UInt32Value)1U, UniqueCount = (UInt32Value)1U };
SharedStringItem sharedStringItem1 = new SharedStringItem();
Run run1 = new Run();
RunProperties runProperties1 = new RunProperties();
FontSize fontSize3 = new FontSize(){ Val = 11D };
Color color3 = new Color(){ Rgb = "FFFF0000" };
RunFont runFont1 = new RunFont(){ Val = "Calibri" };
FontFamily fontFamily1 = new FontFamily(){ Val = 2 };
FontScheme fontScheme4 = new FontScheme(){ Val = FontSchemeValues.Minor };
runProperties1.Append(fontSize3);
runProperties1.Append(color3);
runProperties1.Append(runFont1);
runProperties1.Append(fontFamily1);
runProperties1.Append(fontScheme4);
Text text1 = new Text();
text1.Text = "Microsoft";
run1.Append(runProperties1);
run1.Append(text1);
Run run2 = new Run();
RunProperties runProperties2 = new RunProperties();
FontSize fontSize4 = new FontSize(){ Val = 11D };
Color color4 = new Color(){ Theme = (UInt32Value)1U };
RunFont runFont2 = new RunFont(){ Val = "Calibri" };
FontFamily fontFamily2 = new FontFamily(){ Val = 2 };
FontScheme fontScheme5 = new FontScheme(){ Val = FontSchemeValues.Minor };
runProperties2.Append(fontSize4);
runProperties2.Append(color4);
runProperties2.Append(runFont2);
runProperties2.Append(fontFamily2);
runProperties2.Append(fontScheme5);
Text text2 = new Text(){ Space = SpaceProcessingModeValues.Preserve };
text2.Text = " is great";
run2.Append(runProperties2);
run2.Append(text2);
sharedStringItem1.Append(run1);
sharedStringItem1.Append(run2);
sharedStringTable1.Append(sharedStringItem1);
sharedStringTablePart1.SharedStringTable = sharedStringTable1;
Run Code Online (Sandbox Code Playgroud)
你必须经历这些SharedStringItem
元素。
这样的 aSharedStringItem
可以包含Run
元素。
您将样式应用到该Run
元素上。
SharedStringItem
重要的是,您的代码还应涵盖 a不包含任何子元素的情况Run
。当单元格仅包含文本而没有任何格式化的子元素时,就会出现这种情况。
在这里,您必须创建一个新的 Run 才能应用样式。
下面的代码使用 Excel 文件将第一行单元格中的单词 RED 的颜色设置为红色,如下图所示。
单元A1
格包含Run
元素,单元格B1
不包含元素。
最终结果看起来像
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();
Run Code Online (Sandbox Code Playgroud)
(我将把上面代码中的清理和异常处理留给您......)
编辑
对于您的具体情况,如果单元格值为“Microsoft is beautiful”,您必须将此字符串拆分为单独的部分,并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);
}
Run Code Online (Sandbox Code Playgroud)
下图显示了之前和之后。
编辑
回应您关于如何循环遍历 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 ...
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)