Ну, во-первых, вы хотите найти все разделы текста с заданным шрифтом.
В формате docx
, который используется в MSWord 2007, фрагмент текста с общими свойствами называется run
, определяемым тегом <w:r>
( ECMA-376 стр. 33). Расширенное форматирование (включая шрифт) хранится в теге <w:rPr>
, в частности в теге <w:rFonts>
. Итак, чтобы найти фрагмент текста с заданным шрифтом, мы ищем тег <w:rFonts>
с соответствующей информацией о шрифте.
Тег <w:rFonts>
отформатирован так (некоторые ненужные свойства удалены):
<w:rFonts w:ascii=”FontName”
w:cs=”FontName”
w:eastAsia=”FontName”
w:hAnsi=”FontName”/>
Атрибуты соответствуют различным кодировкам:
w:ascii
соответствует ASCII
w:cs
соответствует Unicode символов, которые требуют Сложные методы форматирования
w:eastAsia
соответствует символам в восточно-азиатском диапазоне Unicode
w:hAnsi
соответствует любому символу в диапазоне Unicode, который не попадает ни в одну из вышеуказанных категорий
Если в ваших документах нет сложного текста на китайском, арабском или других видах, вы можете спокойно игнорировать атрибуты w:cs
и w:eastAsia
.
Подводя итог - нам нужно найти все <w:rFonts>
с w:ascii
или w:hAnsi
атрибутами, соответствующими нужному шрифту или другими словами <w:rFonts w:ascii="Needed Font" w:hAnsi="Needed Font">
.
Теперь, если вы не знакомы с форматом docx
, на самом деле это пакет из нескольких файлов, включая файлы XML ( дополнительная информация о структуре документа docx ). Мы могли бы использовать System.IO.Packaging
и классы синтаксического анализа XML для работы с docx
документами, но у нас есть полезная абстракция от Microsoft - Open XML SDK , которая дает нам хорошую иерархию классов для работы с docx
файлы:
Как только мы перейдем к классу RunFonts
, у нас появятся два свойства, относящиеся к нам - RunFonts.Ascii
и RunFonts.HighAnsi
. Как нам туда добраться? Следующий фрагмент кода демонстрирует:
using System;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace WordProcessingEx
{
public class Program
{
public static void Main(string[] args)
{
string fileName = /*obtain path to file here*/;
using (WordprocessingDocument myDocument = WordprocessingDocument.Open(fileName, true))
{
// Get all paragraphs
var p = myDocument.MainDocumentPart.Document.Body.Elements<Paragraph>().First();
var r = from para in p
from run in para.Elements<Run>()
where run.RunProperties.RunFonts.ASCII ="NeededFont" || run.RunProperties.RunFonts.HighAnsi = "NeededFont"
select run;
}
}
}
}
Теперь, когда у нас все работает с соответствующим шрифтом, нам нужно их выделить. Это достигается с помощью тега <w:highlight>
и его свойства w:val
. Например - <w:highlight w:val="yellow"/>
.
Следующий фрагмент кода демонстрирует:
foreach (var run in r)
{
run.RunProperties.Highlight.SetAttribute(new OpenXmlAttribute("w:val", null, "yellow"));
}
(это входит в блок using
выше, сразу после запроса LINQ)
После всего этого мы закончили. Когда выполнение покидает блок using
, каждый прогон, использующий выбранный шрифт, подсвечивается.