(Решено)Объединение нескольких .docx файлов в один используя python-docx.

Lancellot

Новичок
Пользователь
Апр 30, 2020
22
4
3
Python 3.
Я пробую объединить файлы .docx файлы используя библиотеку python-docx.
MKA-20-5778-0-1.docx', 'MKA-20-5967-0-1.docx - это файлы источники, содержащие контент.
empty.docx - пустой вордовский документ.
Результат объединения сохраняется в combined_word_documents.docx.
В результате работы скрипта сохраняется как пустой файл, а нужно чтобы он содержал контент файлов-источников.

Python:
from docx import Document
files = ['МКА-20-5778-0-1.docx', 'МКА-20-5967-0-1.docx']


def combine_word_documents(files):
    combined_document = Document('empty.docx')
    count, number_of_files = 0, len(files)
    for file in files:
        sub_doc = Document(file)

        # Don't add a page break if you've
        # reached the last file.
        if count < number_of_files - 1:
            sub_doc.add_page_break()

        for paragraph in sub_doc.paragraphs:
            text = paragraph.text
            combined_document.add_paragraph(text)
        count += 1

    combined_document.save('combined_word_documents.docx')

combine_word_documents(files)
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Ваш код собирает все параграфы из переданных .docx файлов, записывает их в combined_document и сохраняет в файл. Запустил - код работает.
 
  • Мне нравится
Реакции: Lancellot

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Я очень удивился, что код рабочий. И попробовал его прогнать с двумя файлами вордовскими с простой текстовой строкой и действительно работает!
Но почему же мои файлы он не объединяет? Видимо специфический контент. Я могу вам для примера скинуть их?
Вот пример, который может объединить ваши файлы, только стили немного сбиваются:
Python:
from docx import Document

files = ['d1.docx', 'd2.docx']

def combine_word_documents(files):
    merged_document = Document()

    for index, file in enumerate(files):
        sub_doc = Document(file)

        if index < len(files) - 1:
            sub_doc.add_page_break()

        for element in sub_doc.element.body:
            merged_document.element.body.append(element)

    merged_document.save('d3.docx')

combine_word_documents(files)
 
  • Мне нравится
Реакции: Lancellot

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Вопрос: Я могу каким-то образом сохранить документ в папке 'MergeDocFiles' без задания абсолютного пути типа C:/Users.... , а просто указав директорию внутри, откуда был запущен скрипт?
Можно создавать папку перед сохранением файла:
Python:
from docx import Document
import os

files = ['d1.docx', 'd2.docx']

def combine_word_documents(files):
    merged_document = Document()

    for index, file in enumerate(files):
        sub_doc = Document(file)

        if index < len(files) - 1:
            sub_doc.add_page_break()

        for element in sub_doc.element.body:
            merged_document.element.body.append(element)

    os.mkdir('MergeDocFiles')
    merged_document.save('MergeDocFiles/d3.docx')

combine_word_documents(files)
 
  • Мне нравится
Реакции: Lancellot

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Погуглил ошибку. Судя по вот этому ответу ошибка в файлах, которые находятся в текущем каталоге. Попробуйте скопировать .docx-файлы в другую папку и снова запустить скрипт.
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Попробуйте перенести .docx файлы в другую папку, а в скрипте путь к ним поменять.
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Проблема в этой части кода:
Python:
# Получаем список всеъ файлов с расширением .docx в текущем каталоге.
for filedocx in os.listdir():
    if filedocx.endswith(".docx"):
        print(filedocx)


files = filedocx
Здесь выводятся на печать только .docx-файлы, а записывается в переменную files последний файл в папке, так как после завершения цикле в переменной filedocx окажется значение последнего файла в текущей папке. А потом при обработке (так как это не .docx-файл) возникает ошибка.
Нужно обрабатывать только .docx-файлы. Вот исправленный код:

Python:
from docx import Document
import os


files = []
# Получаем список всех файлов с расширением .docx в текущем каталоге.
for filedocx in os.listdir():
    if filedocx.endswith(".docx"):
        files.append(filedocx)

print(files)

def combine_word_documents(files):
    merged_document = Document()

    for index, file in enumerate(files):
        sub_doc = Document(file)

        if index < len(files) - 1:
            sub_doc.add_page_break()

        for element in sub_doc.element.body:
            merged_document.element.body.append(element)

    merged_document.save('../НА ПЕЧАТЬ.docx')

combine_word_documents(files)
 
  • Мне нравится
Реакции: Vlad_SD и Lancellot

Lancellot

Новичок
Пользователь
Апр 30, 2020
22
4
3
Ваш код собирает все параграфы из переданных .docx файлов, записывает их в combined_document и сохраняет в файл. Запустил - код работает.
Я очень удивился, что код рабочий. И попробовал его прогнать с двумя файлами вордовскими с простой текстовой строкой и действительно работает!
Но почему же мои файлы он не объединяет? Видимо специфический контент.
 
Последнее редактирование:

Lancellot

Новичок
Пользователь
Апр 30, 2020
22
4
3
Вот пример, который может объединить ваши файлы, только стили немного сбиваются:
Со стилями я разобрался, настроил вордовские файлы таким-образом, чтобы стилей не было и я добился желаемого с вашей помощью.

Ещё момент:
Я при помощи python-docx пытаюсь сохранить документ не в текущую директорию, а в папку 'MergeDocFiles' внутри текущий директории:
doc.save('/MergeDocFiles/' + new_doc_num + ".docx")

В связи чем получаю ошибку: FileNotFoundError: [Errno 2] No such file or directory

Вопрос: Я могу каким-то образом сохранить документ в папке 'MergeDocFiles' без задания абсолютного пути типа C:/Users.... , а просто указав директорию внутри, откуда был запущен скрипт?
 

Lancellot

Новичок
Пользователь
Апр 30, 2020
22
4
3
Снова обращусь к вам за помощью. Дело в том, что скрипт на ноуте у меня работал. При запуске на другом компе с теми же самыми библиотеками (но некоторые версии более новые) возникают ошибки.

Сам скрипт (был раньше рабочий):

Python:
from docx import Document
import os


# Получаем список всеъ файлов с расширением .docx в текущем каталоге.
for filedocx in os.listdir():
    if filedocx.endswith(".docx"):
        print(filedocx)


files = filedocx

def combine_word_documents(files):
    merged_document = Document()

    for index, file in enumerate(files):
        sub_doc = Document(file)

        if index < len(files) - 1:
            sub_doc.add_page_break()

        for element in sub_doc.element.body:
            merged_document.element.body.append(element)

    merged_document.save('../НА ПЕЧАТЬ.docx')

combine_word_documents(files)

Консоль выдаёт сначала результат команды print(filedocx):
Код:
1.docx
2.docx
3.docx

Потом ошибки:
Код:
Traceback (most recent call last):
  File "C:/Users/Grumium/PycharmProjects/MailParsing/venv/MergeDocFiles/Merg.py", line 31, in <module>
    combine_word_documents(files)
  File "C:/Users/Grumium/PycharmProjects/MailParsing/venv/MergeDocFiles/Merg.py", line 21, in combine_word_documents
    sub_doc = Document(file)
  File "C:\Users\Grumium\PycharmProjects\MailParsing\venv\lib\site-packages\docx\api.py", line 25, in Document
    document_part = Package.open(docx).main_document_part
  File "C:\Users\Grumium\PycharmProjects\MailParsing\venv\lib\site-packages\docx\opc\package.py", line 128, in open
    pkg_reader = PackageReader.from_file(pkg_file)
  File "C:\Users\Grumium\PycharmProjects\MailParsing\venv\lib\site-packages\docx\opc\pkgreader.py", line 32, in from_file
    phys_reader = PhysPkgReader(pkg_file)
  File "C:\Users\Grumium\PycharmProjects\MailParsing\venv\lib\site-packages\docx\opc\phys_pkg.py", line 30, in __new__
    raise PackageNotFoundError(
docx.opc.exceptions.PackageNotFoundError: Package not found at 'o'
 

Lancellot

Новичок
Пользователь
Апр 30, 2020
22
4
3
Погуглил ошибку. Судя по вот этому ответу ошибка в файлах, которые находятся в текущем каталоге. Попробуйте скопировать .docx-файлы в другую папку и снова запустить скрипт.

Нет, в файлах ошибки нет. Чтобы это проверить я через "Правая кнопка мыши - создать Word файл" создал пустые .docx файлы. Ошибка не пропала.
Я нашёл, что именно влияет на эту ошибку, но не могу понять почему так происходит.
Последняя строка в дебагере, если я правильно назвал:
Код:
docx.opc.exceptions.PackageNotFoundError: Package not found at 'o'
Ссылается на символ "О".

А вот скрин директории:
error_1.png
Символ "О" это из директории. Если я удаляю папку oldFiles, то получаю ошибку:
Код:
docx.opc.exceptions.PackageNotFoundError: Package not found at 'M'

То есть ругается на название файла Merg.ry. Это сам файл скрипта.
Как победить?
 

Lancellot

Новичок
Пользователь
Апр 30, 2020
22
4
3
Всё работает.
Я безгранично вам благодарен за помощь!
 

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