Похоже модуль docx
не работает с EMF
файлами.
Работа, которую я имею в виду, находится здесь:
import shutil
import zipfile
temp_dir = "_temp"
old_docx = "doc.docx"
new_docx = "doc_new.docx"
old_emf = temp_dir + "/word/media/image1.emf"
new_emf = "new_image.emf"
# unpack content of the docx file into the temp folder
with zipfile.ZipFile(old_docx, "r") as z:
files = z.namelist()
for f in files: z.extract(f, temp_dir)
# replace the image
shutil.copyfile(new_emf, old_emf)
# pack all files from temp folder back into the new docx file
with zipfile.ZipFile(new_docx, "a") as z:
for f in files: z.write(temp_dir + "/" + f, f)
# remove the temp folder
shutil.rmtree(temp_dir)
Типичная структура файла docx:
doc.docx
│
├─ [Content_Types].xml
│
├─ _rels
│ └─ .rels
│
├─ docProps
│ ├─ app.xml
│ └─ docProps
│
└─ word
├─ document.xml <-- text is here
├─ fontTable.xml
├─ settings.xml
├─ webSettings.xml
├─ styles.xml
│
├─ _rels
│ └─ document.xml.rels
│
├─ theme
│ └─ theme1.xml
│
└─ media
└─ image1.emf <-- your image is here
Он распаковывает содержимое файла doc doc.docx
во временную папку _temp
, затем заменяет файл image1.emf
во временной папке другим файлом new_image.emf
из текущей папки. Затем он упаковывает содержимое временной папки обратно в файл doc_new.docx
и удаляет временную папку.
Примечание: новое изображение будет иметь тот же размер в new_doc.docx
, что и старое.
Таким образом, рабочий процесс может быть таким: вы создаете файл шаблона docx, помещаете туда вручную шаблон изображения emf и сохраняете файл docx. Затем вы берете новый образ emf, кладете изображение рядом с файлом docx и запускаете скрипт. Таким образом вы получите новый файл docx с новым изображением emf.
Я полагаю, у вас много изображений в формате emf, поэтому имеет смысл добавить в этот скрипт пару строк, чтобы он мог взять несколько изображений и сделать несколько файлов docx.
Он будет работать нормально, если все изображения emf имеют одинаковый размер. Если они имеют разный размер, потребуется больше кода для обработки данных xml.
Обновить
Я понял, как получить размеры изображения emf. Итак, вот полное решение:
from docx import Document
import shutil
import zipfile
temp_dir = "_temp"
old_docx = "doc.docx"
new_docx = "doc_new.docx"
old_emf = temp_dir + "/word/media/image1.emf" # don't change this line
new_emf = "img5.emf"
# unpack content of the docx file into temp folder
with zipfile.ZipFile(old_docx, "r") as z:
files = z.namelist()
for f in files: z.extract(f, temp_dir)
# replace the image
shutil.copyfile(new_emf, old_emf)
# pack all files from temp folder back into the new docx file
with zipfile.ZipFile(new_docx, "a") as z:
for f in files: z.write(temp_dir + "/" + f, f)
# remove temp folder
shutil.rmtree(temp_dir)
# get sizes of the emf image
with open(new_emf, "rb") as f:
f.read(16)
w1, w2 = f.read(1).hex(), f.read(1).hex()
f.read(2)
h1, h2 = f.read(1).hex(), f.read(1).hex()
width = int(str(w2) + str(w1), 16) * 762
height = int(str(h2) + str(h1), 16) * 762
# open the new docx file and set the sizes for the image
doc = Document(new_docx)
img = doc.inline_shapes[0] # suppose the first image is the image
img.width = width
img.height = height
doc.save(new_docx)
person
Yuri Khristich
schedule
25.05.2021