lxml + django + uwsgi 无法生成格式正确的 excel 文件?
lxml + django + uwsgi failed to generate a right format excel file?
在我的环境中安装 lxml
时,当我的项目使用 uwsgi 启动时生成的 excel 文件无法打开,因为它可以使用 django manage.py runserver
和 gunicorn
成功打开
我的主要代码如下:
── test_excel
├── urls.py
├── wsgi.py
└── settings.py
── manage.py
urls.py
from django.contrib import admin
from django.urls import path
from django.views import View
from openpyxl.writer.excel import save_virtual_workbook
import pandas as pd
from django.http import HttpResponse, StreamingHttpResponse
import xlrd
import openpyxl
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment
from openpyxl.writer.excel import save_virtual_workbook
from openpyxl.cell.cell import ILLEGAL_CHARACTERS_RE
class TestExcelView(View):
def get(self, request):
# indexs = {0: ['cost', '2020-01', 'testing'],
# 1: ['cost', '2020-01', '360 Limited'],
# 2: ['cost', '2020-02', 'Korea Co.,LTD'],
# 3: ['cost', '2020-02', 'ADS4EACH HK TECH LIMITED']}
# columns = [['1'], ['amy'], ['tom'], ['zara'], ['jay'], ['Lee'], ['Uzi'], ['Zome'], ['Qoe'], ['Aoi'], ['Yeezy'],
# ['Hazy'], ['Wash'], ['pany'], ['zoey'], ['Moe'], ['total']]
# datas = {
# 0: [0.0, 0.0, 0.0, 0.0, 0.0, 7.85, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.85],
# 1: [0.0, 0.0, 0.0, 0.0, 0.0, 7.85, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.85],
# 2: [0.0, 0.0, 0.0, 0.0, 0.0, 7.85, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.85],
# 3: [0.0, 0.0, 0.0, 0.0, 0.0, 7.85, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.85]
# }
#
# index = pd.MultiIndex.from_tuples(indexs.values())
# column = pd.MultiIndex.from_tuples(columns)
# data = datas.values()
#
# df = pd.DataFrame(data, index=index, columns=column)
#
# # 1 saved as excel
#
# excel_writer = pd.ExcelWriter(path='download.xlsx', engine='openpyxl')
# df.to_excel(excel_writer)
# wb = excel_writer.book
#
# response = HttpResponse(save_virtual_workbook(wb))
# response["Content-Type"] = 'application/vnd.ms-excel'
# response['Content-Disposition'] = 'attachment; filename={}.xlsx'.format("for_test")
# return response
wb = Workbook()
ws = wb.active
ws.merge_cells('A1:B1')
a1 = ws["A1"]
ws["A1"] = "reason"
ws.column_dimensions["A"].width = 100
ali = Alignment(horizontal='center', vertical='center')
a1.alignment = ali
ws["A2"] = "request_id"
ws.column_dimensions["A"].width = 50
ws["B2"] = "rebate_reason"
ws.column_dimensions["B"].width = 50
for item in ws["A2:B2"][0]:
item.font = Font(color='FF0000')
item.alignment = ali
response = HttpResponse(save_virtual_workbook(wb))
response["Content-Type"] = 'application/vnd.ms-excel'
response['Content-Disposition'] = 'attachment; filename={}.xlsx'.format("test_excel")
return response
urlpatterns = [
path('admin/', admin.site.urls),
path('test/', TestExcelView.as_view()),
]
wsgi.py
import os
from django.core.wsgi import get_wsgi_application
#os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test_excel.settings')
application = get_wsgi_application()
test_excel.ini
[uwsgi]
pythonpath=/home/bluev/work/bv_crm_bak/test_excel
pythonpath=/home/bluev/work/bv_crm_bak/test_excel
env=DJANGO_SETTINGS_MODULE=test_excel.settings
module=test_excel.wsgi
master=True
pidfile=logs/test_excel.pid
vacuum=True
max-requests=100000
enable-threads=true
processes = 4
threads=8
listen=64
daemonize=logs/test_excel.log
log-slow=3000
python-autoreload=1
http=0.0.0.0:8876
然后,如果我在安装 lxml
时启动像 uwsgi --ini test_excel.ini
这样的项目,并请求 localhost:8876/test/
,我将得到一个失败的 excel 文件。但是当我卸载 lxml
结果是正确的。
不明白为什么lxml
会影响django对uwsgi的excel响应
在这种情况下,如何使用 uwsgi
获得正确的 excel 文件响应?
谢谢。
python版本:Python 3.6.8
包列表:
asgiref==3.2.7
Django==3.0.6
et-xmlfile==1.0.1
jdcal==1.4.1
lxml==4.5.1
mysqlclient==1.4.6
numpy==1.18.4
openpyxl==3.0.3
pandas==1.0.3
python-dateutil==2.8.1
pytz==2020.1
six==1.14.0
sqlparse==0.3.1
uWSGI==2.0.18
xlrd==1.2.0
- 更新了不同条件的详细信息
environ condition excel_file(if excel file can be opened)
gunicorn + lxml + django yes
gunicorn + django yes
django runserver + lxml yes
django runserver yes
uwsgi + lxml + django no
uwsgi + django yes
我无法回答究竟是什么导致了你的错误,但如果你的问题是为什么 lxml 的存在会影响你的输出,那是因为 openpyxl 在安装时使用 lxml
, 但标准库的 xml
包未安装时。
来自openpyxl docs:
There is support for the popular lxml library which will be used if it is installed. This is particular useful when creating large files.
Here 是您可以在 openpyxl 源代码中看到的地方,它会在决定调用哪个函数之前检查是否安装了 lxml
。
在我的环境中安装 lxml
时,当我的项目使用 uwsgi 启动时生成的 excel 文件无法打开,因为它可以使用 django manage.py runserver
和 gunicorn
成功打开
我的主要代码如下:
── test_excel
├── urls.py
├── wsgi.py
└── settings.py
── manage.py
urls.py
from django.contrib import admin
from django.urls import path
from django.views import View
from openpyxl.writer.excel import save_virtual_workbook
import pandas as pd
from django.http import HttpResponse, StreamingHttpResponse
import xlrd
import openpyxl
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment
from openpyxl.writer.excel import save_virtual_workbook
from openpyxl.cell.cell import ILLEGAL_CHARACTERS_RE
class TestExcelView(View):
def get(self, request):
# indexs = {0: ['cost', '2020-01', 'testing'],
# 1: ['cost', '2020-01', '360 Limited'],
# 2: ['cost', '2020-02', 'Korea Co.,LTD'],
# 3: ['cost', '2020-02', 'ADS4EACH HK TECH LIMITED']}
# columns = [['1'], ['amy'], ['tom'], ['zara'], ['jay'], ['Lee'], ['Uzi'], ['Zome'], ['Qoe'], ['Aoi'], ['Yeezy'],
# ['Hazy'], ['Wash'], ['pany'], ['zoey'], ['Moe'], ['total']]
# datas = {
# 0: [0.0, 0.0, 0.0, 0.0, 0.0, 7.85, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.85],
# 1: [0.0, 0.0, 0.0, 0.0, 0.0, 7.85, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.85],
# 2: [0.0, 0.0, 0.0, 0.0, 0.0, 7.85, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.85],
# 3: [0.0, 0.0, 0.0, 0.0, 0.0, 7.85, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.85]
# }
#
# index = pd.MultiIndex.from_tuples(indexs.values())
# column = pd.MultiIndex.from_tuples(columns)
# data = datas.values()
#
# df = pd.DataFrame(data, index=index, columns=column)
#
# # 1 saved as excel
#
# excel_writer = pd.ExcelWriter(path='download.xlsx', engine='openpyxl')
# df.to_excel(excel_writer)
# wb = excel_writer.book
#
# response = HttpResponse(save_virtual_workbook(wb))
# response["Content-Type"] = 'application/vnd.ms-excel'
# response['Content-Disposition'] = 'attachment; filename={}.xlsx'.format("for_test")
# return response
wb = Workbook()
ws = wb.active
ws.merge_cells('A1:B1')
a1 = ws["A1"]
ws["A1"] = "reason"
ws.column_dimensions["A"].width = 100
ali = Alignment(horizontal='center', vertical='center')
a1.alignment = ali
ws["A2"] = "request_id"
ws.column_dimensions["A"].width = 50
ws["B2"] = "rebate_reason"
ws.column_dimensions["B"].width = 50
for item in ws["A2:B2"][0]:
item.font = Font(color='FF0000')
item.alignment = ali
response = HttpResponse(save_virtual_workbook(wb))
response["Content-Type"] = 'application/vnd.ms-excel'
response['Content-Disposition'] = 'attachment; filename={}.xlsx'.format("test_excel")
return response
urlpatterns = [
path('admin/', admin.site.urls),
path('test/', TestExcelView.as_view()),
]
wsgi.py
import os
from django.core.wsgi import get_wsgi_application
#os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test_excel.settings')
application = get_wsgi_application()
test_excel.ini
[uwsgi]
pythonpath=/home/bluev/work/bv_crm_bak/test_excel
pythonpath=/home/bluev/work/bv_crm_bak/test_excel
env=DJANGO_SETTINGS_MODULE=test_excel.settings
module=test_excel.wsgi
master=True
pidfile=logs/test_excel.pid
vacuum=True
max-requests=100000
enable-threads=true
processes = 4
threads=8
listen=64
daemonize=logs/test_excel.log
log-slow=3000
python-autoreload=1
http=0.0.0.0:8876
然后,如果我在安装 lxml
时启动像 uwsgi --ini test_excel.ini
这样的项目,并请求 localhost:8876/test/
,我将得到一个失败的 excel 文件。但是当我卸载 lxml
结果是正确的。
不明白为什么lxml
会影响django对uwsgi的excel响应
在这种情况下,如何使用 uwsgi
获得正确的 excel 文件响应?
谢谢。
python版本:Python 3.6.8
包列表:
asgiref==3.2.7
Django==3.0.6
et-xmlfile==1.0.1
jdcal==1.4.1
lxml==4.5.1
mysqlclient==1.4.6
numpy==1.18.4
openpyxl==3.0.3
pandas==1.0.3
python-dateutil==2.8.1
pytz==2020.1
six==1.14.0
sqlparse==0.3.1
uWSGI==2.0.18
xlrd==1.2.0
- 更新了不同条件的详细信息
environ condition excel_file(if excel file can be opened)
gunicorn + lxml + django yes
gunicorn + django yes
django runserver + lxml yes
django runserver yes
uwsgi + lxml + django no
uwsgi + django yes
我无法回答究竟是什么导致了你的错误,但如果你的问题是为什么 lxml 的存在会影响你的输出,那是因为 openpyxl 在安装时使用 lxml
, 但标准库的 xml
包未安装时。
来自openpyxl docs:
There is support for the popular lxml library which will be used if it is installed. This is particular useful when creating large files.
Here 是您可以在 openpyxl 源代码中看到的地方,它会在决定调用哪个函数之前检查是否安装了 lxml
。