7个Python库,快速搞定公司内部工具
Excel 模板又改了,字段名还多了两个空格。
这种内部工具最烦的地方,不是功能多复杂,而是它永远卡在“差一点能用”。财务要导出,运营要筛数据,客服要查接口,领导要一个页面能点。你用纯 Python 写脚本,第二天他们又问能不能加个按钮。
这类东西我现在一般不硬造轮子,7 个库基本够用了。
第一个,pandas。
内部工具绕不开 Excel、CSV、订单明细、用户名单。pandas 不是拿来炫技的,是拿来少写一堆 for 循环的。
比如运营给一份用户表,让你筛出近 30 天没登录但还有余额的人:
import pandas as pddf = pd.read_excel("user_balance.xlsx")
df["last_login"] = pd.to_datetime(df["last_login"], errors="coerce")
cut_day = pd.Timestamp.today() - pd.Timedelta(days=30)
risk_users = df[
(df["balance"] > 0) &
(df["last_login"] < cut_day)
][["user_id", "mobile", "balance", "last_login"]]
risk_users.to_excel("待提醒用户.xlsx", index=False)
这段代码没什么花活,但真能省时间。 我一般会先把字段名清一下,不然 Excel 里一个隐藏空格能查半天。
df.columns = [c.strip().lower() for c in df.columns]
这种小动作,比写一堆异常处理实在。
第二个,openpyxl。
pandas 适合处理数据,openpyxl 适合处理“人要看的 Excel”。比如加颜色、冻结表头、调列宽。公司内部工具里,最后交出去的不是 DataFrame,是一个能让业务同事看懂的表。
from openpyxl import load_workbook
from openpyxl.styles import Font
from openpyxl.utils import get_column_letterwb = load_workbook("待提醒用户.xlsx")
ws = wb.active
for cell in ws[1]:
cell.font = Font(bold=True)
ws.freeze_panes = "A2"
for col in ws.columns:
width = max(len(str(c.value or"")) for c in col) + 2
ws.column_dimensions[get_column_letter(col[0].column)].width = min(width, 30)
wb.save("待提醒用户_可读版.xlsx")
别小看这个,表格好不好读,决定这个工具会不会被反复找你改。
第三个,requests。
内部系统基本都有接口。查库存、查订单、查用户状态,别一上来就搭平台,先用 requests 把链路跑通。
import requestsdefquery_order(order_no: str) -> dict:
resp = requests.get(
"http://order-service.internal/api/orders/detail",
params={"orderNo": order_no},
timeout=3
)
if resp.status_code != 200:
raise RuntimeError(f"订单接口异常: {resp.status_code}, {resp.text[:120]}")
data = resp.json()
if data.get("code") != 0:
raise RuntimeError(f"订单查询失败: {data.get('msg')}")
return data["data"]
这里我一定会加 timeout。 内部工具最怕挂死,业务同事点一下没反应,然后截图发群里问是不是系统崩了。
第四个,SQLAlchemy。
别在脚本里到处拼 SQL。临时工具可以糙,但不能糙到把库拖死。SQLAlchemy 至少能把连接管理、参数绑定这块兜住。
from sqlalchemy import create_engine, textengine = create_engine(
"mysql+pymysql://tool_user:***@10.2.3.8:3306/report",
pool_size=3,
max_overflow=0,
pool_pre_ping=True
)
defload_refund_orders(day: str):
sql = text("""
select order_no, user_id, refund_amount, status
from refund_order
where create_date = :day
and status in ('WAIT_AUDIT', 'RETRY')
limit 5000
""")
with engine.connect() as conn:
return conn.execute(sql, {"day": day}).mappings().all()
我一般会给内部工具单独建只读账号。 别拿业务服务的账号乱连,尤其是带 update 权限的那种,迟早出事。
第五个,Typer。
不是所有工具都需要页面。很多批处理、巡检、补偿脚本,用命令行反而更稳。Typer 写出来的命令行比较清爽,参数也不容易乱。
import typerapp = typer.Typer()
@app.command()
defcheck(day: str, output: str = "result.xlsx"):
orders = load_refund_orders(day)
typer.echo(f"发现待处理退款单: {len(orders)} 条")
df = pd.DataFrame(orders)
df.to_excel(output, index=False)
typer.echo(f"已导出: {output}")
if __name__ == "__main__":
app()
执行时就是:
python refund_tool.py check 2026-06-20 --output refund.xlsx
这种工具适合给研发、测试、运维用。参数明确,日志明确,比一堆散落的临时脚本强。
第六个,Rich。
命令行工具别全靠 print。跑批量任务的时候,进度、失败原因、耗时,最好一眼能看出来。Rich 就干这个。
from rich.console import Console
from rich.table import Tableconsole = Console()
defshow_failed(rows):
table = Table(title="处理失败记录")
table.add_column("订单号")
table.add_column("原因")
for row in rows[:20]:
table.add_row(row["order_no"], row["error"])
console.print(table)
有些失败不是代码问题,是脏数据。 把脏数据打印清楚,能少扯很多皮。
第七个,Streamlit。
业务同事要自己点、自己上传、自己下载,那就别再发 Python 脚本了。Streamlit 起一个轻量页面,够用。
import streamlit as st
import pandas as pdst.title("用户余额核对工具")
file = st.file_uploader("上传用户余额表", type=["xlsx"])
if file:
df = pd.read_excel(file)
df.columns = [c.strip() for c in df.columns]
bad = df[df["系统余额"] != df["导入余额"]]
st.write(f"异常记录:{len(bad)} 条")
st.dataframe(bad)
st.download_button(
"下载异常明细",
bad.to_csv(index=False).encode("utf-8-sig"),
file_name="余额异常明细.csv"
)
这种页面别做太重。 内部工具不是 SaaS 产品,先把上传、校验、下载跑通。权限、审计、菜单这些东西,真有使用频率了再补。
我现在判断一个 Python 内部工具值不值得做,基本看三点:是不是重复操作,是不是容易人工出错,是不是每次都要研发介入。
符合这三点,就别再手工处理了。
pandas 管数据,openpyxl 管 Excel 外观,requests 查接口,SQLAlchemy 连数据库,Typer 做命令行,Rich 管输出体验,Streamlit 给业务一个页面。
不复杂,但够快。内部工具很多时候拼的不是架构,是谁能在半天内把那个烦人的人工流程干掉。