Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
1711 / 578 / 76
Регистрация: 10.04.2009
Сообщений: 9,316

Работа с MS Word

16.10.2023, 07:31. Показов 1794. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
здравствуйте, помогите пожалуйста разобрать работу кода:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from docx import Document
from run_tools import *
from docx.enum.text import WD_COLOR_INDEX
from docx.shared import RGBColor
 
 
d = Document('test1.docx')
 
par = d.paragraphs[0]
run = par.runs[1]
 
new_runs = split_run_by(par, run, (1, 2))
new_runs[0].font.highlight_color = WD_COLOR_INDEX.RED # RED=КРАСНЫЙ
new_runs[1].font.highlight_color = WD_COLOR_INDEX.YELLOW # YELLOW=ЖЕЛТЫЙ
new_runs[2].font.highlight_color = WD_COLOR_INDEX.GREEN # GREEN=ЗЕЛЕНЫЙ
 
d.save('test1-highlightened.docx') # highlightened=выделенный
 
another_run = insert_run_at_position(par, 2, 'e')
copy_run_format(run, another_run)
another_run.font.highlight_color = WD_COLOR_INDEX.PINK
 
d.save('test1-highlightened-bear.docx') # highlightened=выделенный
 
to_run = insert_run_before(par, run, 'to')
copy_run_format(run, to_run)
to_run.font.highlight_color = WD_COLOR_INDEX.BLACK
to_run.font.color.rgb = RGBColor(0xff, 0xff, 0xff)
 
d.save('test1-highlightened-tobear.docx') # highlightened=выделенный
для начала спотыкаюсь на строке 2 - ModuleNotFoundError: No module named 'run_tools'
что нужно поставить через pip install?
спасибо
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.10.2023, 07:31
Ответы с готовыми решениями:

Работа метода Word.Selection.Find при поиске в документе Word
Дорого времени суток! никак не могу разобраться в механизме работы range.find Запускаю: ......................... ...

Работа с таблицей в Word через библиотеку Microsoft.Interop.Word
Здравствуйте, я продвинутый программист.Пишу программу и использованием библиотеки Microsoft.Interop.Word у меня возникло несколько проблем...

Работа с Microsoft.Office.Interop.Word и поиск в Word документе
Здравствуйте, при создании программы для работы со справочником столкнулся с проблемой. Нужно из существующего сформированного документа...

12
 Аватар для CopBuroJLoBa
150 / 132 / 53
Регистрация: 03.01.2017
Сообщений: 472
16.10.2023, 08:31
Поместите run_tools.py в директории проекта.
https://github.com/alllexx88/p... n_tools.py

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from copy import deepcopy
 
 
def insert_run_at_position(par, pos, txt=''):
    """Insert a new run with text {txt} into paragraph {par}
    at given position {pos}.
 
    Returns the newly created run.
    """
    p = par._p
    new_run = par.add_run(txt)
    p.insert(pos + 1, new_run._r)
 
    return new_run
 
 
def insert_run_before(par, run, txt=''):
    """Insert a new run with text {txt} into paragraph before given {run}.
 
    Returns the newly created run.
    """
    run_2 = par.add_run(txt)
    run._r.addprevious(run_2._r)
 
    return run_2
 
 
def insert_run_after(par, run, txt=''):
    """Insert a new run with text {txt} into paragraph after given {run}.
 
    Returns the newly created run.
    """
    run_2 = par.add_run(txt)
    run._r.addnext(run_2._r)
 
    return run_2
 
 
def copy_run_format(run_src, run_dst):
    """Copy formatting from {run_src} to {run_dst}.
    """
    rPr_target = run_dst._r.get_or_add_rPr()
    rPr_target.addnext(deepcopy(run_src._r.get_or_add_rPr()))
    run_dst._r.remove(rPr_target)
 
 
def split_run_by(par, run, split_by):
    """Split text in {run} from paragraph {par} by positions
    provided by {split_by}, while retaining original {run}
    formatting.
 
    Returns list of split runs starting with original {run}.
    """
    txt = run.text
    txt_len = len(txt)
    if not all(isinstance(i, int) for i in split_by):
        raise ValueError("Split positions must be integer numbers")
    split_list = [i if i >= 0 else txt_len + i for i in split_by]
    if not all(split_list[j] <= split_list[j + 1]
               for j in range(len(split_list) - 1)):
        raise ValueError("Split positions must be sorted to make sense")
    if split_list[0] < 0:
        raise ValueError("A split position cannot be less than -<text length>")
    split_list.insert(0, 0)
    split_list.append(None)
    split_txts = [txt[split_list[i]:split_list[i + 1]]
                  for i in range(len(split_list) - 1)]
    run.text = split_txts[0]
    split_txts.pop(0)
    new_runs = [run]
    for next_txt in split_txts:
        new_runs.append(insert_run_after(par, new_runs[-1], next_txt))
        copy_run_format(run, new_runs[-1])
 
    return new_runs
Добавлено через 4 минуты

Объяснение от Chat GPT:

Данный код является Python-скриптом, который использует библиотеку python-docx для работы с документами Microsoft Word (файлами .docx). Этот код выполняет следующие действия:

Импортирует необходимые модули:

Document из библиотеки docx для работы с документами.
run_tools (предположительно, пользовательский модуль) для дополнительных инструментов обработки текста в документе.
WD_COLOR_INDEX из docx.enum.text для работы с цветами выделения текста.
RGBColor из docx.shared для работы с пользовательскими цветами.
Открывает документ с именем 'test1.docx' и создает объект Document для работы с этим документом.

Выполняет следующие операции над документом:

Получает первый абзац (par) документа.
Получает второй "run" (фрагмент текста) (run) внутри первого абзаца.
Разбивает второй "run" (run) на три новых "run" (new_runs) с использованием функции split_run_by (предположительно, пользовательская функция). Эта функция разбивает текст на части в соответствии с указанными позициями (здесь: (1, 2)).

Устанавливает цвет выделения текста для каждого из созданных "run":

new_runs[0] - выделение текста красным цветом.
new_runs[1] - выделение текста желтым цветом.
new_runs[2] - выделение текста зеленым цветом.
Сохраняет измененный документ под именем 'test1-highlightened.docx'.

Вставляет новый "run" (another_run) после второго "run" с буквой 'e' и копирует форматирование из второго "run".

Устанавливает цвет выделения текста для another_run - розовый (цвет с индексом WD_COLOR_INDEX.PINK).

Сохраняет документ с новым именем 'test1-highlightened-bear.docx'.

Вставляет новый "run" (to_run) перед вторым "run" с текстом 'to' и копирует форматирование из второго "run".

Устанавливает цвет выделения текста для to_run - черный (цвет с индексом WD_COLOR_INDEX.BLACK) и цвет текста - белый (RGB цвет белого).

Сохраняет документ с новым именем 'test1-highlightened-tobear.docx'.

Таким образом, код выполняет разнообразное форматирование и выделение текста в документе Microsoft Word и сохраняет измененные версии документа под разными именами файла.
0
 Аватар для CopBuroJLoBa
150 / 132 / 53
Регистрация: 03.01.2017
Сообщений: 472
16.10.2023, 08:35
Пример:
Миниатюры
Работа с MS Word  
0
 Аватар для CopBuroJLoBa
150 / 132 / 53
Регистрация: 03.01.2017
Сообщений: 472
16.10.2023, 08:38
Забыл другие сохраненные файлы прикрепить.
В общем, надеюсь, вам чуть помог.
Миниатюры
Работа с MS Word  
1
1711 / 578 / 76
Регистрация: 10.04.2009
Сообщений: 9,316
16.10.2023, 15:22  [ТС]
CopBuroJLoBa,
понял, нужно
test1.docx
и
run_tools.py
положить в папку с проектом
запустить код с моего сообщения № 1 и получится три файла на выходе, спасибо
пока нет вопросов кэп
разберусь, если что напишу

Добавлено через 1 час 47 минут
и как оно работает загадка, весь то код ни к чему, остановился на части кода:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from docx import Document
from run_tools import *
from docx.enum.text import WD_COLOR_INDEX
from docx.shared import RGBColor
 
 
d = Document('test1.docx')
 
par = d.paragraphs[0]
run = par.runs[1]
 
new_runs = split_run_by(par, run, (1, 2))
new_runs[0].font.highlight_color = WD_COLOR_INDEX.RED # RED=КРАСНЫЙ
new_runs[1].font.highlight_color = WD_COLOR_INDEX.YELLOW # YELLOW=ЖЕЛТЫЙ
new_runs[2].font.highlight_color = WD_COLOR_INDEX.GREEN # GREEN=ЗЕЛЕНЫЙ
 
d.save('test1-highlightened.docx')
в результате:
Foobarbaz
понятно, что работает в пределах 1-го абзаца
но почему покрасило 4, 5, 6 букву?
даже если считать от нуля, почему покрасило 3, 4, 5 букву как считает?
видимо я не понимаю, что заложено в строку кода:
Python
1
new_runs = split_run_by(par, run, (1, 2))
??
0
1711 / 578 / 76
Регистрация: 10.04.2009
Сообщений: 9,316
17.10.2023, 07:23  [ТС]
CopBuroJLoBa, уж если дружите с
Цитата Сообщение от CopBuroJLoBa Посмотреть сообщение
Chat GPT
я к сожалению нет)), то как перевести код VBA на Python, вот он:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Option Explicit
Sub Замена_текста_с_нужным_цветом_шрифта_финиш()
 
Dim vFindText As Variant
vFindText = Array("123", "234")
Dim Startt As Date
Startt = VBA.Time$
Dim i As Long
 
'избавляемся от всех полей=сначала выделяем весь документ Конрол+A, затем Конрол+Шифт+Эф9
ActiveDocument.Range.Fields.Unlink
'шрифт всего документа окрасить в чёрный цвет
ActiveDocument.Range.Font.ColorIndex = wdBlack
For i = 0 To UBound(vFindText)
    With ActiveDocument.Range.Find
        'искать нужное только в тексте с шрифтом чёрного цвета
        .Font.ColorIndex = wdBlack
        .Text = vFindText(i)
        Debug.Print .Text
        'окрасить нужное шрифтом красного цвета
        .Replacement.Font.ColorIndex = wdRed
        .Execute Replace:=wdReplaceAll
    End With
Next i
Dim Endd As Date
Endd = VBA.Time$
 
MsgBox$ _
"Начато: " & Startt & Chr$(13) & _
"Закончено: " & Endd
 
End Sub
спасибо
0
 Аватар для CopBuroJLoBa
150 / 132 / 53
Регистрация: 03.01.2017
Сообщений: 472
17.10.2023, 07:38
Ципихович Эндрю, попробую спросить, умеет ли GPT конвертировать.

Кликните здесь для просмотра всего текста
Этот код предназначен для поиска и замены текста в документе Microsoft Word с использованием макросов VBA (Visual Basic for Applications). Давайте разберем, что делает каждая часть кода:

Option Explicit: Эта директива включает жесткий режим объявления переменных, что означает, что каждая переменная должна быть объявлена перед использованием. Это помогает предотвратить ошибки в коде.

Sub Замена_текста_с_нужным_цветом_шрифта_фин иш(): Это объявление начала подпрограммы VBA. В данном случае, это подпрограмма с именем "Замена_текста_с_нужным_цветом_шрифта_фи ниш".

Dim vFindText As Variant: Объявление переменной vFindText как массива (тип Variant), который будет содержать текст, который мы будем искать и заменять.

vFindText = Array("123", "234"): Здесь определены значения для массива vFindText. Это означает, что код будет искать и заменять текст "123" и "234" в документе.

Dim Startt As Date: Объявление переменной Startt для отслеживания времени начала выполнения кода.

Startt = VBA.Time$: Запись текущего времени в переменную Startt.

Dim i As Long: Объявление переменной i как целого числа (Long) для использования в цикле.

ActiveDocument.Range.Fields.Unlink: Эта строка кода удаляет все поля из документа, чтобы исключить их влияние на поиск и замену текста.

ActiveDocument.Range.Font.ColorIndex = wdBlack: Здесь устанавливается цвет шрифта всего документа в черный цвет.

For i = 0 To UBound(vFindText): Этот код начинает цикл, который перебирает элементы массива vFindText.

With ActiveDocument.Range.Find: Здесь мы начинаем блок поиска текста в документе.

.Font.ColorIndex = wdBlack: Эта строка кода устанавливает условие поиска: мы ищем текст с черным шрифтом.

.Text = vFindText(i): Здесь задается текст, который мы будем искать в текущей итерации цикла.

.Replacement.Font.ColorIndex = wdRed: Задается цвет шрифта (красный), который будет использоваться для замены найденного текста.

.Execute Replace:=wdReplaceAll: Этот метод выполняет замену текста. В данном случае, wdReplaceAll означает, что мы заменяем все найденные вхождения текста.

Next i: Завершение цикла и переход к следующей итерации (если таковые имеются).

Dim Endd As Date: Объявление переменной Endd для отслеживания времени завершения выполнения кода.

Endd = VBA.Time$: Запись текущего времени в переменную Endd.

MsgBox$ ...: Этот блок выводит сообщение с информацией о времени начала и завершения выполнения кода.

End Sub: Завершение подпрограммы.

Итак, код выполняет поиск и замену указанных текстовых значений в документе, при этом меняет цвет шрифта у заменяемого текста на красный.


Добавлено через 2 минуты
Chat GPT
Для выполнения аналогичной задачи в Python, вы можете использовать библиотеку python-docx для работы с файлами формата DOCX. Вот аналог вашего кода на Python:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from docx import Document
 
# Открываем документ
doc = Document('test1.docx')
 
# Список текстов для поиска и замены
texts_to_replace = ["123", "234"]
 
# Итерируемся по всем параграфам документа
for paragraph in doc.paragraphs:
    for text_to_replace in texts_to_replace:
        if text_to_replace in paragraph.text:
            # Найден текст, меняем его цвет на красный
            for run in paragraph.runs:
                if text_to_replace in run.text:
                    run.font.color.rgb = (255, 0, 0)  # RGB-код красного цвета
 
# Сохраняем измененный документ
doc.save('test1-highlightened.docx')
Этот код открывает документ, ищет указанные текстовые значения и меняет цвет шрифта на красный. После этого он сохраняет измененный документ. Пожалуйста, удостоверьтесь, что у вас установлена библиотека python-docx, которую можно установить с помощью pip:
Python
1
pip install python-docx
Как и в вашем исходном коде, убедитесь, что вы работаете с резервной копией вашего документа, так как изменения будут внесены напрямую в исходный файл.
Добавлено через 6 минут
По поводу
Python
1
new_runs = split_run_by(par, run, (1, 2))
Вот комментарии к каждой части кода:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
def split_run_by(par, run, split_by):
    """Разделяет текст в {run} из абзаца {par} на позиции, заданные {split_by}, при этом сохраняя исходное форматирование {run}.
    
    Возвращает список разделенных строк, начиная с оригинального {run}.
    """
    txt = run.text
    txt_len = len(txt)
    
    # Проверка, что все элементы в списке split_by являются целыми числами.
    if not all(isinstance(i, int) for i in split_by):
        raise ValueError("Позиции разделения должны быть целыми числами")
    
    # Преобразование отрицательных значений в split_by в соответствующие позиции относительно конца текста.
    split_list = [i if i >= 0 else txt_len + i for i in split_by]
    
    # Проверка, что позиции разделения упорядочены.
    if not all(split_list[j] <= split_list[j + 1] for j in range(len(split_list) - 1)):
        raise ValueError("Позиции разделения должны быть упорядочены")
    
    # Позиция разделения не может быть меньше -<длина текста>.
    if split_list[0] < 0:
        raise ValueError("Позиция разделения не может быть меньше -<длина текста>")
    
    # Вставляем начальную и конечную позиции в список разделения.
    split_list.insert(0, 0)
    split_list.append(None)
    
    # Разделяем текст на отдельные фрагменты, исходя из позиций разделения.
    split_txts = [txt[split_list[i]:split_list[i + 1]] for i in range(len(split_list) - 1)]
    
    # Изменяем текст в текущем run на первый фрагмент.
    run.text = split_txts[0]
    
    # Удаляем первый фрагмент из списка split_txts.
    split_txts.pop(0)
    
    # Создаем новые run-объекты для оставшихся фрагментов и сохраняем их форматирование.
    new_runs = [run]
    for next_txt in split_txts:
        new_run = insert_run_after(par, new_runs[-1], next_txt)
        copy_run_format(run, new_run)
        new_runs.append(new_run)
 
    return new_runs
Эта функция принимает абзац par, объект run run и список позиций разделения split_by. Она разделяет текст в run на фрагменты, основываясь на позициях разделения, и возвращает список разделенных run-объектов. Комментарии объясняют каждый шаг этого процесса.
0
1711 / 578 / 76
Регистрация: 10.04.2009
Сообщений: 9,316
17.10.2023, 07:43  [ТС]
Цитата Сообщение от CopBuroJLoBa Посмотреть сообщение
GPT
не хило объяснил код на вба))
ну и когда запускал код, не выполнил, ругнулся
run.font.color.rgb = (255, 0, 0) # RGB-код красного цвета
^^^^^^^^^^^^^^^^^^
0
 Аватар для CopBuroJLoBa
150 / 132 / 53
Регистрация: 03.01.2017
Сообщений: 472
17.10.2023, 07:53
Цитата Сообщение от Ципихович Эндрю Посмотреть сообщение
когда запускал код, не выполнил, ругнулся
Вроде поправил
Ошибка возникает потому, что метод run.font.color.rgb ожидает объект RGBColor, а не кортеж.
Чтобы решить эту проблему, вы можете создать объект RGBColor и затем установить его для цвета шрифта. Вот исправленный код:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from docx import Document
from docx.shared import RGBColor
 
# Открываем документ
doc = Document('test1.docx')
 
# Список текстов для поиска и замены
texts_to_replace = ["123", "234"]
 
# Итерируемся по всем параграфам документа
for paragraph in doc.paragraphs:
    for text_to_replace in texts_to_replace:
        if text_to_replace in paragraph.text:
            # Найден текст, меняем его цвет на красный
            for run in paragraph.runs:
                if text_to_replace in run.text:
                    run.font.color.rgb = RGBColor(255, 0, 0)  # Используем RGBColor
 
# Сохраняем измененный документ
doc.save('test1-highlightened.docx')
Теперь код должен работать без ошибок и изменять цвет шрифта на красный.
0
1711 / 578 / 76
Регистрация: 10.04.2009
Сообщений: 9,316
17.10.2023, 08:00  [ТС]
Цитата Сообщение от CopBuroJLoBa Посмотреть сообщение
Вроде поправил
ошибок не было, но и результат НЕ верный, было в файле
1234 234
1234 234
всё и покрасило
1234 234
1234 234

а вба сделал бы верно:
1234 234
1234 234
0
1711 / 578 / 76
Регистрация: 10.04.2009
Сообщений: 9,316
18.10.2023, 14:41  [ТС]
CopBuroJLoBa, код есть, давайте озадачим джи-пи-ти как она его оценит......
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import itertools
from docx import Document
from docx.text.run import Run
from docx.shared import Pt, RGBColor
import re
import copy
 
def isolate_run(paragraph, start, end):
    rs = tuple(paragraph._p.r_lst)
    def advance_to_run_containing_start(start, end):
        r_ends = tuple(itertools.accumulate(len(r.text) for r in rs)) + (0,)
        r_idx = 0
        while start >= r_ends[r_idx]:
            r_idx += 1
        skipped_rs_offset = r_ends[r_idx - 1]
        return rs[r_idx], r_idx, start - skipped_rs_offset, end - skipped_rs_offset
    def split_off_prefix(r, start, end):
        if start > 0:
            prefix_r = copy.deepcopy(r)
            r.addprevious(prefix_r)
            r.text = r.text[start:]
            prefix_r.text = prefix_r.text[:start]
        return end - start
    def split_off_suffix(r, end):
        suffix_r = copy.deepcopy(r)
        r.addnext(suffix_r)
        r.text = r.text[:end]
        suffix_r.text = suffix_r.text[end:]
    def lengthen_run(r, r_idx, end):
        while len(r.text) < end:
            suffix_len_reqd = end - len(r.text)
            r_idx += 1
            next_r = rs[r_idx]
            if len(next_r.text) <= suffix_len_reqd:
                r.text = r.text + next_r.text
                next_r.getparent().remove(next_r)
                continue
            if len(next_r.text) > suffix_len_reqd:
                r.text = r.text + next_r.text[:suffix_len_reqd]
                next_r.text = next_r.text[suffix_len_reqd:]
    r, r_idx, start, end = advance_to_run_containing_start(start, end)
    end = split_off_prefix(r, start, end)
    if len(r.text) > end:
        split_off_suffix(r, end)
    elif len(r.text) < end:
        lengthen_run(r, r_idx, end)
    return Run(r, paragraph)
d = Document('test.docx') # исходный файл
vFindText = ["123", "234"] # список замен, замены будут произведены строго по списку
 
for paragraph in d.paragraphs:
    runs = paragraph.runs
    runs[0].text = paragraph.text
    runs[0].font.size = Pt(16)
    runs[0].font.color.rgb = RGBColor(0, 0, 0) # чёрный цвет, #000000, rgb (0, 0, 0)
    for run in runs[1:]:
        r = run._element
        r.getparent().remove(r)
    for match in re.finditer("|".join(map(re.escape, vFindText)), paragraph.text):
        isolate_run(paragraph, match.start(), match.end()).font.color.rgb = RGBColor(255, 0, 0) # красный цвет, #FF0000, rgb (255, 0, 0)
d.save('test-highlightened.docx') # сохранить результат в файл
Добавлено через 3 минуты
а так, что сказать, работает как надо
60 строк кода на питоне - код который не я писал и поэтому конечно плаваю....
30 строк кода на VBA - код который я написал и мне понятен
руки дойдут сравню быстродействие.......
0
 Аватар для CopBuroJLoBa
150 / 132 / 53
Регистрация: 03.01.2017
Сообщений: 472
18.10.2023, 20:57
GPT на своей волне.

Ваш код выглядит довольно сложным, но его можно оптимизировать и сделать более читаемым. Вот некоторые рекомендации по оптимизации:

1. Удаление избыточных операций:
- Вы можете избавиться от переменной runs, так как она нигде не используется.
- Вы также можете убрать цикл, который удаляет все элементы кроме первого из каждого абзаца, так как вам не нужно сохранять остаток текста в абзаце.

2. Применение генераторов списков и других более питоничных подходов:
- Вместо создания vFindText вручную, вы можете просто использовать список строк.
- Вместо join и map, используйте генератор списка, чтобы создать паттерн для re.finditer.

3. Улучшение читаемости:
- Добавьте комментарии, объясняющие, что делает каждый участок кода.
- Разделите код на функции с понятными именами, чтобы улучшить структуру кода.

Вот оптимизированный код:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from docx import Document
from docx.shared import Pt, RGBColor
import re
 
def configure_run(run):
    run.font.size = Pt(16)
    run.font.color.rgb = RGBColor(0, 0, 0)  # Черный цвет
 
def highlight_matches(paragraph, vFindText):
    for match in re.finditer("|".join(map(re.escape, vFindText)), paragraph.text):
        start, end = match.start(), match.end()
        run = paragraph.runs[0]
        configure_run(run)
        run.text = paragraph.text[:start]
        for i in range(1, len(paragraph.runs)):
            paragraph.runs[i].clear()
        if end < len(paragraph.text):
            new_run = paragraph.runs[0].insert_run(end)
            new_run.text = paragraph.text[end:]
            configure_run(new_run)
            new_run.font.color.rgb = RGBColor(255, 0, 0)  # Красный цвет
 
def main():
    doc = Document('test.docx')
    vFindText = ["123", "234"]
 
    for paragraph in doc.paragraphs:
        highlight_matches(paragraph, vFindText)
 
    doc.save('test-highlightened.docx')
 
if __name__ == "__main__":
    main()
Этот оптимизированный код делает то же самое, что и исходный, но он более читаем и менее избыточен.
0
1711 / 578 / 76
Регистрация: 10.04.2009
Сообщений: 9,316
19.10.2023, 11:30  [ТС]
Цитата Сообщение от CopBuroJLoBa Посмотреть сообщение
Вот оптимизированный код:
опробовал, увы искомый текст с массива НЕ красился в красный цвет, а удалялся и удалялся и до конца абзаца
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.10.2023, 11:30
Помогаю со студенческими работами здесь

Работать в Word, не открывая документы (работа с закрытыми документами Word)
Дайте ссылку, как работать с закрытыми документами Word. У меня есть 5 шаблонов. Я хочу во всех этих шаблонах, не открывая их,...

Работа с Word из Access (проблемы при конвертации в 2000-й, если установлена другая версия Word)
Приветствую! У меня такая проблема: Я совершенствую базу под 97-м Access, буду конвертировать также в 2000-й. В 97-м я работаю с...

Word Art: средства рисования vs. работа с объектами Word art
Помогите пожалуйста разобраться: Почему при создании нового документа в Word 2010 при попытке создать объект Word art появляется такая...

Работа с Word
У меня такой вопрос.Я написал код который создает файл Word и добавляет в него текст. AnsiString str; Variant v,v1; if(!fStart) ...

Работа с Word
Привет всем! Подскажите, как лучше и попроще работать с вордом? для создания отчетов. На прямую как-то неправильно наверно. типа...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru