#c# #ms-word #ms-office #office-interop
#c# #ms-word #ms-office #office-взаимодействие
Вопрос:
Я пытался выяснить, как вставить 2 разных формата в один и тот же абзац, используя interop.word в c #, например:
привет, планета Земля, вот что я хочу сделать
Ответ №1:
Предполагая, что ваш документ определен как oDoc, следующий код должен дать вам желаемый результат:
Word.Paragraph oPara = oDoc.Content.Paragraphs.Add(ref oMissing);
oPara.Range.Text = "hello planet earth here's what I want to do";
object oStart = oPara.Range.Start 13;
object oEnd = oPara.Range.Start 18;
Word.Range rBold = oDoc.Range(ref oStart, ref oEnd);
rBold.Bold = 1;
Комментарии:
1. 1 потому что похоже, что это сработает, но должен быть способ переключить стиль, а затем добавить символы вместо того, чтобы применять стили постфактум.
Ответ №2:
Мне пришлось немного изменить ответ Денниса, чтобы заставить его работать на меня.
То, что я делаю, полностью автоматизировано, поэтому мне приходится работать только с переменными.
private void InsertMultiFormatParagraph(string text, int size, int spaceAfter = 10) {
var para = docWord.Content.Paragraphs.Add(ref objMissing);
para.Range.Text = text;
// Explicitly set this to "not bold"
para.Range.Font.Bold = 0;
para.Range.Font.Size = size;
para.Format.SpaceAfter = spaceAfter;
var start = para.Range.Start;
var end = para.Range.Start text.IndexOf(":");
var rngBold = docWord.Range(ref objStart, ref objEnd);
rngBold.Bold = 1;
para.Range.InsertParagraphAfter();
}
Основное отличие, которое побудило меня захотеть написать этот пост, заключалось в том, что абзац должен быть вставлен ПОСЛЕ изменения шрифта. Моей первоначальной мыслью было вставить его после установки SpaceAfter
свойства, но затем значения objStart
и objEnd
выдавали исключения «вне диапазона». Это было немного нелогично, поэтому я хотел убедиться, что все знают.
Комментарии:
1. «Я пока не могу прокомментировать его ответ» ИМО, если вы предлагаете новый код или нетривиальную модификацию, тогда новый ответ — правильный способ сделать это в любом случае. Я подозреваю, что для
.Bold
значений все же есть константы true / false.2. Я тоже думал о том же, за исключением того, что жирный шрифт (а также курсив, подчеркивание и т.д.) — это все свойства типа данных int. 1 будет «true», 0 — «false». По умолчанию значение равно -1, поэтому существует третий параметр «unset». Как и все, что связано с Office Interops, это отчасти противоречит интуиции по сравнению с тем, как вы ожидаете, что это будет работать. Весь устаревший код немного усложняет работу новичкам (таким, как я).
Ответ №3:
Следующий код, казалось, работал лучше всего для меня при форматировании определенного выделения в абзаце. Использование встроенной в Word функции «найти» для выделения, затем форматирование только выделенного текста. Этот подход будет хорошо работать только в том случае, если текст для выделения является уникальной строкой в пределах выделения. Но для большинства ситуаций, с которыми я сталкивался, это, кажется, работает.
oWord.Selection.Find.Text = Variable_Containing_Text_to_Select; // sets the variable for find and select
oWord.Selection.Find.Execute(); // Executes find and select
oWord.Selection.Font.Bold = 1; // Modifies selection
oWord.Selection.Collapse(); // Clears selection
Надеюсь, это кому-то поможет!
Комментарии:
1. Спасибо! это помогло мне. Просто хотел добавить на случай, если кто-то еще увидит это, как только вы запустите oWord. Выделение.Поиск. Выполнить(); затем вам нужно запустить oWord. Выделение. Свернуть(); перед запуском другого выделения.Найдите. Это очистит первое выделение.
2. Это отличный совет. Спасибо!
3. Я изменил свой ответ, чтобы включить вашу рекомендацию, поскольку кажется, что это может быть общей потребностью.
Ответ №4:
Я знаю, что этот пост старый, но он появлялся почти во всех моих поисках. Приведенный ниже ответ на случай, если кто-то, как и я, захочет сделать это для более чем одного слова в предложении. В этом случае я перебираю строковый массив переменных, которые содержат строки, и изменяю этот текст на жирный — модификация @joshman1019
string[] makeBold = new string[4] {a, b, c, d};
foreach (string s in makeBold)
{
wApp.Selection.Find.Text = s; //changes with each iteration
wApp.Selection.Find.Execute();
wApp.Selection.Font.Bold = 1;
wApp.Selection.Collapse(); //used to 'clear' the selection
wApp.Selection.Find.ClearFormatting();
}
Таким образом, каждая строка, представленная переменной, будет выделена жирным шрифтом. Итак, если a = "hello world"
, то Hello World выделен жирным шрифтом в Word doc. Надеюсь, это сэкономит кому-то немного времени.
Ответ №5:
Я знаю, что это старая тема, но я подумал, что в любом случае опубликую здесь для тех, кто наткнулся на нее через Google (как я сделал). Я прошел большую часть пути к решению с помощью подхода криллгара, но у меня возникли проблемы, потому что часть моего текста содержит новые строки. Соответственно, эта модификация работала лучше всего для меня:
private void WriteText(string text)
{
var para = doc.Content.Paragraphs.Add();
var start = para.Range.Start;
var end = para.Range.Start text.IndexOf(":");
para.Range.Text = text;
para.Range.Font.Bold = 0;
para.Range.InsertParagraphAfter();
if(text.Contains(":")){
var rngBold = doc.Range(start, end);
rngBold.Bold = 1;
}
}
Ключевое отличие заключается в том, что я вычисляю начало и конец ранее в функции. Я не могу точно указать на это, но я думаю, что если в вашем новом тексте есть новые строки, более позднее вычисление начала / конца что-то испортит.
И, очевидно, мое решение предназначено для текста в формате:
Метка: Данные
где метка должна быть выделена жирным шрифтом.
Ответ №6:
Рассмотрите возможность использования Range.Collapse
в конечном итоге с Microsoft.Office.Interop.Word.WdCollapseDirection.wdCollapseEnd
в качестве параметра. Это позволило бы следующему тексту иметь форматирование, отличное от предыдущего текста (а форматирование следующего текста не повлияет на форматирование предыдущего).