Files
medical_training/apps/common/excel.py
T

59 lines
1.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""CMS 导入 / 导出通用工具(基于 openpyxl)。"""
import io
from django.http import HttpResponse
from openpyxl import Workbook, load_workbook
XLSX_CONTENT_TYPE = (
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
def xlsx_response(filename, headers, rows):
"""生成 .xlsx 下载响应。
Args:
filename: 下载文件名(含 .xlsx
headers: 表头列表
rows: 二维数据(list[list]);空则只导出表头(可作模板)
"""
wb = Workbook()
ws = wb.active
ws.append(list(headers))
for row in rows:
ws.append(list(row))
buf = io.BytesIO()
wb.save(buf)
buf.seek(0)
resp = HttpResponse(buf.getvalue(), content_type=XLSX_CONTENT_TYPE)
resp['Content-Disposition'] = f'attachment; filename="{filename}"'
return resp
def rows_from_xlsx(file):
"""解析上传的 .xlsx,首行为表头,返回 list[dict](表头→单元格字符串)。
空行跳过;单元格统一转为去空格字符串(None → '')。
"""
wb = load_workbook(file, read_only=True, data_only=True)
ws = wb.active
it = ws.iter_rows(values_only=True)
try:
header_cells = next(it)
except StopIteration:
return []
headers = [str(h).strip() if h is not None else '' for h in header_cells]
result = []
for raw in it:
if raw is None or all(c is None or str(c).strip() == '' for c in raw):
continue
row = {}
for i, h in enumerate(headers):
if not h:
continue
val = raw[i] if i < len(raw) else None
row[h] = '' if val is None else str(val).strip()
result.append(row)
return result