0
点赞
收藏
分享

微信扫一扫

Django导出Excel,前端下载

罗子僧 2022-03-30 阅读 76

题记:实现这个功能也是遇到各自坑,各自查资料,从昨天到今天早上,也算是理通了,实现了交互与下载excel表小功能,这个下载功能也算是比较常用的,也感谢那些免费提供资料的网上的小伙伴们,我也把问题记录下来,大家有需要都可以查阅。

坑一:出现403(Forbidden)的错误。

在这里插入图片描述
在这里插入图片描述
问题解决:可以在django项目的setting.py下注释‘‘django.middleware.csrf.CsrfViewMiddleware’’。
在这里插入图片描述

坑二:用ajax请求不能异步下载文件,这是小点,一点进去了,就是无底洞。

django后台代码:

from django.http import HttpResponse
from django.shortcuts import render
import openpyxl
from io import BytesIO
#显示界面
def index(request):
    return render(request,'index.html')
#生成所需方法
base = [str(x) for x in range(10)] + [ chr(x) for x in range(ord('A'),ord('A')+6)]
# bin2dec
# 二进制 to 十进制: int(str,n=10)
def bin2dec(string_num):
    return str(int(string_num, 2))
# dec2bin
# 十进制 to 二进制: bin()
def dec2bin(string_num):
    num = int(string_num)
    mid = []
    while True:
        if num == 0: break
        num,rem = divmod(num, 2)
        mid.append(base[rem])
    return ''.join([str(x) for x in mid[::-1]])
# dec2hex
# 十进制 to 十六进制: hex()
def dec2hex(string_num):
    num = int(string_num)
    mid = []
    while True:
        if num == 0: break
        num,rem = divmod(num, 16)
        mid.append(base[rem])
    return ''.join([str(x) for x in mid[::-1]])
#二进制 to 十六进制
def bin2hex(string_num):
    return dec2hex(bin2dec(string_num))
# hex2dec
# 十六进制 to 十进制
def hex2dec(string_num):
    return str(int(string_num.upper(), 16))
# 十六进制 to 二进制: bin(int(str,16))
def hex2bin(string_num):
    return dec2bin(hex2dec(string_num.upper()))
#为字符串按照输入长度补'0'
def add_zero(str,gd_length):
    if (str.__len__() < gd_length):
        add_zero = '0'
        for i in range(gd_length - str.__len__() - 1):
            add_zero += '0'
        str = add_zero + str
    return str

def EPC(request):
    #获取数据
    CompanyPrefixLength = int(request.POST.get('CompanyPrefixLength', 0))
    FilterValue = request.POST.get('FilterValue', 0)
    UPC = request.POST.get('UPC', 0)
    SerialNumber = int(request.POST.get('SerialNumber', 0)) - 1
    StartSerialNumber = SerialNumber + 1
    AllNumber = int(request.POST.get('AllNumber', 0))
    #创建excel表
    wb = openpyxl.Workbook()
    wa = wb.active
    wa.column_dimensions['B'].width = 15
    wa.column_dimensions['C'].width = 20
    wa.column_dimensions['D'].width = 30
    wa.append(['ID', 'SerialNumber', 'BarCode', 'EPC'])
    ID = 0
    ExcelIndex = 1  # excel插入行数据索引
    #Header 二进制8bits
    Header_bits = '00110000'
    #filter过滤值3bits
    if FilterValue == '0':
        Filter_bits = '000'
    elif FilterValue == '1':
        Filter_bits = '001'
    elif FilterValue == '2':
        Filter_bits = '010'
    elif FilterValue == '3':
        Filter_bits = '011'
    elif FilterValue == '4':
        Filter_bits = '100'
    elif FilterValue == '5':
        Filter_bits = '101'
    elif FilterValue == '6':
        Filter_bits = '110'
    elif FilterValue == '7':
        Filter_bits = '111'
    else:
        print('error')
    # 根据GS1公司前缀长度进而判断
    if CompanyPrefixLength == 6:
        Cutoff_Point = 7
        GS1_Company_Prefix_bitslen = 20
        ID_IRN_bitslen = 24
        Partition_bits = '110'  # 6
    elif CompanyPrefixLength == 7:
        Cutoff_Point = 8
        GS1_Company_Prefix_bitslen = 24
        ID_IRN_bitslen = 20
        Partition_bits = '101'  # 5
    elif CompanyPrefixLength == 8:
        Cutoff_Point = 9
        GS1_Company_Prefix_bitslen = 27
        ID_IRN_bitslen = 17
        Partition_bits = '100'  # 4
    elif CompanyPrefixLength == 9:
        Cutoff_Point = 10
        GS1_Company_Prefix_bitslen = 30
        ID_IRN_bitslen = 14
        Partition_bits = '011'  # 3
    elif CompanyPrefixLength == 10:
        Cutoff_Point = 11
        GS1_Company_Prefix_bitslen = 34
        ID_IRN_bitslen = 10
        Partition_bits = '010'  # 2
    elif CompanyPrefixLength == 11:
        Cutoff_Point = 12
        GS1_Company_Prefix_bitslen = 37
        ID_IRN_bitslen = 7
        Partition_bits = '001'  # 1
    elif CompanyPrefixLength == 12:
        Cutoff_Point = 13
        GS1_Company_Prefix_bitslen = 40
        ID_IRN_bitslen = 4
        Partition_bits = '000'  # 0

    GTIN_BITS_PRO = Header_bits + Filter_bits + Partition_bits
    GS1_Company_Prefix = UPC[1:Cutoff_Point]
    ID_IRN = UPC[0] + UPC[Cutoff_Point:13]
    # GS1_Company_Prefix化为二进制,如果不够规定位数,前面加'0'
    GS1_Company_Prefix_bits = add_zero(dec2bin(GS1_Company_Prefix), GS1_Company_Prefix_bitslen)  # 24bits
    # ID_IRN 化为二进制,如果不够规定位数,前面加'0'
    ID_IRN_bits = add_zero(dec2bin(ID_IRN), ID_IRN_bitslen)
    GTIN_BITS = GTIN_BITS_PRO + GS1_Company_Prefix_bits + ID_IRN_bits
    for i in range(AllNumber):
        ID += 1
        ExcelIndex += 1
        SerialNumber += 1
        wa.cell(ExcelIndex, 1, str(ID))
        wa.cell(ExcelIndex, 2, str(SerialNumber))
        wa.cell(ExcelIndex, 3, str(UPC))
        wa.cell(ExcelIndex, 4, bin2hex(GTIN_BITS + add_zero(dec2bin(SerialNumber), 38)))
    output = BytesIO()
    wb.save(output)
    output.seek(0)
    response = HttpResponse(output.getvalue(), content_type='application/vnd.ms-excel')
    # ctime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    # file_name = 'export.xls' % ctime  # 给文件名中添加日期时间
    # file_name = urlquote(file_name)  # 使用urlquote()方法解决中文无法使用的问题
    response['Content-Disposition'] = 'attachment; filename=bug_info.xls'
    # response.write(output.getvalue())  # 在设置HttpResponse的类型时,如果给了值,可以不写这句
    return response

前端请求代码与返回结果:

 if(CheckData() == true){
            $.ajax({
                url:'http://192.168.0.68:8000/conversion/EPC/',
                data:{
                        CompanyPrefixLength:$(".CompanyPrefixLength").val(),
                        FilterValue:$(".FilterValue").val(),
                        UPC:$(".UPC").val(),
                        SerialNumber:$(".SerialNumber").val(),
                        AllNumber:$(".AllNumber").val()
                },
                type:'POST',
                dataType:'json',
                complete:function (data) {
                    console.log("complete");
                    console.log(data);
                }
            })

返回的数据应该都是存储在reponseTest,还有乱码,所以可以用XMLHttpRequest来请求。
在这里插入图片描述
前端用XMLHttpRequest请求代码:

let data = JSON.stringify({
                "CompanyPrefixLength":$(".CompanyPrefixLength").val(),
                "FilterValue":$(".FilterValue").val(),
                "UPC":$(".UPC").val(),
                "SerialNumber":$(".SerialNumber").val(),
                "AllNumber":$(".AllNumber").val()
            })
            const req = new XMLHttpRequest();
                req.open('POST','http://192.168.0.68:8000/conversion/EPC/', true);
                req.responseType = 'blob';
                req.setRequestHeader('Content-Type', 'application/json'); //设置请求头
                req.send(data); //输入参数
                req.onload = function() {
                     const data = req.response;
                     const a = document.createElement('a');
                     const blob = new Blob([data]);
                     const blobUrl = window.URL.createObjectURL(blob); //创建下载的链接
                     a.href = blobUrl;
                     a.download = 'EPC.xls'; //下载后文件名
                     // a.download = unescape(req.headers.filr)
                     a.click();
                     // self.download(blobUrl);
                };

后端接收代码:

import json
def EPC(request):
    data = json.loads(request.body)
    #获取数据
    CompanyPrefixLength = int(data['CompanyPrefixLength'])
    FilterValue = data['FilterValue']
    UPC = data['UPC']
    SerialNumber = int(data['SerialNumber']) - 1
    StartSerialNumber = SerialNumber + 1
    AllNumber = int(data['AllNumber'])

运行有EPC文件:
在这里插入图片描述
在这里插入图片描述

举报

相关推荐

0 条评论