当前位置:网站首页>使用 zipfile、openpyxl、flask 批量导出excel zip
使用 zipfile、openpyxl、flask 批量导出excel zip
2022-06-22 14:36:00 【mtl1994】
使用 zipfile、openpyxl、flask 批量导出excel zip
文章目录
前言
一、python 使用 openpyxl 操作 excel https://blog.csdn.net/mtl1994/article/details/123349397
一、环境
- python3.10 (https://docs.python.org/3/library/zipfile.html)
二、使用
1.压缩本地文件
with ZipFile('spam.zip', 'w') as myzip:
myzip.write('1.xls')
myzip.write('app.py')
2.压缩流文件到zip
xls_byte = io.BytesIO()
xls_tmp = load_workbook('1.xlsx')
xls_tmp.save(xls_byte)
with ZipFile('spam.zip', 'w') as myzip:
myzip.writestr('1.xlsx', xls_byte.getvalue())
xls_byte.seek(0)
3.压缩目录下 pyc
project = PyZipFile("project.zip", mode='w')
project.writepy("d:/datasets-work")
4.openpyxl 生成多个excel, excel zipfile 压缩 flask接口 导出
@admin.route("/export_all_tmplate", methods=["GET"])
def export_all_tmplate():
all_zip = BytesIO()
zf = ZipFile(all_zip, 'w')
for i in range(10):
output = BytesIO()
wb_tmp = load_workbook(f'tmp-{i}.xlsx')
wb_tmp.save(output)
"""
操作excel...
"""
zf.writestr(f"tmp-{i}.xlsx", output.getvalue())
output.seek(0)
zf.close()
all_zip.seek(0)
resp = make_response(all_zip.getvalue())
basename = 'all.zip'
# 转码,支持中文名称
resp.headers["Content-Disposition"] = "attachment; filename*=UTF-8''{utf_filename}".format(
utf_filename=basename)
resp.headers['Content-Type'] = 'application/zip'
return resp
5.实例
@admin.route("/equipment_standing_book/basic/export_all_tmplate", methods=["GET"])
# @need_login
# @cache.cached(timeout=600, key_prefix=make_cache_key)
def equipment_standing_book_export_all_tmplate():
"""
#group 导出接口
#name 导出接口
#desc 导出excel
#param tmp_name #模板名称
#priv need_login
#return data <dict> 各个字段的注释
#example
{
"code": 0,
"msg": "成功",
"data":{}
}
"""
tmp_name = str(g.request_data.get("tmp_name", "")).strip()
time = str(g.request_data.get("time", "")).strip()
filename = time
tmplate = equip_standing_config.query({'tmp_name': tmp_name})[0]
format = "%Y"
if tmplate['type'] == '3':
format = "%Y-%m"
all_zip = BytesIO()
zf = ZipFile(all_zip, 'w')
record_list = equip_standing_record.query(where=f" and config_id='{tmplate['id']}' and date_format(create_time, '{format}') = '{time}'")
last_record_time = ""
for ri, record in enumerate(record_list):
output = BytesIO()
#如果相同日期合并到一个excel,多sheet
if last_record_time != "" and last_record_time == record["create_time"].strftime('%Y-%m-%d'):
ws = wb_tmp["next"]
ws.title = record['code'].replace(":", "")
target = wb_tmp.copy_worksheet(wb_tmp.active)
target.title = "next"
else:
wb_tmp = load_workbook(f'./src/statics/{tmp_name}.xlsx')
ws = wb_tmp[wb_tmp.sheetnames[0]]
ws.title = record['code'].replace(":", "")
target = wb_tmp.copy_worksheet(wb_tmp.active)
target.title = "next"
detail_list = eval(tmp_name).query({'record_id': record['id']})
obj: {} = eval(tmp_name).get_dict()
start, start_row, points = 0, [], {}
#找到从哪一行赋值 excel中 配置和实体类对应的字段
for i, row in enumerate(ws.values):
print(type(row))
start_row = row
for j, value in enumerate(row):
print(i,j,value)
if value in obj.keys():
points[j] = value
start = i
if value == 'serial_number':
points[j] = 'serial_number'
start = i
if start > 0:
break
ws.delete_rows(start + 1)
ws.insert_rows(start + 1, len(detail_list))
#赋值
for i, obj in enumerate(detail_list):
for point in points.keys():
cell = ws.cell(row=start + 1, column=point + 1)
cell.value = i if points[point] == 'serial_number' else obj[points[point]]
cell.border = Border(top=Side(border_style='thin', color='000000'),
bottom=Side(border_style='thin', color='000000'),
left=Side(border_style='thin', color='000000'),
right=Side(border_style='thin', color='000000'))
start += 1
#如果当前行和上一行相同,合并
for i in range(start + 1, ws.max_row + 1):
ws.merge_cells(start_row=i, start_column=1, end_row=i, end_column=ws.max_column)
if (ri + 1 < len(record_list) and record_list[ri + 1]["create_time"].strftime('%Y-%m-%d') != record_list[ri]["create_time"].strftime('%Y-%m-%d'))\
or (last_record_time != "" and last_record_time != record["create_time"].strftime('%Y-%m-%d')):
wb_tmp.remove(wb_tmp["next"])
wb_tmp.save(output)
zf.writestr(record['create_time'].strftime('%Y-%m-%d') + ".xlsx", output.getvalue())
output.seek(0)
last_record_time = record["create_time"].strftime('%Y-%m-%d')
zf.close()
all_zip.seek(0)
resp = make_response(all_zip.getvalue())
basename = f'{filename}.zip'
# 转码,支持中文名称
resp.headers["Content-Disposition"] = "attachment; filename*=UTF-8''{utf_filename}".format(
utf_filename=basename)
resp.headers['Content-Type'] = 'application/zip'
return resp
总结
~~~
边栏推荐
- Meet webassembly again
- Using virtual serial port to debug serial port in keil MDK
- 类似attention nlp
- 基于最小化三维NDT距离的快速精确点云配准
- Be an we media video blogger, and share the necessary 32 material websites
- ROS2前置基础教程 | 使用CMakeLists.txt编译ROS2节点
- C语言学习-17-函数作为参数传入函数
- Quickly play ci/cd graphical choreography
- vector的模拟实现
- 推进兼容适配,使能协同发展 GBase 5月适配速递
猜你喜欢

Jenkins 通过检查代码提交自动触发编译

(pytorch advanced path 2) word embedding and position embedding

After 100 days, Xiaoyu built a robot communication community!! Now invite moderators!

C language learning -18-makefile file writing examples and how to generate and call dynamic libraries

Promouvoir l'adaptation compatible et permettre le développement collaboratif du Service Express adaptatif gbase en mai

C # implements insertion sorting

推进兼容适配,使能协同发展 GBase 5月适配速递

ML笔记-matrix fundamental, Gradient Descent

Common operations in Visual Studio development

Hongshi electric appliance rushes to the Growth Enterprise Market: the annual revenue is 600million yuan. Liujinxian's equity was frozen by Guangde small loan
随机推荐
推进兼容适配,使能协同发展 GBase 5月适配速递
C language learning -17- function is passed in as a parameter
大佬们 2.2.1cdc 监控sqlsever 只能拿到全量的数据 后期增量的数据拿不到 咋回事啊
Scala语言学习-06-传名参数、传值参数、传函数参数的区别
快速排序quick_sort
FPGA collects DHT11 temperature and humidity
微信小程序头像挂件制作
C language learning -18-makefile file writing examples and how to generate and call dynamic libraries
High precision calculation
基于最小化三维NDT距离的快速精确点云配准
标准化、最值归一化、均值归一化应用场景的进阶思考
Be an we media video blogger, and share the necessary 32 material websites
Yilian technology rushes to Shenzhen Stock Exchange: annual revenue of RMB 1.4 billion, 65% of which comes from Ningde times
向量1(类和对象)
Discourse 的信任级别
阿里云中间件的开源往事
Ask if you want to get the start of sqlserver_ Is there a good way for LSN?
"Software defines the world, open source builds the future" 2022 open atom global open source summit will open at the end of July
各位学弟学妹,别再看教材了,时间复杂度看这篇就好了
ROS2前置基础教程 | 小鱼教你用CMake依赖查找流程