尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

python操作sqlite——数据库导出Excel报表——2020.12.25

python操作sqlite——数据库导出Excel报表——2020.12.25 1. 为什么我还在用 sqlite3 openpyxl 做报表Python 操作 SQLite 数据库导出 Excel 报表说白了就两件事用标准库sqlite3把数据查出来再用openpyxl把结果写成带样式的 xlsx 文件。它适合谁适合手里有一个本地.db文件、又不想装 MySQL/PostgreSQL 那套服务的人比如课程设计、小型进销存、爬虫落库后的二次整理或者像我这样临时要交一份“能直接打开看”的表格给同事。我试过用 pandas 一行to_excel搞定快是快但一旦要合并单元格、冻结首行、给表头加底色、按数值区间标红pandas 就得绕回 openpyxl 的底层对象反而更啰嗦。所以这篇我按“标准库读取 openpyxl 精细写样式”的路线走全程只用 Python 自带模块加一个openpyxl不碰任何数据库服务。核心检索词先摆出来python sqlite 数据库导出 Excel 报表。你能得到的是——可复制的建表与查询脚本、字段映射配置、表头样式代码以及运行后打开 xlsx 核对行数与列名的验证动作。整条链路在本地跑数据不出机器适合对数据流向比较在意的场景。先说清楚数据流SQLite 文件 →sqlite3.connect()建立连接 →cursor.execute()执行 SELECT →fetchall()拿到行元组 → openpyxl 的Worksheet.append()或单元格写入 →workbook.save()落盘成 xlsx。中间任何一步出错报错信息都挺直白排查成本低这也是我愿意用它做小报表的原因。下面按“先建库造数据、再写导出脚本、然后验证、最后排错”的顺序展开。你如果已经有现成的.db可以直接跳到第 3 节改字段映射。2. 前置准备TaoToken 与本地环境怎么配这一节讲两件前置的事一是本地 Python 环境二是如果你想让脚本里的“字段映射/表头文案”这类配置更省心可以借助 TaoToken 的模型对话能力来生成或校对映射配置。TaoToken 是一个聚合多家大模型能力的 API 平台官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。它能做什么简单说你拿到一个 Key就能用统一的接口调用不同模型适合把“生成 SQL、解释报错、写字段映射”这类零碎活儿交给模型自己专注在业务逻辑上。适合谁适合经常写脚本、又不想为每个模型单独注册账号的开发者。本地环境部分确认 Python 版本和装包python --version # 期望输出 Python 3.8 及以上我这边是 3.11 pip install openpyxl # sqlite3 是标准库不用装如果你要用 TaoToken 辅助生成配置先在控制台创建 Key。入口在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。拿到 Key 后调用方式兼容 OpenAI 风格的接口Base URL 填https://taotoken.net/apiModel ID 按你选的模型填。想先试对话效果可以去 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 直接聊两句确认返回正常再写进脚本。这里要提醒一句TaoToken 是模型调用入口不是数据库工具别指望它替你连 SQLite。它的定位是“帮你把配置和 SQL 写对”真正的读写还是本地sqlite3干。把职责分清后面排错才不会乱。环境变量建议这样设避免 Key 硬编码进脚本# Linux / macOS export TAOTOKEN_API_KEY你的Key # Windows PowerShell $env:TAOTOKEN_API_KEY你的KeyPython 里用os.environ.get(TAOTOKEN_API_KEY)读取。这样脚本可以进 GitKey 不会泄露。如果你只是本地跑导出、暂时不需要模型辅助这一节的环境变量可以先跳过直接进第 3 节。3. 可复制配置建表、查询与字段映射这一节给全套可复制代码。先造一个测试库模拟成绩表字段包括学号、姓名、教学班、分数。建表脚本import sqlite3 conn sqlite3.connect(jwxt.db) c conn.cursor() c.execute( CREATE TABLE IF NOT EXISTS Grade ( id INTEGER PRIMARY KEY AUTOINCREMENT, XH TEXT NOT NULL, XM TEXT NOT NULL, JXBID TEXT NOT NULL, SCORE REAL ) ) rows [ (2020001, 张三, JXB001, 88.5), (2020002, 李四, JXB001, 92.0), (2020003, 王五, JXB002, 76.5), (2020004, 赵六, JXB001, 59.0), ] c.executemany(INSERT INTO Grade (XH, XM, JXBID, SCORE) VALUES (?, ?, ?, ?), rows) conn.commit() conn.close() print(建库完成共写入, len(rows), 行)字段映射配置单独抽出来方便改表头文案和列顺序。用一个列表套字典的结构COLUMN_MAP [ {field: XH, header: 学号, width: 14}, {field: XM, header: 姓名, width: 12}, {field: JXBID, header: 教学班, width: 14}, {field: SCORE, header: 分数, width: 10}, ]导出脚本主体注意表头样式和冻结首行import sqlite3 from openpyxl import Workbook from openpyxl.styles import Font, PatternFill, Alignment, Border, Side COLUMN_MAP [ {field: XH, header: 学号, width: 14}, {field: XM, header: 姓名, width: 12}, {field: JXBID, header: 教学班, width: 14}, {field: SCORE, header: 分数, width: 10}, ] def export_report(db_path, jxbid, out_path): conn sqlite3.connect(db_path) c conn.cursor() fields , .join(item[field] for item in COLUMN_MAP) sql fSELECT {fields} FROM Grade WHERE JXBID ? c.execute(sql, (jxbid,)) data c.fetchall() conn.close() wb Workbook() ws wb.active ws.title 成绩报表 header_font Font(name微软雅黑, size11, boldTrue, colorFFFFFF) header_fill PatternFill(solid, fgColor4472C4) center Alignment(horizontalcenter, verticalcenter) thin Side(stylethin, colorBFBFBF) border Border(leftthin, rightthin, topthin, bottomthin) for col_idx, item in enumerate(COLUMN_MAP, start1): cell ws.cell(row1, columncol_idx, valueitem[header]) cell.font header_font cell.fill header_fill cell.alignment center cell.border border ws.column_dimensions[cell.column_letter].width item[width] for row_idx, row in enumerate(data, start2): for col_idx, value in enumerate(row, start1): cell ws.cell(rowrow_idx, columncol_idx, valuevalue) cell.alignment center cell.border border ws.freeze_panes A2 wb.save(out_path) return len(data) if __name__ __main__: n export_report(jwxt.db, JXB001, output.xlsx) print(f导出完成共 {n} 行数据)如果你更习惯用 settings 文件管理配置可以把它写成 JSON脚本读进来即可{ db_path: jwxt.db, out_path: output.xlsx, columns: [ {field: XH, header: 学号, width: 14}, {field: XM, header: 姓名, width: 12}, {field: JXBID, header: 教学班, width: 14}, {field: SCORE, header: 分数, width: 10} ] }读取时用json.load(open(report.json, encodingutf-8))把columns传给导出函数。这样换一张表只改 JSON不动 Python 代码。注意 SQL 里字段名是拼进字符串的所以field值必须来自你自己的白名单别直接拿用户输入拼避免注入。4. 验证请求与成功结果打开 xlsx 核对行数列名脚本跑完不算完得验证。运行python export_report.py # 输出导出完成共 3 行数据JXB001 这个班有张三、李四、赵六三条所以 3 行是对的。接着用 openpyxl 反向读一遍核对行数和列名这步比肉眼打开更可靠from openpyxl import load_workbook wb load_workbook(output.xlsx) ws wb.active print(工作表名:, ws.title) print(总行数(含表头):, ws.max_row) print(总列数:, ws.max_column) print(表头:, [ws.cell(row1, columni).value for i in range(1, ws.max_column 1)]) print(首行数据:, [ws.cell(row2, columni).value for i in range(1, ws.max_column 1)])期望输出工作表名: 成绩报表 总行数(含表头): 4 总列数: 4 表头: [学号, 姓名, 教学班, 分数] 首行数据: [2020001, 张三, JXB001, 88.5]总行数 4 1 行表头 3 行数据列名和 COLUMN_MAP 里的 header 完全一致首行数据字段顺序也对得上。到这一步报表就算导出成功了。再手动双击output.xlsx确认首行冻结、表头蓝底白字、边框完整。如果你想让模型帮你核对字段映射有没有漏可以把 COLUMN_MAP 和表头输出贴给 TaoToken 的模型对话让它比对字段名和中文表头是否一一对应。入口在 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 适合字段多、人工核对容易看花眼的情况。验证通过后把export_report包一层循环就能按教学班批量导出多个 sheet 或多个文件for jxbid in [JXB001, JXB002]: n export_report(jwxt.db, jxbid, freport_{jxbid}.xlsx) print(jxbid, -, n, 行)5. 本篇常见错排查401、local proxy failed、reading choices排错这节按真实报错来。先说清楚下面这些报错分两类一类是本地 sqlite/openpyxl 的一类是你用 TaoToken 辅助时可能遇到的接口报错。第一类本地导出报错。sqlite3.OperationalError: no such table: Grade—— 库文件路径不对或者表名拼错。先确认jwxt.db和脚本在同一目录再执行SELECT name FROM sqlite_master WHERE typetable;看实际表名。SQLite 表名大小写不敏感但拼写必须一致。openpyxl.utils.exceptions.IllegalCharacterError—— 单元格里混进了 Excel 不认的控制字符常见于从网页抓来的文本。写入前清洗value .join(ch for ch in str(value) if ch.isprintable())。PermissionError: [Errno 13] Permission denied: output.xlsx—— 文件正被 Excel 打开关掉再跑。这个坑我踩过不止一次脚本没报错逻辑问题纯粹是文件被占用。第二类TaoToken 接口报错。401 Unauthorized—— Key 没带对或已失效。检查请求头Authorization: Bearer $TAOTOKEN_API_KEY确认环境变量真的导出成功echo $TAOTOKEN_API_KEY看有没有值。Key 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 管理重新生成一个再试。local proxy failed—— 本地网络层拦截了请求。先确认 Base URL 写的是https://taotoken.net/api没有多余斜杠或路径再检查本机有没有设置奇怪的全局代理环境变量HTTP_PROXY/HTTPS_PROXY有就临时清掉。注意这里说的是排查本机环境变量不是让你去搭什么通道。Error reading choices或返回体里choices字段缺失 —— 通常是请求体格式不对比如model字段名写错、messages不是数组。对照文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 检查 JSON 结构。如果你用的是 Claude Code 这类工具接入配置里三件套要写全Base URL 填https://taotoken.net/apiKey 填你的 KeyModel ID 填具体模型名缺一个都会报错。相关接入说明在 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。OAuth相关报错 —— 多见于工具类客户端首次授权流程确认回调地址和 Key 权限范围匹配别把只读 Key 用在需要写权限的接口上。排错通用思路先看报错第一行定位类型再看最后一行的具体位置中间堆栈是给你看调用链的。本地导出问题九成在路径、表名、文件占用接口问题九成在 Key、Base URL、请求体结构。把这两组变量固定住问题范围就缩小了。6. 长期编码与 Agent 场景把导出脚本接进工作流单次导出跑通之后很多人会想把它变成日常流程每天定时导出、按班级拆分、或者让 Agent 自动生成报表。这时候可以考虑 TaoToken 的 Coding Plan入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 适合长期写代码、需要稳定模型调用的场景。它能做什么把生成 SQL、补全字段映射、解释报错这些重复动作交给模型你保留最终审核。适合谁适合脚本维护频率高、字段经常变的人。具体怎么接把第 3 节的COLUMN_MAP和建表语句作为上下文让模型根据新表结构生成映射配置你复制进 JSON 即可。注意模型生成的 SQL 一定要自己过一遍尤其是 WHERE 条件和字段名别直接上生产库。本地 SQLite 文件建议先备份一份再跑批量脚本。再进一步可以把导出脚本包成命令行工具用argparse接收--db、--jxbid、--out参数配合系统定时任务每天生成报表。这样从“手动跑脚本”变成“自动出报表”中间省下的时间就是纯收益。最后给个实用技巧导出前先SELECT COUNT(*)数一遍导出后再用 openpyxl 读max_row - 1数一遍两个数对上才发出去。这个双计数习惯帮我拦下过好几次“查了但没写全”的低级错误。脚本里加两行打印比事后返工划算得多。
返回列表