CKAN2.10下载按钮创建及Excel回传、资源上传问题
解决CKAN生成Excel并回传下载的问题
一、修复resource_create API调用错误
你碰到的NotImplementedError是因为files参数格式写错了——得用冒号的键值对格式,还要指定文件名和MIME类型。修正后的代码如下:
import requests response = requests.post( "http://localhost:5000/api/v3/action/resource_create", data={"package_id": "test1234", "name": "导出数据.xlsx"}, headers={"X-CKAN-API-Key": "xxxxxxxxxxxxxxxxx"}, # 注意files的正确结构:键为upload,值是包含文件名、文件对象、MIME类型的元组 files={"upload": ("导出数据.xlsx", open("the excel path", "rb"), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")} ) # 验证上传结果 if response.status_code == 200: resource_info = response.json()["result"] print(f"上传成功,下载链接:{resource_info['url']}") else: print(f"上传失败:{response.json()['error']}")
二、评估“上传资源供下载”的方案可行性
这个方案是可行的:
- 上传后的Excel会存在CKAN的filestore里,用户能通过资源的标准下载链接访问,适合需要长期留存的导出文件。
- 但如果是临时生成的一次性下载文件,这种方案会额外占用服务器存储,不如直接返回下载响应高效。
三、更高效的方案:直接返回Excel下载响应
如果不需要持久化文件,建议在插件的自定义视图里直接生成Excel并返回下载响应,步骤如下:
- 在
plugin.py中注册自定义路由和视图:
from flask import Blueprint, make_response import pandas as pd from io import BytesIO import ckan.plugins as plugins import ckan.plugins.toolkit as toolkit def get_excel_blueprint(): blueprint = Blueprint(name='excel_export', import_name=__name__) blueprint.add_url_rule('/export-excel', view_func=export_excel, methods=['GET']) return blueprint def export_excel(): # 1. 替换成你自己的Excel生成逻辑 sample_data = {"序号": [1,2,3], "内容": ["测试A","测试B","测试C"]} df = pd.DataFrame(sample_data) # 2. 将Excel写入内存流,避免存本地文件 output_stream = BytesIO() with pd.ExcelWriter(output_stream, engine='openpyxl') as writer: df.to_excel(writer, index=False, sheet_name='导出数据') output_stream.seek(0) # 3. 构建下载响应 response = make_response(output_stream.getvalue()) response.headers["Content-Disposition"] = "attachment; filename=导出数据.xlsx" response.headers["Content-type"] = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" return response class MyExcelExportPlugin(plugins.SingletonPlugin): plugins.implements(plugins.IConfigurer) def update_config(self, config): toolkit.add_blueprint(get_excel_blueprint())
- 在HTML页面中添加下载按钮,直接指向这个路由:
<a href="/export-excel" class="btn btn-primary">下载Excel</a>
这种方式不用上传文件到CKAN,生成后直接返回给用户,更适合临时导出场景。
内容的提问来源于stack exchange,提问作者xxestter
相关产品推荐
相关产品推荐

