新手进阶Python:办公看板集成多数据源+ECharts高级可视化

大家好!我是CSDN的Python新手博主~ 上一篇我们完成了看板的移动端适配与企业微信深度集成,打通了全场景办公链路,但很多小伙伴反馈两个核心痛点:① 数据来源太单一,实际工作中数据可能分散在Excel、数据库、CSV文件中,需要手动汇总后导入看板,效率极低;② 图表是静态图片,无法缩放、筛选,想查看某一部门/时间段的细分数据只能重新生成,交互性差。今天就带来超落地的新手实战项目------办公看板多数据源整合+ECharts高级交互式可视化!

本次基于之前的"全场景适配云端看板"代码,新增4大核心功能:① 多数据源统一读取(支持Excel、MySQL数据库、CSV文件,自动适配数据格式);② ECharts交互式图表集成(替换静态图表,实现缩放、点击筛选、多图表联动);③ 自定义图表配置(支持切换图表类型、选择数据维度,如按部门/日期/人员统计);④ 多数据源数据融合分析(如关联MySQL客户数据与Excel销售数据)。全程基于现有技术栈(Flask+HTML),新增数据库连接、ECharts初始化逻辑,代码注释详细,新手只需配置数据源参数,跟着步骤复制操作就能成功,让办公看板具备专业数据分析工具的核心能力~

一、本次学习目标

  1. 掌握Python读取多数据源(Excel/MySQL/CSV)的方法,封装统一数据读取接口,适配不同数据存储场景;

  2. 了解ECharts基础语法与配置逻辑,学会在Flask项目中集成ECharts交互式图表;

  3. 实现图表自定义功能(切换类型、选择维度、筛选条件),适配多样化数据分析需求;

  4. 掌握多数据源数据融合技巧,实现跨来源数据关联分析(如销售数据关联客户信息);

  5. 确保多数据源访问与现有权限体系联动,实现数据访问权限精准管控。

二、前期准备

  1. 安装核心依赖库

安装核心依赖(pymysql对接MySQL,pandas处理数据,openpyxl读取Excel)

pip3 install pymysql pandas openpyxl python-dotenv -i https://pypi.tuna.tsinghua.edu.cn/simple

确保已有依赖正常(Flask、requests等)

pip3 install --upgrade flask flask-login gunicorn requests -i https://pypi.tuna.tsinghua.edu.cn/simple

说明:ECharts为前端框架,无需后端安装,直接通过CDN引入即可;python-dotenv用于安全存储数据库账号密码,避免硬编码。

  1. 数据源准备与配置
  • Excel数据源(复用原有):/home/office_dashboard/每日销售报表/(存储每日销售明细);

  • MySQL数据源(新增):搭建本地/云端MySQL数据库,创建"customer"表(存储客户信息,关联销售数据),记录数据库地址、端口、账号、密码、数据库名;

  • CSV数据源(新增):/home/office_dashboard/部门配置.csv(存储部门与负责人关联关系,用于图表维度补充);

  • 安全配置:创建.env文件存储数据库敏感信息,避免代码泄露。

  1. ECharts资源准备

三、实战:多数据源整合+ECharts可视化升级

  1. 第一步:封装多数据源统一读取接口

-- coding: utf-8 --

datasource.py 多数据源读取脚本

import os

import pandas as pd

import pymysql

from dotenv import load_dotenv

from pathlib import Path

加载环境变量(存储数据库敏感信息)

load_dotenv() # 读取.env文件

====================== 数据源配置(新手修改这里) ======================

1. Excel配置

EXCEL_DIR = "/home/office_dashboard/每日销售报表"

EXCEL_SUFFIX = [".xlsx", ".xls"]

2. MySQL配置(从环境变量读取,避免硬编码)

MYSQL_CONFIG = {

"host": os.getenv("MYSQL_HOST", "localhost"),

"port": int(os.getenv("MYSQL_PORT", 3306)),

"user": os.getenv("MYSQL_USER", "root"),

"password": os.getenv("MYSQL_PASSWORD", "123456"),

"database": os.getenv("MYSQL_DB", "office_data"),

"charset": "utf8mb4"

}

3. CSV配置

CSV_FILE = "/home/office_dashboard/部门配置.csv"

====================== 核心读取函数 ======================

def read_excel_data(date=None):

"""读取Excel销售数据(按日期筛选,无日期则读取全部)"""

try:

excel_files = [f for f in os.listdir(EXCEL_DIR) if any(f.endswith(suf) for suf in EXCEL_SUFFIX)]

if not excel_files:

return pd.DataFrame(), "未找到Excel数据文件"

复制代码
    # 按日期筛选文件(假设文件名格式:20260119_销售报表.xlsx)
    if date:
        target_file = next((f for f in excel_files if date in f), None)
        if not target_file:
            return pd.DataFrame(), f"未找到{date}的Excel数据"
        file_path = os.path.join(EXCEL_DIR, target_file)
        df = pd.read_excel(file_path)
    else:
        # 读取所有Excel文件并合并
        df_list = []
        for f in excel_files:
            file_path = os.path.join(EXCEL_DIR, f)
            df_list.append(pd.read_excel(file_path))
        df = pd.concat(df_list, ignore_index=True)
    
    # 数据标准化(统一列名、格式)
    df.columns = ["date", "name", "dept", "sales", "order_count", "qualified"]
    df["date"] = pd.to_datetime(df["date"]).dt.strftime("%Y-%m-%d")
    return df, "Excel数据读取成功"
except Exception as e:
    return pd.DataFrame(), f"Excel数据读取失败:{str(e)}"

def read_mysql_data(table_name="customer"):

"""读取MySQL数据库数据(默认读取客户表)"""

try:

连接MySQL数据库

conn = pymysql.connect(**MYSQL_CONFIG)

sql = f"SELECT * FROM {table_name};"

df = pd.read_sql(sql, conn)

conn.close()

复制代码
    # 数据标准化(关联销售数据的客户ID列)
    df.columns = ["customer_id", "customer_name", "contact", "dept", "create_time"]
    df["create_time"] = pd.to_datetime(df["create_time"]).dt.strftime("%Y-%m-%d")
    return df, "MySQL数据读取成功"
except Exception as e:
    return pd.DataFrame(), f"MySQL数据读取失败:{str(e)}"

def read_csv_data():

"""读取CSV部门配置数据"""

try:

if not os.path.exists(CSV_FILE):

return pd.DataFrame(), "未找到CSV部门配置文件"

复制代码
    df = pd.read_csv(CSV_FILE, encoding="utf-8")
    # 数据标准化
    df.columns = ["dept", "manager", "dept_code"]
    return df, "CSV数据读取成功"
except Exception as e:
    return pd.DataFrame(), f"CSV数据读取失败:{str(e)}"

def get_combined_data(date=None):

"""多数据源数据融合(销售数据+客户数据+部门配置)"""

try:

读取各数据源

excel_df, excel_msg = read_excel_data(date)

mysql_df, mysql_msg = read_mysql_data()

csv_df, csv_msg = read_csv_data()

复制代码
    # 数据融合(按部门关联)
    combined_df = excel_df.merge(csv_df, on="dept", how="left")  # 销售数据关联部门配置
    combined_df = combined_df.merge(mysql_df[["customer_name", "dept"]], on="dept", how="left")  # 关联客户数据
    
    # 处理缺失值
    combined_df.fillna({"manager": "未分配", "customer_name": "未知客户"}, inplace=True)
    return combined_df, "数据融合成功"
except Exception as e:
    return pd.DataFrame(), f"数据融合失败:{str(e)}"

测试数据源读取功能

if name == "main ":

combined_df, msg = get_combined_data(date="2026-01-19")

print(msg)

print(combined_df.head())

  1. 第二步:创建.env文件,安全存储数据库信息

进入项目目录

cd /home/office_dashboard

创建并编辑.env文件

vim .env

.env 文件(敏感信息配置)

MYSQL_HOST=47.108.xxx.xxx # 数据库地址(本地为localhost)

MYSQL_PORT=3306 # 数据库端口(默认3306)

MYSQL_USER=office_user # 数据库账号

MYSQL_PASSWORD=xxxxxxxx # 数据库密码

MYSQL_DB=office_data # 数据库名

chmod 600 .env # 仅当前用户可读写

  1. 第三步:集成ECharts,实现交互式可视化

(1)引入ECharts CDN,添加图表容器

{% block content %}

图表配置

折线图(销售额趋势) 柱状图(部门销售额对比) 饼图(部门销售额占比) 按日期维度 按部门维度 按人员维度 刷新图表

达标率分布
部门负责人业绩关联

{% endblock %}

(2)编写ECharts初始化与交互脚本

{% block script %}

{% endblock %}

  1. 第四步:修改后端路由,传递融合数据并管控权限

在app.py中修改dashboard路由

from datasource import get_combined_data

import json

@app.route("/")

@login_required

def dashboard():

selected_date = request.args.get("date", TODAY)

available_dates = get_available_dates()

复制代码
# 1. 获取多数据源融合数据
combined_df, combine_msg = get_combined_data(date=selected_date)
if combined_df.empty:
    flash(f"数据加载失败:{combine_msg}", "error")
    combined_data = []
else:
    # 2. 基于用户角色过滤数据(权限管控)
    if current_user.role == "leader":
        # 管理员可查看全部数据
        filtered_df = combined_df
    elif current_user.role == "dept":
        # 部门负责人仅查看本部门数据
        filtered_df = combined_df[combined_df["dept"] == current_user.dept]
    else:
        # 普通员工仅查看个人数据
        filtered_df = combined_df[combined_df["name"] == current_user.name]
    
    # 3. 转换为JSON格式,传递给前端
    combined_data = filtered_df.to_dict("records")

# 4. 原有数据汇总、图表路径逻辑保留
summary, detail_data = get_summary_data(filtered_df)  # 基于过滤后的数据生成汇总
chart_path = get_chart_path(selected_date)  # 保留原有静态图表路径(备用)

return render_template(
    "dashboard.html",
    summary=summary,
    detail_data=detail_data,
    combined_data=combined_data,  # 传递融合数据给前端ECharts
    chart_path=chart_path,
    available_dates=available_dates,
    selected_date=selected_date,
    current_user=current_user
)

新增:数据导出接口(支持多格式、自定义字段)

@app.route("/export/data", methods=["POST"])

@login_required

def export_data():

data = request.get_json()

export_format = data.get("format", "excel") # excel/csv

fields = data.get("fields", ["date", "name", "dept", "sales"]) # 自定义导出字段

复制代码
# 获取融合数据并过滤
selected_date = data.get("date", TODAY)
combined_df, _ = get_combined_data(date=selected_date)
if current_user.role != "leader":
    combined_df = combined_df[combined_df["dept"] == current_user.dept]

# 筛选导出字段
export_df = combined_df[fields]

# 生成导出文件
filename = f"办公数据_{selected_date}.{export_format}"
if export_format == "excel":
    response = make_response(export_df.to_excel(index=False, engine="openpyxl"))
    response.headers["Content-Disposition"] = f"attachment; filename={filename}"
    response.headers["Content-Type"] = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
else:
    response = make_response(export_df.to_csv(index=False, encoding="utf-8-sig"))
    response.headers["Content-Disposition"] = f"attachment; filename={filename}"
    response.headers["Content-Type"] = "text/csv"

return response
  1. 第五步:测试验证功能

重启Gunicorn和Nginx

kill -9 (ps aux \| grep gunicorn \| grep -v grep \| awk '{print 2}')

nohup gunicorn -w 4 -b 0.0.0.0:5000 app:app &

systemctl restart nginx

  • 多数据源读取:访问看板,验证是否加载Excel销售数据、MySQL客户数据、CSV部门配置数据,数据融合正常;

  • 图表交互:切换图表类型(折线/柱状/饼图)、数据维度(日期/部门/人员),图表是否实时刷新,支持缩放、鼠标悬浮查看详情;

  • 多图表联动:点击主图表某一数据项,验证是否触发详细数据筛选(可结合前端表格插件完善);

  • 权限管控:用不同角色账号登录,验证是否仅能查看对应范围的数据,导出功能也受权限限制;

  • 数据导出:测试导出功能,验证是否能自定义字段,导出Excel/CSV格式文件正常。

五、新手避坑小贴士

  1. MySQL连接失败:优先检查3点------① .env文件中数据库参数是否正确;② 数据库是否允许外网访问(云数据库需配置安全组);③ 服务器是否安装MySQL客户端,网络能否ping通数据库地址;

  2. 数据格式不统一:确保各数据源的关联字段(如"dept")格式一致(大小写、名称统一),可在read_*函数中添加格式校验;

  3. ECharts图表不显示:检查CDN是否引入成功,图表容器是否设置宽高,后端传递的combined_data是否为JSON格式,控制台打印是否有报错;

  4. 中文乱码问题:CSV文件读取时指定encoding="utf-8",MySQL数据库charset设置为utf8mb4,导出CSV时用encoding="utf-8-sig";

  5. 数据量过大导致卡顿:在数据聚合时限制时间范围(按日期筛选),ECharts启用数据分页或抽样展示,避免一次性加载过多数据;

  6. 导出功能报错:确保导出字段在融合数据中存在,Excel导出需安装openpyxl引擎,避免字段名包含特殊字符。

六、进阶扩展(新手可选)

  1. 实时数据更新:集成WebSocket,实现多数据源数据实时推送,图表自动刷新,无需手动刷新页面;

  2. 更多图表类型支持:扩展ECharts配置,添加雷达图(多维度对比)、散点图(数据分布)、热力图(关联分析);

  3. 数据脱敏功能:对导出和展示的数据进行脱敏(如隐藏客户联系方式、员工手机号),符合数据合规要求;

  4. 自定义报表模板:支持用户保存常用图表配置和导出字段,生成个性化报表模板,一键加载;

  5. 大数据量优化:引入Redis缓存热点数据,使用Pandas分块读取大文件,ECharts开启增量渲染,提升页面加载速度。

七、总结与系列数据能力闭环

  • AI增强分析:结合之前的OpenAI集成,让ECharts图表支持自然语言生成(如"生成近7天各部门销售额对比柱状图");

  • 数据中台对接:集成企业数据中台API,实现更广泛的数据源接入(ERP、CRM、OA系统);

  • 报表自动化分发:按预设规则定时生成可视化报表,自动推送至企业微信/邮箱,无需手动操作。

如果这篇文章对你有帮助,欢迎点赞收藏+关注!如果在多数据源配置、ECharts图表调试、数据导出时遇到问题,随时在评论区留言,我会逐一解答~ 新手不用怕多数据源整合和可视化开发,跟着步骤一步步测试,就能让你的办公看板具备专业数据分析能力,用数据赋能团队高效工作!

相关推荐
猛扇赵四那边好嘴.2 小时前
Flutter 框架跨平台鸿蒙开发 - 问答社区应用开发教程
开发语言·javascript·flutter·华为·harmonyos
C_心欲无痕2 小时前
Next.js 路由系统对比:Pages Router vs App Router
开发语言·前端·javascript
LawrenceLan2 小时前
Flutter 零基础入门(二十二):Text 文本组件与样式系统
开发语言·前端·flutter·dart
程序员敲代码吗2 小时前
如何从Python初学者进阶为专家?
jvm·数据库·python
kylezhao20192 小时前
C# 各种类型转换深入剖析
开发语言·c#
hxjhnct2 小时前
JavaScript 的 new会发生什么
开发语言·javascript
少控科技2 小时前
QT进阶日记004
开发语言·qt
狗都不学爬虫_2 小时前
JS逆向 - 最新版某某安全中心滑块验证(wasm设备指纹)
javascript·爬虫·python·网络爬虫·wasm
阿杰 AJie2 小时前
Lambda 表达式大全
开发语言·windows·python