Вы должны пройти через элементы SharedStringItem
.
Такой SharedStringItem
может содержать Run
элементов.
Вы применяете стиль к этому элементу Run
.
Важно, чтобы ваш код также охватывал ситуацию, когда SharedStringItem
не содержит никаких дочерних элементов Run
.
Это тот случай, когда ячейка содержит только текст, без каких-либо отформатированных дочерних элементов.
Здесь вы должны создать новый Run, чтобы применить стиль.
Приведенный ниже код устанавливает цвет слова КРАСНЫЙ на красный для ячеек в первой строке, используя файл Excel, как показано на рисунке ниже.
Ячейка 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();
( Я оставлю вам очистку и обработку исключений в приведенном выше коде ... )
EDIT
Для вашего конкретного случая, имея значение ячейки «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);
}
Изображение ниже показывает до и после.
EDIT
В ответ на ваш комментарий о том, как перебрать все ячейки в документе 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 ...
}
}
}
}
}