lxml + django + uwsgi 无法生成正确格式的excel文件?

jia*_*mmy 5 python django excel lxml uwsgi

当我的项目lxml安装在我的环境中时使用 uwsgi 启动时,生成的 excel 文件无法打开,因为它可以使用django manage.py runserver和成功打开gunicorn

我的主要代码如下:


?? test_excel
           ??? urls.py
           ??? wsgi.py
           ??? settings.py

?? manage.py


Run Code Online (Sandbox Code Playgroud)

网址.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()),
]
Run Code Online (Sandbox Code Playgroud)

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()

Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

然后,如果我开始这个项目就像uwsgi --ini test_excel.inilxml安装和要求localhost:8876/test/,我会得到一个失败的Excel文件。但是当我卸载时lxml,结果是正确的。

我不明白为什么lxml用uwsgi影响django的excel响应

uwsgi在这种情况下,如何获得正确的 excel 文件响应?

谢谢。

蟒蛇版本: 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
Run Code Online (Sandbox Code Playgroud)
  • 更新了不同的条件细节
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

Run Code Online (Sandbox Code Playgroud)

Del*_*lan 1

我无法回答到底是什么导致了您遇到的错误,但如果您的问题是为什么 lxml 的存在会影响您的输出,那么这是因为 openpyxllxml在安装时使用,但在安装xml时使用标准库的包安装。

来自 openpyxl文档

支持流行的 lxml 库,如果安装了该库就会使用它。这在创建大文件时特别有用。

您可以在 openpyxl 源代码中看到,它在决定调用哪个函数之前检查是否lxml安装。