You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将多个Plotly图表、标签页及图片导出为单个交互式HTML文件

可行实现方案

以下方案均支持PyInstaller打包为exe后在无Python环境的设备上正常运行,生成的HTML为完全独立的单文件,保留Plotly全交互功能。

方案1:轻量原生拼接(最适合打包场景)

该方案无额外重型依赖,打包后exe体积小,无依赖冲突:

  • 处理Plotly图表:调用每个Plotly图对象的to_html(full_html=False, include_plotlyjs='cdn')方法获取单图的HTML片段。如果需要完全离线打开HTML,将include_plotlyjs参数改为'inline'即可,会把Plotly.js库直接内嵌到代码中,不需要依赖网络。注意仅第一个图需要加载Plotly.js,后续图表的include_plotlyjs参数可设为False,避免重复嵌入增加文件体积。
  • 标签页功能直接用原生HTML+内联CSS+内联JS实现,不需要引入外部前端库,完全内联到HTML文件中。
  • 本地图片转base64编码内嵌到<img>标签的src属性,不需要单独附带图片文件,保证单文件完整性。
  • 所有片段拼接为完整HTML字符串后直接写入.html后缀的本地文件即可。

核心代码示例:

import base64
import plotly.express as px

# 示例Plotly图表生成
fig1 = px.line(x=[1,2,3], y=[4,5,6])
fig2 = px.bar(x=[1,2,3], y=[7,8,9])

# 1. 提取Plotly.js内联代码+单图HTML片段
plotly_js_include = fig1.to_html(full_html=False, include_plotlyjs='inline').split('<script type="text/javascript">')[0] + '<script type="text/javascript">' + fig1.to_html(full_html=False, include_plotlyjs='inline').split('<script type="text/javascript">')[1].split('</script>')[0] + '</script>'
fig1_html = fig1.to_html(full_html=False, include_plotlyjs=False)
fig2_html = fig2.to_html(full_html=False, include_plotlyjs=False)

# 2. 本地图片转base64内嵌
def img_to_base64(img_path):
    with open(img_path, 'rb') as f:
        return base64.b64encode(f.read()).decode('utf-8')
img_html = f'<img src="data:image/png;base64,{img_to_base64("你的本地图片路径.png")}" alt="展示图">'

# 3. 拼接完整HTML
full_html = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>导出结果</title>
<style>
/* 自定义样式+标签页样式直接内联 */
.tab-content .tab-pane {{display: none;}}
.tab-content .tab-pane.active {{display: block;}}
.tab-header {{cursor: pointer; padding: 8px 16px; display: inline-block; border: 1px solid #ccc;}}
.tab-header.active {{background: #f0f0f0; border-bottom: none;}}
</style>
{plotly_js_include}
</head>
<body>
<!-- 标签页结构 -->
<div class="tab-group">
  <div class="tab-header active" onclick="switchTab(0)">图表1</div>
  <div class="tab-header" onclick="switchTab(1)">图表2</div>
  <div class="tab-header" onclick="switchTab(2)">图片</div>
</div>
<div class="tab-content">
  <div class="tab-pane active">{fig1_html}</div>
  <div class="tab-pane">{fig2_html}</div>
  <div class="tab-pane">{img_html}</div>
</div>
<script>
// 标签页切换逻辑内联
function switchTab(index) {
  const headers = document.querySelectorAll('.tab-header');
  const panes = document.querySelectorAll('.tab-pane');
  headers.forEach((h, i) => h.classList.toggle('active', i === index));
  panes.forEach((p, i) => p.classList.toggle('active', i === index));
}
</script>
</body>
</html>
"""

# 写入本地文件
with open('导出结果.html', 'w', encoding='utf-8') as f:
    f.write(full_html)

方案2:Jinja2模板引擎(适合复杂样式场景)

如果自定义页面结构和样式复杂度较高,手动拼接字符串容易出错,可以用Jinja2管理HTML模板:

  • 提前写好HTML模板文件,用模板变量占位图表、图片、标签内容的位置
  • 代码中渲染模板时传入Plotly的HTML片段、base64编码的图片内容等变量
  • 渲染得到完整HTML字符串后写入本地文件即可
  • Jinja2为纯Python实现,打包时将模板文件一同打包进exe资源即可,无运行环境依赖。

注意事项

  • 使用include_plotlyjs='cdn'生成的HTML打开时需要联网加载Plotly交互能力,inline模式完全离线可用,仅会增加约3MB的HTML文件体积。
  • 所有外部资源(CSS、JS、图片)全部内联到HTML中,即可保证生成的是完全独立的单文件,拷贝到任意设备可直接打开使用。

内容的提问来源于stack exchange,提问作者dj8030

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 12:21:03