-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdocxedit.py
228 lines (193 loc) · 8.6 KB
/
docxedit.py
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
import docx
def show_line(doc: object, current_text: str, show_errors: bool = True):
"""
Shows the 'line' of text in the doc where the string is found (without replacing anything).
Args:
doc (Object): The docx document object.
current_text (str): The string to search for.
show_errors (bool): Whether to show errors or not. Default is True.
Returns:
The line of text where the string is found, if it is found.
"""
try:
for paragraph in doc.paragraphs:
if current_text in paragraph.text:
inline = paragraph.runs
for i in range(len(inline)):
if current_text in inline[i].text:
text = inline[i].text
inline[i].text = text
print(f'Text found in line: {paragraph.text}')
else:
if show_errors:
print(f'Error: {current_text} not found in document.')
except Exception as e:
print(f'Error: An Exception occurred: {e}')
def replace_string(doc: object, old_string: str, new_string: str,
include_tables: bool = True, show_errors: bool = False):
"""
Replaces an old string (placeholder) with a new string
without changing the formatting of the text.
Args:
doc (Object): The docx document object.
old_string (str): The old string to replace.
new_string (str): The new string to replace the old one with.
include_tables (bool): Whether to include tables or not. Default is True.
show_errors (bool): Whether to show errors or not. Default is False.
Returns:
Success or Error.
"""
string_instances_replaced = 0
for paragraph in doc.paragraphs:
if old_string in paragraph.text:
inline = paragraph.runs
for i in range(len(inline)):
if old_string in inline[i].text:
text = inline[i].text.replace(str(old_string), str(new_string))
inline[i].text = text
string_instances_replaced += 1
print(f'Success: Replaced the string "{old_string}" with "{new_string}" in a paragraph')
else:
if show_errors:
print(f'Error: Could not find the string "{old_string}" in the document')
if include_tables:
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for paragraph in cell.paragraphs:
if old_string in paragraph.text:
inline = paragraph.runs
for i in range(len(inline)):
if old_string in inline[i].text:
text = inline[i].text.replace(str(old_string), str(new_string))
inline[i].text = text
string_instances_replaced += 1
print(f'Success: Replaced the string "{old_string}" '
f'with "{new_string}" in a table')
else:
if show_errors:
print(f'Error: Could not find {old_string} in a table')
print(f'Summary: Replaced {string_instances_replaced} instances of "{old_string}" '
f'with "{new_string}"')
def replace_string_up_to_paragraph(doc: object, old_string: str, new_string: str,
paragraph_number: int, show_errors: bool = True):
"""
Replaces an old string (placeholder) with a new string
without changing the format of the text but only up to
a specific paragraph number.
Args:
doc (Object): The docx document object.
old_string (str): The old string to replace.
new_string (str): The new string to replace the old one with.
paragraph_number (int): The paragraph number to stop at.
show_errors (bool): Whether to show errors or not. Default is True.
"""
string_instances_replaced = 0
for index, paragraph in enumerate(doc.paragraphs):
if index < paragraph_number:
if old_string in paragraph.text:
inline = paragraph.runs
for i in range(len(inline)):
if old_string in inline[i].text:
text = inline[i].text.replace(str(old_string), str(new_string))
inline[i].text = text
string_instances_replaced += 1
print(
f'Success: Replaced the string "{old_string}" with "{new_string}" '
f'in paragraph number {index}')
print(f'Summary: Replaced {string_instances_replaced} instances of "{old_string}" '
f'with "{new_string}"')
def remove_paragraph(paragraph: object, show_errors: bool = True):
"""
Remove a paragraph. Input must be a paragraph object.
Args:
paragraph (Object): The paragraph object to remove.
show_errors (bool): Whether to show errors or not. Default is True.
Returns:
Success or Error.
"""
try:
paragraph_element = paragraph._element
paragraph_element.getparent().remove(paragraph_element)
paragraph._p = paragraph._element = None
return print(f'Success: Removed paragraph {paragraph}')
except Exception as e:
if show_errors:
return print(f'Error: Could not remove paragraph {paragraph}: {e}')
def remove_lines(doc, first_line: str, number_of_lines: int, show_errors: bool = True):
"""
Remove a line including any keyword (first_line),
and a certain number of rows after that.
Args:
doc (Object): The docx document object.
first_line (String): The first line to remove.
number_of_lines (Integer): The number of lines to remove.
show_errors (bool): Whether to show errors or not. Default is True.
Returns:
Success or Error.
"""
list_of_paragraphs = []
for i in doc.paragraphs:
list_of_paragraphs.append(i)
for index, i in enumerate(doc.paragraphs):
if first_line in i.text:
try:
remove_paragraph(i)
except AttributeError:
if show_errors:
print(f'Error: Could not remove line {index}: {i.text}')
b_var = 0
c_var = 0
while b_var < number_of_lines:
try:
print(list_of_paragraphs[index + 1 + b_var])
remove_paragraph(list_of_paragraphs[index + 1 + c_var])
b_var += 1
print(f'Success: Removed line {str(index + 1 + c_var)}')
except Exception as e:
if show_errors:
print(f'Error: Could not remove line {str(index + 1 + c_var)} '
f'due to exception: {e}')
c_var += 1
continue
def add_text_in_table(table, row_num: int, column_num: int,
new_string: str, show_errors: bool = True):
"""
Add text to a cell in a table.
Args:
table (Object): The table object.
row_num (int): The row number to add the text to.
column_num (int): The column number to add the text to.
new_string (str): The text to add.
show_errors (bool): Whether to show errors or not. Default is False.
Returns:
Success or Error.
"""
try:
table.cell(row_num, column_num).text = new_string
return print(f'Success: Added {new_string} to row {row_num} and column {column_num}')
except Exception as e:
if show_errors:
return print(f'Error: Could not add {new_string} to row {row_num} '
f'and column {column_num} due to exception: {e}')
def change_table_font_size(table: object, font_size: int, show_errors: bool = True):
"""
Change the font size of the whole table.
Args:
table (Object): The table object.
font_size (Integer): The font size to change to.
show_errors (bool): Whether to show errors or not. Default is True.
Returns:
Success or Error.
"""
try:
for row in table.rows:
for cell in row.cells:
for paragraph in cell.paragraphs:
for run in paragraph.runs:
font = run.font
font.size = docx.shared.Pt(font_size)
return print(f'Success: Changed font size to {font_size}')
except Exception as e:
if show_errors:
return print(f'Error: Could not change font size to {font_size}: {e}')