如何将Folium地图转为PNG存入IOBytes并用于PyDocx?
解决Docker环境下Folium地图直接写入docx(无本地文件)的问题
针对你在Streamlit Docker应用中,要把Folium地图直接写入docx报告(不落地本地文件)的需求,以下是可行的实现方案:
核心思路
Folium地图本质是HTML,没有原生转PNG的方法,所以需要先把地图转成HTML字符串,再用工具将HTML渲染为PNG字节流,最后存入BytesIO对象添加到docx中。全程在内存操作,完全符合Docker环境要求。
实现步骤及代码
1. 安装依赖
需要安装folium、python-docx、imgkit,同时Docker容器内要安装wkhtmltopdf(imgkit依赖它渲染HTML)。
2. 完整代码示例
import folium from docx import Document from docx.shared import Inches import io import imgkit # 1. 生成Folium地图并转为HTML字符串 m = folium.Map(location=[51.421606, -0.067276], zoom_start=12) # 可按需添加地图标记、图层等元素 folium.Marker([51.421606, -0.067276], popup="目标位置").add_to(m) # 将地图转为HTML字符串 map_html = m._repr_html_() # 2. 配置imgkit,直接输出PNG字节流 # Docker中wkhtmltoimage默认路径为/usr/bin/wkhtmltoimage config = imgkit.config(wkhtmltoimage='/usr/bin/wkhtmltoimage') # 从HTML字符串生成PNG字节流,第二个参数传False表示不写入文件 png_bytes = imgkit.from_string(map_html, False, config=config) # 3. 将PNG字节流存入BytesIO并添加到docx doc = Document() img_stream = io.BytesIO(png_bytes) doc.add_picture(img_stream, width=Inches(6)) # 4. Streamlit场景下直接返回下载(无需落地文件) doc_bytes = io.BytesIO() doc.save(doc_bytes) doc_bytes.seek(0) # st.download_button("下载自定义报告", doc_bytes, "custom_report.docx")
3. Docker配置
在你的Dockerfile中添加以下命令,确保容器内安装wkhtmltopdf:
# 安装wkhtmltopdf依赖 RUN apt-get update && apt-get install -y wkhtmltopdf
替代方案(若imgkit兼容性有问题)
如果遇到wkhtmltopdf的环境适配问题,可改用Selenium + Headless Chrome实现:
- 在Docker中安装Chrome浏览器和对应版本的ChromeDriver
- 用Selenium加载地图HTML,通过截图获取PNG字节流
不过优先推荐imgkit方案,配置更轻量,性能更优。
内容的提问来源于stack exchange,提问作者CER
相关产品推荐
相关产品推荐

