Python-docx - 从 URL 将图片插入 docx

Posted

技术标签:

【中文标题】Python-docx - 从 URL 将图片插入 docx【英文标题】:Python-docx - insert picture into docx from URL 【发布时间】:2020-06-19 07:49:29 【问题描述】:

我正在尝试抓取网站(例如 imgur)上托管的图像并将其添加到 docx。

这是我的初始代码(这是函数的一部分。我已将其剥离为相关代码):

from PIL import Image
from urllib.request import urlopen

thisParagraph = document.sections[0].paragraphs[0]
run = thisParagraph.add_run()

# imgLink is a direct link to the image. Something like https://i.imgur.com/<name>.jpg
# online is a parsed-in boolean to determine if the image link is from an image hosting site
# or from the local machine
if (online):
   imgLinkData = urlopen(imgLink )
   img = Image.open(imgLinkData )
   width, height = img.size
else:
   img = Image.open(imgLink )
   width, height = img.size
   imgLinkData = imgLink 

if (width > 250) or (height > 250):
   if (height > width):
       run.add_picture(imgLinkData, width=Cm(3), height=Cm(4) )
   else:
       run.add_picture(imgLinkData, width=Cm(4), height=Cm(3) )
else:
       run.add_picture(imgLinkData)

在大多数情况下,如果 imgLink 指向我的本地系统(即图像托管在我的 PC 上),则此方法有效。

但如果我引用一个 url 链接(online=True),我会得到各种类型的异常(我试图修复它),范围从 io.UnsupportOperation(搜索)到 TypeError(需要字符串参数,得到' bytes'),原因总是run.add_picture 行。

现在的代码会引发io.UnsupportOperation 异常。

【问题讨论】:

【参考方案1】:

将图像保存到文件中,然后使用文件路径作为.add_picture() 的第一个参数。这大概是这样的:

img.save("my-image.jpg")
run.add_picture("my-image.jpg", width=Cm(3), height=Cm(4))

作为替代方案,您可以创建一个包含图像的“内存中”文件 (io.BytesIO) 并使用它。第二种方法的优点是不需要访问文件系统。

import io
image_stream = io.BytesIO(imgLinkData)
run.add_picture(image_stream, width=Cm(3), height=Cm(4))

Document.add_picture() 的接口需要一个 str 路径或类似文件的对象(打开的文件或内存中的文件)作为其第一个参数:https://python-docx.readthedocs.io/en/latest/api/document.html#docx.document.Document.add_picture

【讨论】:

按照建议,我修改为:if (online): imgLinkData = urlopen(imgLink ) img = Image.open(imgLinkData ) width, height = img.size image_stream = io.BytesIO(imgLinkData) 我在该特定行得到了TypeError: a bytes-like object is required, not 'HTTPResponse'。如果可能的话,我宁愿不将图像保存到机器上。【参考方案2】:

我想我可能已经解决了这个问题。

基于this link,我对自己的代码做了一些细微的修改。

我补充说:

import requests, io

然后我改变了:

imgLinkData = urlopen(imgLink )

imgLinkData= io.BytesIO(requests.get(imgLink ).content )

这似乎已经成功地在我的 docx 文档中生成了图像,虽然我不完全确定为什么,除了 urlopen 返回的事实

<class 'http.client.HTTPResponse'>

requests.get 返回

<class 'requests.models.Response'>

和 .content 返回一个

<class 'bytes'>

对象。

Further reading 甚至似乎表示反对使用urllib

【讨论】:

以上是关于Python-docx - 从 URL 将图片插入 docx的主要内容,如果未能解决你的问题,请参考以下文章

将变量插入到python-docx生成的单词doc的标题中

python-docx 插入点

Python-docx

页码python-docx

python-docx 中文个人翻译

如何使用 mysql 数据库中的存储过程在数据库中插入图像 url?