Python从入门到精通day48

报表制作实战:Excel/PDF 导出与前端可视化图表

在 Web 项目中,报表是数据的可视化呈现形式(报表 = 多样的格式 + 动态的数据)。本节课将基于 Django 实现三类核心报表功能:Excel 文件导出、PDF 文件导出、前端 ECharts 统计图表,满足不同场景下的数据展示需求。

一、导出 Excel 报表

报表就是用表格、图表等格式来动态显示数据,所以有人用这样的公式来描述报表:

复制代码
报表 = 多样的格式 + 动态的数据

Excel 报表适合数据批量下载、离线分析,我们选用xlwt库(轻量、性能优,仅支持 xls 格式)实现教师信息 Excel 导出。

1.安装依赖

复制代码
pip install xlwt

2.编写 Excel 导出视图函数

复制代码
def export_teachers_excel(request):
    # 创建工作簿
    wb = xlwt.Workbook()
    # 添加工作表
    sheet = wb.add_sheet('老师信息表')
    # 查询所有老师的信息
    queryset = Teacher.objects.all()
    # 向Excel表单中写入表头
    colnames = ('姓名', '介绍', '好评数', '差评数', '学科')
    for index, name in enumerate(colnames):
        sheet.write(0, index, name)
    # 向单元格中写入老师的数据
    props = ('name', 'detail', 'good_count', 'bad_count', 'subject')
    for row, teacher in enumerate(queryset):
        for col, prop in enumerate(props):
            value = getattr(teacher, prop, '')
            if isinstance(value, Subject):
                value = value.name
            sheet.write(row + 1, col, value)
    # 保存Excel
    buffer = BytesIO()
    wb.save(buffer)
    # 将二进制数据写入响应的消息体中并设置MIME类型
    resp = HttpResponse(buffer.getvalue(), content_type='application/vnd.ms-excel')
    # 中文文件名需要处理成百分号编码
    filename = quote('老师.xls')
    # 通过响应头告知浏览器下载该文件以及对应的文件名
    resp['content-disposition'] = f'attachment; filename*=utf-8\'\'{filename}'
    return resp
  1. 配置 URL 路由

    urlpatterns = [

    复制代码
     path('excel/', views.export_teachers_excel),

    ]

核心优化说明

select_related('subject'):关联查询学科,避免循环中多次查询数据库(N+1 问题);

BytesIO:内存中操作文件,无需生成临时文件,提升性能;

quote():处理中文文件名,避免浏览器解析乱码;

• 表头样式:可选配置,提升 Excel 可读性。

二、导出 PDF 报表

  1. 安装依赖

    安装reportlab库(PDF生成核心库)

    pip install reportlab

  2. 编写 PDF 导出视图函数

    def export_pdf(request: HttpRequest) -> HttpResponse:
    buffer = io.BytesIO()
    pdf = canvas.Canvas(buffer)
    pdf.setFont("Helvetica", 80)
    pdf.setFillColorRGB(0.2, 0.5, 0.3)
    pdf.drawString(100, 550, 'hello, world!')
    pdf.showPage()
    pdf.save()
    resp = HttpResponse(buffer.getvalue(), content_type='application/pdf')
    resp['content-disposition'] = 'inline; filename="demo.pdf"'
    return resp

  3. 配置 URL 路由

    urlpatterns = [
    # 其他路由...
    path('export/pdf/', views.export_teachers_pdf, name='export_pdf'), # PDF导出
    ]

关键说明

字体问题reportlab默认无中文字体,需指定系统存在的中文字体(如SimSun宋体、Microsoft YaHei微软雅黑);

• 页面布局:
canvas:适合自定义位置绘制(如报表、证件),灵活度高;
SimpleDocTemplate:适合流式文档(如长文本、列表),自动分页;

• 响应头配置:
inline:浏览器在线预览 PDF;
attachment:强制下载 PDF 文件。

三、生成前端统计图表

前端图表适合数据可视化展示(柱状图、折线图、饼图等),我们使用百度 ECharts(开源、易用)实现教师好评 / 差评统计。

  1. 编写数据接口视图

    def get_teachers_data(request):
    queryset = Teacher.objects.all()
    names = [teacher.name for teacher in queryset]
    good_counts = [teacher.good_count for teacher in queryset]
    bad_counts = [teacher.bad_count for teacher in queryset]
    return JsonResponse({'names': names, 'good': good_counts, 'bad': bad_counts})

  2. 配置 URL 路由

    urlpatterns = [
    path('teachers_data/', views.get_teachers_data),
    ]

  3. 编写前端图表页面(ECharts)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>老师评价统计</title> </head> <body>

    返回首页

    <script src="https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts.min.js"></script> <script> var myChart = echarts.init(document.querySelector('#main')) fetch('/teachers_data/') .then(resp => resp.json()) .then(json => { var option = { color: ['#f00', '#00f'], title: { text: '老师评价统计图' }, tooltip: {}, legend: { data:['好评', '差评'] }, xAxis: { data: json.names }, yAxis: {}, series: [ { name: '好评', type: 'bar', data: json.good }, { name: '差评', type: 'bar', data: json.bad } ] } myChart.setOption(option) }) </script> </body> </html>

运行效果如下图所示。

核心优化说明

数据请求 :使用fetch异步获取数据,添加错误处理,提升用户体验;

图表适配
resize事件:窗口大小变化时图表自适应;
rotate:X 轴标签旋转,避免教师姓名重叠;
min: 0:Y 轴最小值设为 0,数据展示更合理;

• 样式优化:自定义颜色(好评绿、差评红)、柱子宽度,提升可读性;

• 性能优化:后端仅返回所需字段(values查询),减少数据传输量。

四、扩展与最佳实践

  1. Excel 格式扩展(xlsx)

若需支持 xlsx 格式,可改用openpyxl库,核心代码调整:

复制代码
from openpyxl import Workbook
from openpyxl.styles import Font

def export_teachers_xlsx(request):
    wb = Workbook()
    sheet = wb.active
    sheet.title = '老师信息表'
    # 写入表头(略)
    # 写入数据(略)
    buffer = BytesIO()
    wb.save(buffer)
    resp = HttpResponse(buffer.getvalue(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    resp['Content-Disposition'] = f'attachment; filename*=utf-8\'\'{quote("老师信息表.xlsx")}'
    return resp
  1. PDF 复杂报表优化

• 批量数据:使用SimpleDocTemplate+Table组件实现表格;

• 中文支持:若reportlab无中文字体,可手动加载字体文件:

复制代码
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
# 注册字体(需提前准备字体文件,如simsun.ttf)
pdfmetrics.registerFont(TTFont('SimSun', 'static/fonts/simsun.ttf'))
  1. 前端图表扩展

• 切换图表类型:将type: 'bar'改为'line'(折线图)、'pie'(饼图)即可;

• 数据筛选:前端添加时间 / 学科筛选条件,后端接收参数后过滤数据;

• 动态刷新:添加定时刷新(setInterval),实时更新数据。

五、小结

本次实战完成了三类报表的核心实现,覆盖数据下载、离线文档、在线可视化场景:
关键点回顾

1.Excel 导出xlwt(xls)/openpyxl(xlsx),内存缓冲区操作,中文文件名编码;

  1. PDF 导出reportlab库,canvas 自定义绘制,注意中文字体配置;

  2. 前端图表 :ECharts 异步获取数据,适配性优化,样式自定义;

  3. 性能优化:关联查询、字段筛选、内存操作,减少数据库 / 网络开销。

六、AI工具,提高学习,工作效率,神器

国内直接使用顶级AI工具

谷歌浏览器访问:

https://www.nezhasoft.cloud/r/vMPJZr

相关推荐
虎大猫猫2 小时前
JupyterLab的安装与使用完全指南
ide·python·jupyter
晨晖22 小时前
java容器类的博客
java·开发语言
web3.08889992 小时前
如何确保1688商品数据API接口的安全性
python
<-->2 小时前
SGLang 相比 vLLM 的主要优势
人工智能·pytorch·python·transformer
leo__5202 小时前
MHT多假设跟踪算法(Multiple Hypothesis Tracking)MATLAB实现
开发语言·算法·matlab
燃于AC之乐2 小时前
深入解剖STL RB-tree(红黑树):用图解带入相关复杂操作实现
开发语言·c++·stl·红黑树·大厂面试·图解·插入操作
夫唯不争,故无尤也2 小时前
Agent 开发者如何快速上手 SQL:从表设计到 Python 交互的一篇实战入门
python·sql·交互
a1117762 小时前
堆叠式流程图编辑器(html 开源)
开发语言·前端·javascript·开源·编辑器·html·流程图