convert-stream 1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of convert-stream might be problematic. Click here for more details.
- convert_stream/__init__.py +19 -0
- convert_stream/__main__.py +29 -0
- convert_stream/_version.py +7 -0
- convert_stream/convert.py +300 -0
- convert_stream/imagelib.py +493 -0
- convert_stream/library.py +5 -0
- convert_stream/models/__init__.py +10 -0
- convert_stream/models/m_imgelib.py +107 -0
- convert_stream/models/m_pdf_convert.py +171 -0
- convert_stream/models/m_pdf_document.py +139 -0
- convert_stream/models/m_pdf_page.py +88 -0
- convert_stream/models/m_text.py +480 -0
- convert_stream/pdf_convert.py +282 -0
- convert_stream/pdf_document.py +534 -0
- convert_stream/pdf_page.py +251 -0
- convert_stream/text.py +8 -0
- convert_stream-1.1.dist-info/METADATA +45 -0
- convert_stream-1.1.dist-info/RECORD +20 -0
- convert_stream-1.1.dist-info/WHEEL +5 -0
- convert_stream-1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
from typing import List, Dict
|
|
6
|
+
from abc import ABC, abstractmethod
|
|
7
|
+
from io import BytesIO
|
|
8
|
+
from pandas import DataFrame
|
|
9
|
+
import pandas
|
|
10
|
+
from PIL import Image
|
|
11
|
+
from reportlab.pdfgen import canvas
|
|
12
|
+
from reportlab.pdfgen.canvas import Canvas
|
|
13
|
+
from reportlab.lib.pagesizes import letter
|
|
14
|
+
from reportlab.lib.utils import ImageReader
|
|
15
|
+
from reportlab.platypus import Image as ReportLabImage
|
|
16
|
+
from PyPDF2 import PdfReader, PdfWriter, PageObject
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
from fitz import Page, Pixmap, Document
|
|
20
|
+
except:
|
|
21
|
+
from pymupdf import Page, Pixmap, Document
|
|
22
|
+
|
|
23
|
+
from soup_files import File, Directory
|
|
24
|
+
from convertlib.models.m_pdf_page import LibraryPDF, ABCPagePdf
|
|
25
|
+
from convertlib.models.m_imgelib import LibraryImage
|
|
26
|
+
from convertlib.models.m_pdf_document import ABCDocumentPdf
|
|
27
|
+
from convertlib.imagelib import ImageObject, ImageInverColor
|
|
28
|
+
from convertlib.pdf_page import PageDocumentPdf, FitzPagePdf, PyPdf2PagePdf
|
|
29
|
+
|
|
30
|
+
#=======================================================================#
|
|
31
|
+
# Documento PDF
|
|
32
|
+
#=======================================================================#
|
|
33
|
+
class DocumentPyPdf2(ABCDocumentPdf):
|
|
34
|
+
def __init__(self):
|
|
35
|
+
super().__init__(LibraryPDF.PYPDF)
|
|
36
|
+
|
|
37
|
+
def is_null(self):
|
|
38
|
+
if len(self.pages) < 1:
|
|
39
|
+
return True
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
def add_page(self, page:PageDocumentPdf):
|
|
43
|
+
if not isinstance(page, PageDocumentPdf):
|
|
44
|
+
raise ValueError(f'Use: PageDocumentPdf(), não {type(page)}')
|
|
45
|
+
if self.num_pages >= self.max_num_pages:
|
|
46
|
+
print(f'Número máximo de páginas está definido em: {self.max_num_pages}')
|
|
47
|
+
return False
|
|
48
|
+
self.num_pages += 1
|
|
49
|
+
page.page_number = self.num_pages
|
|
50
|
+
self.pages.append(page)
|
|
51
|
+
return True
|
|
52
|
+
|
|
53
|
+
def add_pages(self, pages:List[PageDocumentPdf]):
|
|
54
|
+
for p in pages:
|
|
55
|
+
self.add_page(p)
|
|
56
|
+
|
|
57
|
+
def add_file_pdf(self, file:File):
|
|
58
|
+
pdf_reader = PdfReader(file.absolute())
|
|
59
|
+
for page in pdf_reader.pages:
|
|
60
|
+
self.add_page(PageDocumentPdf.create_from_page_pypdf2(page))
|
|
61
|
+
|
|
62
|
+
def add_files_pdf(self, files:List[File]):
|
|
63
|
+
for f in files:
|
|
64
|
+
self.add_file_pdf(f)
|
|
65
|
+
|
|
66
|
+
def add_bytes_page(self, page_bytes:bytes):
|
|
67
|
+
self.add_page(PageDocumentPdf.create_from_page_bytes(page_bytes))
|
|
68
|
+
|
|
69
|
+
def add_bytes_file_pdf(self, bytes_file_pdf:BytesIO):
|
|
70
|
+
try:
|
|
71
|
+
# Cria um objeto PdfReader a partir dos bytes
|
|
72
|
+
pdf_reader = PdfReader(bytes_file_pdf)
|
|
73
|
+
|
|
74
|
+
except Exception as e:
|
|
75
|
+
print(f"Erro ao adicionar PDF a partir de bytes: {e}")
|
|
76
|
+
else:
|
|
77
|
+
# Itera pelas páginas do documento e adiciona ao objeto atual
|
|
78
|
+
page:PageObject = None
|
|
79
|
+
for num, page in enumerate(pdf_reader.pages):
|
|
80
|
+
self.add_page(
|
|
81
|
+
PageDocumentPdf(PyPdf2PagePdf(page, num+1))
|
|
82
|
+
)
|
|
83
|
+
finally:
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
def add_file_url(self, url):
|
|
87
|
+
try:
|
|
88
|
+
import requests
|
|
89
|
+
except Exception as e:
|
|
90
|
+
print(e)
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
response:requests.Response = requests.get(url)
|
|
95
|
+
except Exception as e:
|
|
96
|
+
print(e)
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
if not response.status_code == 200:
|
|
100
|
+
return
|
|
101
|
+
bt:BytesIO = BytesIO(response.content)
|
|
102
|
+
self.add_bytes_file_pdf(bt)
|
|
103
|
+
|
|
104
|
+
def remove_page(self, page_number:int) -> None:
|
|
105
|
+
if (page_number > self.num_pages) or (page_number < 1):
|
|
106
|
+
return
|
|
107
|
+
del self.pages[page_number - 1]
|
|
108
|
+
for num, page in enumerate(self.pages):
|
|
109
|
+
page.page_number = num + 1
|
|
110
|
+
self.num_pages = len(self.pages)
|
|
111
|
+
|
|
112
|
+
def remove_pages(self, num_pages:List[int]):
|
|
113
|
+
new:List[PageDocumentPdf] = []
|
|
114
|
+
for idx, page in enumerate(self.pages):
|
|
115
|
+
if (idx + 1) in num_pages:
|
|
116
|
+
continue
|
|
117
|
+
new.append(page)
|
|
118
|
+
self.clear()
|
|
119
|
+
self.add_pages(new)
|
|
120
|
+
#self.pages = new
|
|
121
|
+
|
|
122
|
+
def rotate_page(self, page_number: int, degrees:int):
|
|
123
|
+
if page_number > self.num_pages:
|
|
124
|
+
return
|
|
125
|
+
if page_number < 1:
|
|
126
|
+
return
|
|
127
|
+
self.pages[page_number - 1].rotate(degrees)
|
|
128
|
+
|
|
129
|
+
def set_paisagem(self):
|
|
130
|
+
for page in self.pages:
|
|
131
|
+
page.set_paisagem()
|
|
132
|
+
|
|
133
|
+
def to_file_pdf(self, fp: File):
|
|
134
|
+
"""
|
|
135
|
+
Salva o documento no disco, usando PyPDF2.
|
|
136
|
+
"""
|
|
137
|
+
writer = PdfWriter()
|
|
138
|
+
for page in self.pages:
|
|
139
|
+
if not isinstance(page.page, PyPdf2PagePdf): # Verifica se a página é do tipo PyPdf2
|
|
140
|
+
raise TypeError("Todas as páginas devem ser do tipo PyPdf2PagePdf para salvar com PyPDF2.")
|
|
141
|
+
writer.add_page(page.page.page) # Adiciona a página ao writer
|
|
142
|
+
with open(fp.absolute(), "wb+") as f:
|
|
143
|
+
writer.write(f)
|
|
144
|
+
|
|
145
|
+
def to_data(self, separator:str='\n') -> DataFrame:
|
|
146
|
+
data:List[DataFrame] = []
|
|
147
|
+
for page in self.pages:
|
|
148
|
+
current_df = page.to_table(separator).to_data()
|
|
149
|
+
if current_df.empty:
|
|
150
|
+
continue
|
|
151
|
+
current_num = len(current_df)
|
|
152
|
+
current_df['NUM_PÁGINA'] = [page.page_number] * current_num
|
|
153
|
+
data.append(current_df)
|
|
154
|
+
return pandas.concat(data)
|
|
155
|
+
|
|
156
|
+
def to_excel(self, file, *, separator:str='\n'):
|
|
157
|
+
try:
|
|
158
|
+
self.to_data(separator).to_excel(file.absolute(), index=False)
|
|
159
|
+
except Exception as e:
|
|
160
|
+
print(e)
|
|
161
|
+
|
|
162
|
+
def to_list(self, separator='\n') -> List[str]:
|
|
163
|
+
values: List[str] = []
|
|
164
|
+
for p in self.pages:
|
|
165
|
+
text = p.to_string()
|
|
166
|
+
if text is not None:
|
|
167
|
+
values.append(text)
|
|
168
|
+
return values
|
|
169
|
+
|
|
170
|
+
def clear(self):
|
|
171
|
+
self.num_pages = 0
|
|
172
|
+
self.pages.clear()
|
|
173
|
+
|
|
174
|
+
def get_page_number(self, num) -> PageDocumentPdf:
|
|
175
|
+
"""
|
|
176
|
+
Retorna a página correspondente ao número fornecido.
|
|
177
|
+
Se o número estiver fora do intervalo, retorna None.
|
|
178
|
+
"""
|
|
179
|
+
if not isinstance(num, int):
|
|
180
|
+
raise ValueError(f'{__class__.__name__} Use um número inteiro para referência de páginas, não {type(num)}')
|
|
181
|
+
if (num > self.num_pages) or (num < 1):
|
|
182
|
+
return None
|
|
183
|
+
if self.is_null():
|
|
184
|
+
return None
|
|
185
|
+
return self.pages[num - 1]
|
|
186
|
+
|
|
187
|
+
def get_pages_numbers(self, numbers:List[int]) -> List[PageDocumentPdf]:
|
|
188
|
+
"""
|
|
189
|
+
Retorna uma lista de páginas correspondentes aos números fornecidos.
|
|
190
|
+
Se algum número estiver fora do intervalo, ele será ignorado.
|
|
191
|
+
"""
|
|
192
|
+
if not isinstance(numbers, list):
|
|
193
|
+
raise ValueError(f'{__class__.__name__} Use uma lista de números inteiros para referência de páginas, não {type(pages_numbers)}')
|
|
194
|
+
if self.is_null():
|
|
195
|
+
return []
|
|
196
|
+
|
|
197
|
+
new_pages:List[PageDocumentPdf] = []
|
|
198
|
+
for num in numbers:
|
|
199
|
+
pg = self.get_page_number(num)
|
|
200
|
+
if pg is not None:
|
|
201
|
+
new_pages.append(pg)
|
|
202
|
+
return new_pages
|
|
203
|
+
|
|
204
|
+
def get_document_with_text(self, text) -> DocumentPdf:
|
|
205
|
+
"""
|
|
206
|
+
Retorna uma lista de páginas que contêm o texto especificado.
|
|
207
|
+
Se o texto não for encontrado, retorna uma lista vazia.
|
|
208
|
+
"""
|
|
209
|
+
doc = DocumentPdf(self.library)
|
|
210
|
+
for page in self.pages:
|
|
211
|
+
current_text:str = page.to_string()
|
|
212
|
+
if (current_text is not None) and (text in current_text):
|
|
213
|
+
doc.add_page(page)
|
|
214
|
+
return doc
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class DocumentFitz(ABCDocumentPdf):
|
|
218
|
+
def __init__(self):
|
|
219
|
+
super().__init__(LibraryPDF.FITZ)
|
|
220
|
+
|
|
221
|
+
def is_null(self):
|
|
222
|
+
if len(self.pages) < 1:
|
|
223
|
+
return True
|
|
224
|
+
return False
|
|
225
|
+
|
|
226
|
+
def add_page(self, page:PageDocumentPdf):
|
|
227
|
+
if not isinstance(page, PageDocumentPdf):
|
|
228
|
+
raise ValueError(f'Use: PageDocumentPdf(), não {type(page)}')
|
|
229
|
+
if self.num_pages >= self.max_num_pages:
|
|
230
|
+
print(f'Número máximo de páginas está definido em: {self.max_num_pages}')
|
|
231
|
+
return False
|
|
232
|
+
self.num_pages += 1
|
|
233
|
+
page.page_number = self.num_pages
|
|
234
|
+
self.pages.append(page)
|
|
235
|
+
return True
|
|
236
|
+
|
|
237
|
+
def add_pages(self, pages:List[ABCPagePdf]):
|
|
238
|
+
for p in pages:
|
|
239
|
+
self.add_page(p)
|
|
240
|
+
|
|
241
|
+
def add_file_pdf(self, file:File):
|
|
242
|
+
doc = Document(file.absolute())
|
|
243
|
+
for page in doc:
|
|
244
|
+
self.add_page(PageDocumentPdf.create_from_page_fitz(page))
|
|
245
|
+
|
|
246
|
+
def add_files_pdf(self, files:List[File]):
|
|
247
|
+
for f in files:
|
|
248
|
+
self.add_file_pdf(f)
|
|
249
|
+
|
|
250
|
+
def add_bytes_page(self, page_bytes:bytes):
|
|
251
|
+
self.add_page(PageDocumentPdf.create_from_page_bytes(page_bytes, library=LibraryPDF.FITZ))
|
|
252
|
+
|
|
253
|
+
def add_bytes_file_pdf(self, bytes_file_pdf:BytesIO):
|
|
254
|
+
try:
|
|
255
|
+
# Cria um objeto fitz.Document a partir dos bytes
|
|
256
|
+
pdf_document:Document = Document(stream=bytes_file_pdf, filetype="pdf")
|
|
257
|
+
# Itera pelas páginas do documento e adiciona ao objeto atual
|
|
258
|
+
for page in pdf_document:
|
|
259
|
+
self.add_page(
|
|
260
|
+
PageDocumentPdf(FitzPagePdf(page, page.number))
|
|
261
|
+
)
|
|
262
|
+
except Exception as e:
|
|
263
|
+
print(f"Erro ao adicionar PDF a partir de bytes: {e}")
|
|
264
|
+
finally:
|
|
265
|
+
pass
|
|
266
|
+
#pdf_document.close() # Fecha o documento após o uso
|
|
267
|
+
|
|
268
|
+
def add_file_url(self, url):
|
|
269
|
+
try:
|
|
270
|
+
import requests
|
|
271
|
+
except Exception as e:
|
|
272
|
+
print(e)
|
|
273
|
+
return
|
|
274
|
+
|
|
275
|
+
try:
|
|
276
|
+
response:requests.Response = requests.get(url)
|
|
277
|
+
except Exception as e:
|
|
278
|
+
print(e)
|
|
279
|
+
return
|
|
280
|
+
|
|
281
|
+
if not response.status_code == 200:
|
|
282
|
+
return
|
|
283
|
+
bt:BytesIO = BytesIO(response.content)
|
|
284
|
+
self.add_bytes_file_pdf(bt)
|
|
285
|
+
|
|
286
|
+
def remove_page(self, page_number:int) -> None:
|
|
287
|
+
if not isinstance(page_number, int):
|
|
288
|
+
raise ValueError(f'{__class__.__name__} Use um número inteiro para referência de páginas, não {type(page_number)}')
|
|
289
|
+
|
|
290
|
+
if (page_number > self.num_pages) or (page_number < 1):
|
|
291
|
+
return
|
|
292
|
+
del self.pages[page_number - 1]
|
|
293
|
+
for num, page in enumerate(self.pages):
|
|
294
|
+
page.page_number = num + 1
|
|
295
|
+
self.num_pages = len(self.pages)
|
|
296
|
+
|
|
297
|
+
def remove_pages(self, num_pages:List[int]):
|
|
298
|
+
new:List[PageDocumentPdf] = []
|
|
299
|
+
for idx, page in enumerate(self.pages):
|
|
300
|
+
if (idx + 1) in num_pages:
|
|
301
|
+
continue
|
|
302
|
+
new.append(page)
|
|
303
|
+
self.clear()
|
|
304
|
+
self.add_pages(new)
|
|
305
|
+
#self.pages = new
|
|
306
|
+
|
|
307
|
+
def rotate_page(self, page_number: int, degrees:int):
|
|
308
|
+
if (page_number > self.num_pages) or (page_number < 1):
|
|
309
|
+
return
|
|
310
|
+
self.pages[page_number - 1].rotate(degrees)
|
|
311
|
+
|
|
312
|
+
def set_paisagem(self):
|
|
313
|
+
for page in self.pages:
|
|
314
|
+
page.set_paisagem()
|
|
315
|
+
|
|
316
|
+
def to_file_pdf(self, fp: File):
|
|
317
|
+
"""
|
|
318
|
+
Salva o documento no disco, incluíndo todas as páginas (atuais e adicionadas)
|
|
319
|
+
com a lib fitz.
|
|
320
|
+
"""
|
|
321
|
+
pdf_document = Document() # Cria um novo documento PDF
|
|
322
|
+
for page in self.pages:
|
|
323
|
+
if not isinstance(page.page.page, Page): # Verifica se a página é do tipo fitz.Page
|
|
324
|
+
raise TypeError(f"Todas as páginas devem ser do tipo [fitz.Page], não {type(page.page.page)}.")
|
|
325
|
+
# Insere as páginas no novo documento
|
|
326
|
+
pdf_document.insert_pdf(
|
|
327
|
+
page.page.page.parent,
|
|
328
|
+
from_page=page.page.page.number,
|
|
329
|
+
to_page=page.page.page.number
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
# Salva o documento final no disco
|
|
333
|
+
pdf_document.save(fp.absolute())
|
|
334
|
+
pdf_document.close()
|
|
335
|
+
|
|
336
|
+
def to_data(self, separator:str='\n') -> DataFrame:
|
|
337
|
+
data:List[DataFrame] = []
|
|
338
|
+
for page in self.pages:
|
|
339
|
+
tb = page.to_table(separator)
|
|
340
|
+
current_df = tb.to_data()
|
|
341
|
+
if current_df.empty:
|
|
342
|
+
continue
|
|
343
|
+
current_num = len(current_df)
|
|
344
|
+
current_df['NUM_PÁGINA'] = [page.page_number] * current_num
|
|
345
|
+
data.append(current_df)
|
|
346
|
+
return pandas.concat(data)
|
|
347
|
+
|
|
348
|
+
def to_excel(self, file, *, separator:str='\n'):
|
|
349
|
+
try:
|
|
350
|
+
self.to_data(separator).to_excel(file.absolute(), index=False)
|
|
351
|
+
except Exception as e:
|
|
352
|
+
print(e)
|
|
353
|
+
|
|
354
|
+
def to_list(self, separator='\n') -> List[str]:
|
|
355
|
+
values: List[str] = []
|
|
356
|
+
for p in self.pages:
|
|
357
|
+
text = p.to_string()
|
|
358
|
+
if text is not None:
|
|
359
|
+
values.append(text)
|
|
360
|
+
return values
|
|
361
|
+
|
|
362
|
+
def clear(self):
|
|
363
|
+
self.num_pages = 0
|
|
364
|
+
self.pages.clear()
|
|
365
|
+
|
|
366
|
+
def get_page_number(self, num) -> PageDocumentPdf:
|
|
367
|
+
"""
|
|
368
|
+
Retorna a página correspondente ao número fornecido.
|
|
369
|
+
Se o número estiver fora do intervalo, retorna None.
|
|
370
|
+
"""
|
|
371
|
+
if not isinstance(num, int):
|
|
372
|
+
raise ValueError(f'{__class__.__name__} Use um número inteiro para referência de páginas, não {type(num)}')
|
|
373
|
+
if (num > self.num_pages) or (num < 1):
|
|
374
|
+
return None
|
|
375
|
+
if self.is_null():
|
|
376
|
+
return None
|
|
377
|
+
return self.pages[num - 1]
|
|
378
|
+
|
|
379
|
+
def get_pages_numbers(self, numbers:List[int]) -> List[PageDocumentPdf]:
|
|
380
|
+
"""
|
|
381
|
+
Retorna uma lista de páginas correspondentes aos números fornecidos.
|
|
382
|
+
Se algum número estiver fora do intervalo, ele será ignorado.
|
|
383
|
+
"""
|
|
384
|
+
if not isinstance(numbers, list):
|
|
385
|
+
raise ValueError(f'{__class__.__name__} Use uma lista de números inteiros para referência de páginas, não {type(pages_numbers)}')
|
|
386
|
+
if self.is_null():
|
|
387
|
+
return []
|
|
388
|
+
|
|
389
|
+
new_pages:List[PageDocumentPdf] = []
|
|
390
|
+
for num in numbers:
|
|
391
|
+
pg = self.get_page_number(num)
|
|
392
|
+
if pg is not None:
|
|
393
|
+
new_pages.append(pg)
|
|
394
|
+
return new_pages
|
|
395
|
+
|
|
396
|
+
def get_document_with_text(self, text) -> DocumentPdf:
|
|
397
|
+
"""
|
|
398
|
+
Retorna uma lista de páginas que contêm o texto especificado.
|
|
399
|
+
Se o texto não for encontrado, retorna uma lista vazia.
|
|
400
|
+
"""
|
|
401
|
+
doc = DocumentPdf(self.library)
|
|
402
|
+
for page in self.pages:
|
|
403
|
+
current_text:str = page.to_string()
|
|
404
|
+
if (current_text is not None) and (text in current_text):
|
|
405
|
+
doc.add_page(page)
|
|
406
|
+
return doc
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
class DocumentPdf(ABCDocumentPdf):
|
|
410
|
+
def __init__(self, library = LibraryPDF.FITZ):
|
|
411
|
+
self.library:LibraryPDF = library
|
|
412
|
+
if self.library == LibraryPDF.PYPDF:
|
|
413
|
+
self.document:ABCDocumentPdf = DocumentPyPdf2()
|
|
414
|
+
elif self.library == LibraryPDF.FITZ:
|
|
415
|
+
self.document:ABCDocumentPdf = DocumentFitz()
|
|
416
|
+
else:
|
|
417
|
+
raise NotImplementedError(f'{__class__.__name__}\nLibraryPDF não implementada: {type(library)}')
|
|
418
|
+
|
|
419
|
+
@property
|
|
420
|
+
def max_num_pages(self) -> int:
|
|
421
|
+
return self.document.max_num_pages
|
|
422
|
+
|
|
423
|
+
@max_num_pages.setter
|
|
424
|
+
def max_num_pages(self, new:int):
|
|
425
|
+
if isinstance(new, int):
|
|
426
|
+
self.document.max_num_pages = new
|
|
427
|
+
|
|
428
|
+
@property
|
|
429
|
+
def num_pages(self) -> int:
|
|
430
|
+
return self.document.num_pages
|
|
431
|
+
|
|
432
|
+
@num_pages.setter
|
|
433
|
+
def num_pages(self, new:int):
|
|
434
|
+
self.document.num_pages = new
|
|
435
|
+
|
|
436
|
+
@property
|
|
437
|
+
def pages(self) -> List[PageDocumentPdf]:
|
|
438
|
+
return self.document.pages
|
|
439
|
+
|
|
440
|
+
@pages.setter
|
|
441
|
+
def pages(self, new:List[PageDocumentPdf]):
|
|
442
|
+
self.num_pages = 0
|
|
443
|
+
for pg in new:
|
|
444
|
+
self.add_page(pg)
|
|
445
|
+
|
|
446
|
+
def is_null(self) -> bool:
|
|
447
|
+
return self.document.is_null()
|
|
448
|
+
|
|
449
|
+
def add_page(self, page:PageDocumentPdf):
|
|
450
|
+
if self.library != page.current_library:
|
|
451
|
+
if self.library == LibraryPDF.FITZ:
|
|
452
|
+
page.set_page_fitz()
|
|
453
|
+
elif self.library == LibraryPDF.PYPDF:
|
|
454
|
+
page.set_page_pypdf2()
|
|
455
|
+
if self.document.add_page(page):
|
|
456
|
+
print(f'Página PDF adicionada: {self.num_pages}')
|
|
457
|
+
|
|
458
|
+
def add_pages(self, pages:List[ABCPagePdf]):
|
|
459
|
+
for p in pages:
|
|
460
|
+
self.add_page(p)
|
|
461
|
+
|
|
462
|
+
def add_file_pdf(self, file:File):
|
|
463
|
+
print(f'Adicionando páginas do arquivo: {file.basename()}')
|
|
464
|
+
self.document.add_file_pdf(file)
|
|
465
|
+
|
|
466
|
+
def add_files_pdf(self, files:List[File]):
|
|
467
|
+
for f in files:
|
|
468
|
+
self.add_file_pdf(f)
|
|
469
|
+
|
|
470
|
+
def add_bytes_page(self, page_bytes:bytes):
|
|
471
|
+
self.document.add_bytes_page(page_bytes)
|
|
472
|
+
|
|
473
|
+
def add_bytes_file_pdf(self, file_bytes:BytesIO):
|
|
474
|
+
self.document.add_bytes_file_pdf(file_bytes)
|
|
475
|
+
|
|
476
|
+
def add_file_url(self, url):
|
|
477
|
+
print(f'Adicionando URL: {url}')
|
|
478
|
+
self.document.add_file_url(url)
|
|
479
|
+
|
|
480
|
+
def remove_page(self, page_number:int) -> None:
|
|
481
|
+
self.document.remove_page(page_number)
|
|
482
|
+
|
|
483
|
+
def remove_pages(self, num_pages:List[int]):
|
|
484
|
+
self.document.remove_pages(num_pages)
|
|
485
|
+
|
|
486
|
+
def rotate_page(self, page_number: int, degrees:int):
|
|
487
|
+
print(f'Rotacionando a página {page_number} [{degrees}]')
|
|
488
|
+
self.document.rotate_page(page_number, degrees)
|
|
489
|
+
|
|
490
|
+
def set_paisagem(self):
|
|
491
|
+
self.document.set_paisagem()
|
|
492
|
+
|
|
493
|
+
def to_file_pdf(self, file:File) -> bool:
|
|
494
|
+
if self.is_null():
|
|
495
|
+
print(f'O documento está vazio, adicione páginas ou arquivos para prosseguir!')
|
|
496
|
+
return False
|
|
497
|
+
print(f'Salvando arquivo: {file.basename()}')
|
|
498
|
+
self.document.to_file_pdf(file)
|
|
499
|
+
return False
|
|
500
|
+
|
|
501
|
+
def to_data(self, separator:str='\n') -> DataFrame:
|
|
502
|
+
return self.document.to_data(separator)
|
|
503
|
+
|
|
504
|
+
def to_excel(self, file, *, separator = '\n'):
|
|
505
|
+
self.document.to_excel(file, separator=separator)
|
|
506
|
+
|
|
507
|
+
def to_list(self, separator='\n') -> List[str]:
|
|
508
|
+
return self.document.to_list(separator)
|
|
509
|
+
|
|
510
|
+
def clear(self):
|
|
511
|
+
self.document.clear()
|
|
512
|
+
|
|
513
|
+
def get_page_number(self, num) -> PageDocumentPdf:
|
|
514
|
+
return self.document.get_page_number(num)
|
|
515
|
+
|
|
516
|
+
def get_pages_numbers(self, numbers) -> List[PageDocumentPdf]:
|
|
517
|
+
return self.document.get_pages_numbers(numbers)
|
|
518
|
+
|
|
519
|
+
def get_document_with_text(self, text) -> DocumentPdf:
|
|
520
|
+
"""
|
|
521
|
+
Retorna um novo documento com as páginas que contém o texto informado no parâmetro,
|
|
522
|
+
se o texto não for encontrado, retorna um documento vazio.
|
|
523
|
+
"""
|
|
524
|
+
return self.document.get_document_with_text(text)
|
|
525
|
+
|
|
526
|
+
@classmethod
|
|
527
|
+
def create_from_file(cls, file:File, *, library:LibraryPDF=LibraryPDF.PYPDF) -> DocumentPdf:
|
|
528
|
+
doc = cls(library)
|
|
529
|
+
doc.add_file_pdf(file)
|
|
530
|
+
return doc
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
|