我已经在文档中搜索了python-docx
和其他软件包,以及堆栈溢出,但是找不到如何使用python从docx
文件中删除所有图像的方法。
我的确切用例:我需要将数百个Word文档转换为“草稿”格式,以供客户查看。这些草稿应与原始文档相同,但所有图像都必须从中删除/编辑。
很抱歉,没有提供我尝试过的事情的示例,我尝试过的是数小时未提供任何信息的研究。我发现了有关如何从Word文件中提取图像的问题,但这并没有从实际文档中删除它们:Extract pictures from Word and Excel with Python
从那里和其他来源,我发现docx
文件可以读取为简单的zip文件,我不知道这是否意味着可以在没有图像的情况下“重新压缩”而不影响docx
文件的完整性(编辑:仅删除图像即可,但由于缺少对图像的引用而阻止python-docx
继续使用此文件),但认为这可能是指向文件的路径。解决方案。
有什么想法吗?
答案 0 :(得分:3)
如果您的目标是编辑图像,那么我在类似用例中使用的这段代码可能会有用:
import sys
import zipfile
from PIL import Image, ImageFilter
import io
blur = ImageFilter.GaussianBlur(40)
def redact_images(filename):
outfile = filename.replace(".docx", "_redacted.docx")
with zipfile.ZipFile(filename) as inzip:
with zipfile.ZipFile(outfile, "w") as outzip:
for info in inzip.infolist():
name = info.filename
print(info)
content = inzip.read(info)
if name.endswith((".png", ".jpeg", ".gif")):
fmt = name.split(".")[-1]
img = Image.open(io.BytesIO(content))
img = img.convert().filter(blur)
outb = io.BytesIO()
img.save(outb, fmt)
content = outb.getvalue()
info.file_size = len(content)
info.CRC = zipfile.crc32(content)
outzip.writestr(info, content)
在这里,我使用了PIL来模糊某些文件中的图像,但是可以使用任何其他合适的操作来代替模糊滤镜。对于我的用例来说,这很好。
答案 1 :(得分:1)
我认为它当前未在python-docx中实现。
Word对象模型中的图片定义为浮动形状或嵌入式形状。 docx documentation声明它仅支持嵌入式形状。
内联形状的Word Object Model支持Delete()
方法,该方法应该可以访问。但是,它没有在examples of InlineShapes中列出,段落也有类似的方法。对于段落,有一个open feature request添加此功能-可以追溯到2014年!如果未将其添加到段落中,则InlineShapes将无法使用它们,因为它们被实现为离散的段落。
如果您安装了装有Word和Python的计算机,则可以使用win32com进行此操作。
这将允许您直接调用Word对象模型,从而使您可以访问Delete()
方法。实际上,您可能会作弊-可以滚动查找和替换来清除图像,而不是滚动浏览文档以获取每个图像。 This SO question讨论了win32com查找和替换:
import win32com.client
from os import getcwd, listdir
docs = [i for i in listdir('.') if i[-3:]=='doc' or i[-4:]=='docx'] #All Word file
FromTo = {"First Name":"John",
"Last Name":"Smith"} #You can insert as many as you want
word = win32com.client.DispatchEx("Word.Application")
word.Visible = True #Keep comment after tests
word.DisplayAlerts = False
for doc in docs:
word.Documents.Open('{}\\{}'.format(getcwd(), doc))
for From in FromTo.keys():
word.Selection.Find.Text = From
word.Selection.Find.Replacement.Text = FromTo[From]
word.Selection.Find.Execute(Replace=2, Forward=True) #You made the mistake here=> Replace must be 2
name = doc.rsplit('.',1)[0]
ext = doc.rsplit('.',1)[1]
word.ActiveDocument.SaveAs('{}\\{}_2.{}'.format(getcwd(), name, ext))
word.Quit() # releases Word object from memory
在这种情况下,由于我们需要图像,因此需要使用短代码^ g作为find.Text和空白作为替换。
word.Selection.Find
find.Text = "^g"
find.Replacement.Text = ""
find.Execute(Replace=1, Forward=True)
答案 2 :(得分:0)
我对这个库不了解,但是翻阅我发现的文档this section about images。它提到当前无法插入除嵌入式图像以外的其他图像。如果那是您当前在文档中所拥有的,我想您还可以通过在Document对象中查找然后将其删除来检索它们?
here对文档进行了说明。
尽管不是重复的,但您可能还需要查看this question's answer,其中“ scanny”用户说明他如何使用该库查找图像。