Извлечение определенного текста из PDF и вставка в WORD (или PDF)

lisabon_Q3

Новичок
Пользователь
Окт 22, 2020
5
0
1
Всем доброго времени суток.
Есть такая задачка, над которой я ломаю голову уже неделю...

Чтобы понять, это судебная система есть два файла, заявление (файл 1.pdf) и решение (файл 2.doc)
Сейчас вручную берется файл "1.pdf", копируются данные должника (желтая заливка), он может быть один или два, как в примере, и вставляется в файл "2.doc" после слова "должник:" И также вставляется на страницу 2 и 3, тоже выделил желтой заливкой.

И еще действие: берется файл "1.pdf", копируется текст со 2 страницы после слов "Вынести судебный приказ о взыскании с " (выделил бирюзовым) и вставляется в файл "2.doc" после слова "Взыскать с".
Если откроете 2 файла, то поймете визуально что откуда копируется и вставляется, тупо Ctrl+C - Ctrl+V, но нужно знать откуда и куда.
И так 600 файлов....
Мой мозг как увидел это у жены на работе просто вскипел, автоматизированное действие выполняет человек целыми дням и вздумал это дело автоматизировать.

Так вот, прошу помощи, любые идеи как это организовать и подходит ли питон для этого.
Любые советы, голова есть на плечах, но не знаю с чего начинать.


Пока дошел до Pyfpdf, установил, работает, командой "pdf2txt.py 1.pdf" выводится текст из PDF, отлично, но как извлечь нужный мне и вставить в файл DOC??
Мне кажется, что в DOC будет проблема вставить, то можно вставить в PDF, конвертировать файл DOC-PDF не проблема. Сделал файл "2.pdf", это тот же файл DOC, только конвертированные, то есть можно в него вставлять данные из файла "1.pdf"


Windows 10, Python 3.9 (32bit)

cffi 1.14.3
chardet 3.0.4
click 7.1.2
cryptography 3.1.1
distribute 0.7.3
fpdf 1.7.2
joblib 0.17.0
nltk 3.5
pdfminer.six 20200726
pdfminer3k 1.3.4
pip 20.2.4
ply 3.11
pycparser 2.20
PyPDF2 1.26.0
regex 2020.10.15
setuptools 49.2.1
six 1.15.0
slate 0.5.2
slate3k 0.5.3
sortedcontainers 2.2.2
tqdm 4.50.2
 

Вложения

  • example.zip
    628,7 КБ · Просмотры: 2

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 580
457
83
Python:
import fitz
import docx
import sys
import os
from docx.shared import Pt

file_docx = docx.Document('shablon.docx')
list_pdf_file = []

# Добвляем в список все пдф из папки где лежит скрипт
for file in os.listdir(os.getcwd()):
    if file.endswith(".pdf"):
        list_pdf_file.append(file)


# Читаем пдф, пишем в список
def read_pdf(object_pdf):
    copy_pdf = []

    page_1 = object_pdf.loadPage(0).getText()
    page_2 = object_pdf.loadPage(1).getText()

    if page_1.find('Должники:') == -1:
        copy_1 = page_1[page_1.find('Должник:') + 9:page_1.find('Цена')]
    else:
        copy_1 = page_1[page_1.find('Должники:') + 10:page_1.find('Цена')]

    copy_2 = page_2[page_2.find('взыскании') + 12:page_2.find('2.')]

    # Если надо и в первой копии убрать перенос строки
    # copy_pdf.append(copy_1.replace('\n', ''))

    copy_pdf.append(copy_1)
    copy_pdf.append(copy_2.replace('\n', ''))

    return copy_pdf


# Читаем док файл, объединяем все таблицы в список
def read_docx(object_docx):
    table_1 = object_docx.tables[0]
    table_2 = object_docx.tables[1]
    table_3 = object_docx.tables[2]
    table_4 = object_docx.tables[3]
    table_5 = object_docx.tables[4]
    copy_docx = extract_table(table_1) \
                + extract_table(table_2) + extract_table(table_3) + extract_table(table_4) + extract_table(table_5)

    return copy_docx


# Читаем таблицы в док файле, пишем в список
def extract_table(table):
    list_table = []
    for row in table.rows:
        for cell in row.cells:
            list_table.append(cell.text)

    return list_table


# Меняем позиции в док списке на позиции из пдф списка
def change_table():
    list_pdf = read_pdf(file_pdf)
    list_docx = read_docx(file_docx)

    list_docx[1] = list_pdf[0]
    list_docx[4] = list_pdf[0]
    list_docx[6] = list_pdf[0]
    list_docx[7] = list_pdf[0]
    list_docx[2] = 'Взыскать с ' + list_pdf[1]

    return list_docx


# Вставляем новый список в таблицы и сохраняем изменения в файл 3.docx
def save_change(object_docx, save_name_file):
    change_list = change_table()

    table_1 = object_docx.tables[0]
    object_docx.tables[0].style = 'Table Grid'
    style_table_1 = object_docx.tables[0].style
    font_table_1 = style_table_1.font
    font_table_1.size = Pt(12)

    table_2 = object_docx.tables[1]
    object_docx.tables[1].style = 'Table Grid'
    style_table_2 = object_docx.tables[1].style
    font_table_2 = style_table_2.font
    font_table_2.size = Pt(12)

    table_3 = object_docx.tables[2]
    object_docx.tables[2].style = 'Table Grid'
    style_table_3 = object_docx.tables[2].style
    font_table_3 = style_table_3.font
    font_table_3.size = Pt(12)

    table_4 = object_docx.tables[3]
    object_docx.tables[3].style = 'Table Grid'
    style_table_4 = object_docx.tables[3].style
    font_table_4 = style_table_4.font
    font_table_4.size = Pt(12)

    table_5 = object_docx.tables[4]
    object_docx.tables[4].style = 'Table Grid'
    style_table_5 = object_docx.tables[4].style
    font_table_5 = style_table_5.font
    font_table_5.size = Pt(12)

    count = 0

    for row in table_1.rows:
        for cell in row.cells:
            if count != 0:
                cell.text = change_list[count]
            count += 1

    for row in table_2.rows:
        for cell in row.cells:
            cell.text = change_list[count]
            count += 1

    for row in table_3.rows:
        for cell in row.cells:
            if count != 3:
                cell.text = change_list[count]
            count += 1

    for row in table_4.rows:
        for cell in row.cells:
            if count != 5:
                cell.text = change_list[count]
            count += 1

    for row in table_5.rows:
        for cell in row.cells:
            cell.text = change_list[count]
            count += 1

    try:
        object_docx.save(save_name_file)
    except PermissionError:
        print('Невозможно сохранить файл, недостаточно прав!')
        sys.exit(0)


# Перебираем файлы по одному и запускаем функцию
for file in list_pdf_file:
    file_pdf = fitz.open(file)
    name_file = file.split('.')[0] + '.docx'
    save_change(file_docx, name_file)

print('Выполнено!')
 

weamagic

Пользователь
Пользователь
Июл 11, 2020
141
13
18
Всем доброго времени суток.
Есть такая задачка, над которой я ломаю голову уже неделю...

Чтобы понять, это судебная система есть два файла, заявление (файл 1.pdf) и решение (файл 2.doc)
Сейчас вручную берется файл "1.pdf", копируются данные должника (желтая заливка), он может быть один или два, как в примере, и вставляется в файл "2.doc" после слова "должник:" И также вставляется на страницу 2 и 3, тоже выделил желтой заливкой.

И еще действие: берется файл "1.pdf", копируется текст со 2 страницы после слов "Вынести судебный приказ о взыскании с " (выделил бирюзовым) и вставляется в файл "2.doc" после слова "Взыскать с".
Если откроете 2 файла, то поймете визуально что откуда копируется и вставляется, тупо Ctrl+C - Ctrl+V, но нужно знать откуда и куда.
И так 600 файлов....
Мой мозг как увидел это у жены на работе просто вскипел, автоматизированное действие выполняет человек целыми дням и вздумал это дело автоматизировать.

Так вот, прошу помощи, любые идеи как это организовать и подходит ли питон для этого.
Любые советы, голова есть на плечах, но не знаю с чего начинать.


Пока дошел до Pyfpdf, установил, работает, командой "pdf2txt.py 1.pdf" выводится текст из PDF, отлично, но как извлечь нужный мне и вставить в файл DOC??
Мне кажется, что в DOC будет проблема вставить, то можно вставить в PDF, конвертировать файл DOC-PDF не проблема. Сделал файл "2.pdf", это тот же файл DOC, только конвертированные, то есть можно в него вставлять данные из файла "1.pdf"
Вообще-то должен быть вариант проще. В судах, как слышал краем уха, есть БД с такими данными. Можно в ворде макрос написать на VBA\VSTA для коннекта с ней и вставки нужных данных.
 

lisabon_Q3

Новичок
Пользователь
Окт 22, 2020
5
0
1
Да, файл 1.pdf генерируется автоматически не судом, а сторонней компанией c помощью PHP, базы данных и модуля dompdf + CPDF....
Но!
Это делает другая компания автоматически и в суд уже попадает только файл PDF из которого делают приказ вручную.
Естественно генерировать и приказ сторонняя компания не будет, это не их забота.
Поэтому тут остается только работать с PDF.
И к сожалению никаких баз данных нет, все вручную, поверьте мне, и журналы даже ведутся от руки...
 

weamagic

Пользователь
Пользователь
Июл 11, 2020
141
13
18
Да, файл 1.pdf генерируется автоматически не судом, а сторонней компанией c помощью PHP, базы данных и модуля dompdf + CPDF....
Но!
Это делает другая компания автоматически и в суд уже попадает только файл PDF из которого делают приказ вручную.
Естественно генерировать и приказ сторонняя компания не будет, это не их забота.
Поэтому тут остается только работать с PDF.
И к сожалению никаких баз данных нет, все вручную, поверьте мне, и журналы даже ведутся от руки...
Согласен, для файла Excel БД - громкое название. Посмотри в сторону библиотеки Python-Docx
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 580
457
83
а построение документа одинаково всегда? у вас в вордовском файле, где вставлять надо, таблицы, это так и надо?
 
Последнее редактирование:

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 580
457
83
если документы всегда такие как вы скинули по построению (есть таблицы), то вот так можно (вроде работает)
используемые модули
Python:
pip install python-docx
pip install PyMupdf
сам код
Python:
import fitz
import docx

file_docx = docx.Document('2.docx')
file_pdf = fitz.open('1.pdf')


# Читаем пдф, пишем в список
def read_pdf(object_pdf):
    copy_pdf = []

    page_1 = object_pdf.loadPage(0).getText()
    page_2 = object_pdf.loadPage(1).getText()

    copy_1 = page_1[page_1.find('Должники:')+10:page_1.find('Цена')]
    copy_2 = page_2[page_2.find('взыскании с')+12:page_2.find('2.')]

    copy_pdf.append(copy_1)
    copy_pdf.append(copy_2)

    return copy_pdf


# Читаем док файл, объединяем все таблицы в список
def read_docx(object_docx):
    table_1 = object_docx.tables[0]
    table_2 = object_docx.tables[1]
    table_3 = object_docx.tables[2]
    table_4 = object_docx.tables[3]
    table_5 = object_docx.tables[4]
    copy_docx = extract_table(table_1)\
                + extract_table(table_2) + extract_table(table_3) + extract_table(table_4) + extract_table(table_5)

    return copy_docx


# Читаем таблицы в док файле, пишем в список
def extract_table(table):
    list_table = []
    for row in table.rows:
        for cell in row.cells:
            list_table.append(cell.text)

    return list_table


# Меняем позиции в док списке на позиции из пдф списка
def change_table():
    list_pdf = read_pdf(file_pdf)
    list_docx = read_docx(file_docx)

    list_docx[1] = list_pdf[0]
    list_docx[4] = list_pdf[0]
    list_docx[6] = list_pdf[0]
    list_docx[7] = list_pdf[0]
    list_docx[2] = 'Взыскать с ' + list_pdf[1]

    return list_docx


# Вставляем новый список в таблицы и сохраняем изменения в файл 3.docx
def save_change(object_docx):
    table_1 = object_docx.tables[0]
    table_2 = object_docx.tables[1]
    table_3 = object_docx.tables[2]
    table_4 = object_docx.tables[3]
    table_5 = object_docx.tables[4]
    count = 0

    for row in table_1.rows:
        for cell in row.cells:
            if count != 0:
                cell.text = change_table()[count]
            count += 1

    for row in table_2.rows:
        for cell in row.cells:
            cell.text = change_table()[count]
            count += 1

    for row in table_3.rows:
        for cell in row.cells:
            if count != 3:
                cell.text = change_table()[count]
            count += 1

    for row in table_4.rows:
        for cell in row.cells:
            if count != 5:
                cell.text = change_table()[count]
            count += 1

    for row in table_5.rows:
        for cell in row.cells:
            cell.text = change_table()[count]
            count += 1

    try:
        object_docx.save('3.docx')
    except PermissionError:
        print('Невозможно сохранить файл, недостаточно прав!')

    print('Выполнено!')


save_change(file_docx)
 
Последнее редактирование:
  • Wow!
Реакции: lisabon_Q3

lisabon_Q3

Новичок
Пользователь
Окт 22, 2020
5
0
1
а построение документа одинаково всегда? у вас в вордовском файле, где вставлять надо, таблицы, это так и надо?
Да одинаковое, да там таблицы, если это проблематично, то можно убрать..
Ваш код отрабатывает отлично, это то что нужно, спасибо большое!

Но есть пара моментов, помогите их решить, пожалуйста:
  1. Вставляемый текст из PDF в WORD в 10 шрифте (размер). Почему так? Посмотрел и в ворде и пдф стоит 12 шрифт, почему извлекаемый шрифт в 10? Такой настройки в скрипте не вижу даже. Можно ли сделать в 12 шрифте как и весь текст?

  2. Сейчас заметил, что иногда есть файлы PDF, где один должник, то есть на первой странице в первой таблице может быть написано 'Должник:', а не 'Должники:'
    То есть часть кода:
    Python:
    copy_1 = page_1[page_1.find('Должники:')+10:page_1.find('Цена')]
    Не видит "Должник: " и естественно текст считывает с начала и все летит к чертям..


    Pdf c 1 должником отлично отрабатывает с кодом:
    Python:
    copy_1 = page_1[page_1.find('Должник:')+9:page_1.find('Цена')]
    Можно ли сделать так, чтобы скрипт если не находил "Должники: " отрабатывал по "('Должник:')+9" ?

  3. Во вложении я переделал под одного должника, но не могу понять, почему стала плохо отрабатывать эта часть:
    Python:
    copy_2 = page_2[page_2.find('о взыскании с')+12:page_2.find('2.')]
    На выходе получается:
    "Взыскать с и вышеизложенного, руководствуясь ст. ст. 309, 153-157 ЖК РФ, 23, 122 - 124 ГПК
    РФ,
    ПРОШУ:
    1. Вынести судебный приказ о взыскании c
    Сидоровой Полины Сергеевны в пользу АО
    «» , задолженности за «ОТОПЛЕНИЕ» за период c 01.06.2019г. по "


    Почему так? Сидел так и не смог понять, ведь мы "говорим" скрипту искать текст на 2 странице "о взыскании с", и отступать 12 символов.
    А скрипт почему-то берет строку на 2 странице "На основании вышеизложенного, руководствуясь....."

    Можете не только исправить, но и объяснить почему скрипт игнорирует теперь команду поиска?


Заранее благодарю.
 

Вложения

  • example_2.zip
    497,3 КБ · Просмотры: 2
Последнее редактирование:

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 580
457
83
Вставляемый текст из PDF в WORD в 10 шрифте (размер). Почему так? Посмотрел и в ворде и пдф стоит 12 шрифт, почему извлекаемый шрифт в 10? Такой настройки в скрипте не вижу даже. Можно ли сделать в 12 шрифте как и весь текст?
Потому что по умолчанию размер шрифта 10, поменял на 12, но во второй таблице, где "Взыскать с...", появилась граница у таблицы, так как пришлось присвоить ей стиль, в документации не нашел, как убрать границу у таблицы, может быть сами поищите найдете решение
Сейчас заметил, что иногда есть файлы PDF, где один должник, то есть на первой странице в первой таблице может быть написано 'Должник:', а не 'Должники:'
Поправил
Во вложении я переделал под одного должника, но не могу понять, почему стала плохо отрабатывать эта часть
По какой то причине не находил сочетание 'о взыскании с', поменял условие поиска на 'взыскании', вроде работает

код
Python:
import fitz
import docx
import sys
from docx.shared import Pt

file_docx = docx.Document('shablon.docx')
file_pdf = fitz.open('1.pdf')


# Читаем пдф, пишем в список
def read_pdf(object_pdf):
    copy_pdf = []

    page_1 = object_pdf.loadPage(0).getText()
    page_2 = object_pdf.loadPage(1).getText()

    if page_1.find('Должники:') == -1:
        copy_1 = page_1[page_1.find('Должник:') + 9:page_1.find('Цена')]
    else:
        copy_1 = page_1[page_1.find('Должники:') + 10:page_1.find('Цена')]

    copy_2 = page_2[page_2.find('взыскании') + 12:page_2.find('2.')]

    copy_pdf.append(copy_1)
    copy_pdf.append(copy_2)

    return copy_pdf


# Читаем док файл, объединяем все таблицы в список
def read_docx(object_docx):
    table_1 = object_docx.tables[0]
    table_2 = object_docx.tables[1]
    table_3 = object_docx.tables[2]
    table_4 = object_docx.tables[3]
    table_5 = object_docx.tables[4]

    copy_docx = extract_table(table_1) \
                + extract_table(table_2) + extract_table(table_3) + extract_table(table_4) + extract_table(table_5)

    return copy_docx


# Читаем таблицы в док файле, пишем в список
def extract_table(table):
    list_table = []
    for row in table.rows:
        for cell in row.cells:
            list_table.append(cell.text)

    return list_table


# Меняем позиции в док списке на позиции из пдф списка
def change_table():
    list_pdf = read_pdf(file_pdf)
    list_docx = read_docx(file_docx)

    list_docx[1] = list_pdf[0]
    list_docx[4] = list_pdf[0]
    list_docx[6] = list_pdf[0]
    list_docx[7] = list_pdf[0]
    list_docx[2] = 'Взыскать с ' + list_pdf[1]

    return list_docx


# Вставляем новый список в таблицы и сохраняем изменения в файл 3.docx
def save_change(object_docx):
    change_list = change_table()

    table_1 = object_docx.tables[0]
    object_docx.tables[0].style = 'Table Grid'
    style_table_1 = object_docx.tables[0].style
    font_table_1 = style_table_1.font
    font_table_1.size = Pt(12)

    table_2 = object_docx.tables[1]
    object_docx.tables[1].style = 'Table Grid'
    style_table_2 = object_docx.tables[1].style
    font_table_2 = style_table_2.font
    font_table_2.size = Pt(12)

    table_3 = object_docx.tables[2]
    object_docx.tables[2].style = 'Table Grid'
    style_table_3 = object_docx.tables[2].style
    font_table_3 = style_table_3.font
    font_table_3.size = Pt(12)

    table_4 = object_docx.tables[3]
    object_docx.tables[3].style = 'Table Grid'
    style_table_4 = object_docx.tables[3].style
    font_table_4 = style_table_4.font
    font_table_4.size = Pt(12)

    table_5 = object_docx.tables[4]
    object_docx.tables[4].style = 'Table Grid'
    style_table_5 = object_docx.tables[4].style
    font_table_5 = style_table_5.font
    font_table_5.size = Pt(12)

    count = 0

    for row in table_1.rows:
        for cell in row.cells:
            if count != 0:
                cell.text = change_list[count]
            count += 1

    for row in table_2.rows:
        for cell in row.cells:
            cell.text = change_list[count]
            count += 1

    for row in table_3.rows:
        for cell in row.cells:
            if count != 3:
                cell.text = change_list[count]
            count += 1

    for row in table_4.rows:
        for cell in row.cells:
            if count != 5:
                cell.text = change_list[count]
            count += 1

    for row in table_5.rows:
        for cell in row.cells:
            cell.text = change_list[count]
            count += 1

    try:
        object_docx.save('3.docx')
    except PermissionError:
        print('Невозможно сохранить файл, недостаточно прав!')
        sys.exit(0)

    print('Выполнено!')


save_change(file_docx)
 
  • Мне нравится
Реакции: lisabon_Q3

lisabon_Q3

Новичок
Пользователь
Окт 22, 2020
5
0
1
может быть сами поищите найдете решение
Подправил шаблон, видимо в нем было дело, сделал границы отображаемыми, но белого цвета, так рамка не появляется теперь во второй таблице.

Еще хотел бы пару моментов попросить допилить:
1. Во вставляемом тексте можно убрать переносы строк? Конвертировать в пробелы, например...
Для наглядности скриншот из WORD с включенными символами:
w.png

2. Можно ли сделать так, чтобы скрипт перелопачивал все PDF файлы в текущей папке и сохранял их с тем же именем, но уже docx ?
Я попробовал, и вот что получилось, не могу понять как зациклить это чудо.

Чтобы после запуска были файлы Сидорова.docx, Иванова.docx, сейчас почему то только одна.
 

Вложения

  • example_3.zip
    964,9 КБ · Просмотры: 1

lisabon_Q3

Новичок
Пользователь
Окт 22, 2020
5
0
1
Спасибо, regnor!
Да, это то что нужно!
Низкий поклон вам за вашу помощь и терпение. Всех благ!
 

Форум IT Специалистов