Django设计批量导入Excel数据接口(包含图片)

news2024/12/23 22:24:30

Django设计批量导入Excel数据接口(包含图片)

目录

  • Django设计批量导入Excel数据接口(包含图片)
    • 示例xlsx文件
    • 接口详情
      • 前端上传FormData
      • 后端APIView
      • 调用函数

Django                        4.2.7
openpyxl                      3.1.5

示例xlsx文件

image-20240926094248909

接口详情

前端上传FormData

随便弄个上传按钮即可

image-20240926095002094

这里上传我用的是ElementUI自带的action()

<el-upload
    class="upload-Excel-demo"
    name="Excel_File"
    :action=$config.BASEURL+$config.ExcelUploadURL
    :with-credentials=true
    :on-success="handleSuccess"
    multiple
    :file-list="ExcelFileList">
  <el-button size="small">Excel批量导入</el-button>
</el-upload>

后端APIView

class UploadExcelApiView(APIView):
    def post(self, request, *args, **kwargs):
        # 上传Excel文件
        excel_file = request.FILES.get('Excel_File', None)
        print(excel_file)
        # 验证文件格式
        file_extension = os.path.splitext(excel_file.name)[1]
        assert file_extension.lower() in ['.xlsx', '.xls'], "不支持的文件格式,请上传 .xlsx 或 .xls 文件"
        # 定义一个允许的字段字典
        allowed_fields = {'男/女': '', '款号': '', '产品类型': '', '针型': '', '克重': '', '材质': '', '针法': '',
                          '织机时间': '', '描述': '', '工艺师': '', '生产日期': '', '产品图片': ''}

        # 读取Excel文件并将每个sheet表格放入列表中
        wb = openpyxl.load_workbook(excel_file)
        sheet_list = [wb[sheet] for sheet in wb.sheetnames]

        # 定义临时变量 存储数据对象
        garment_knowledge_objects = []
        garment_image_objects = []
        try:
            for sheet in sheet_list:
                # 验证表头是否正确
                first_row = next(sheet.iter_rows(values_only=True))
                print(f'first_row: {first_row}')
                allowed_fields = xlsx_first_row_validator(allowed_fields, first_row)
                print(f'allowed_fields: {allowed_fields}')

                # 提取图片
                for img in sheet._images:
                    # 图片转base64 以便上传到服务器
                    img_file = xlsx_img_to_base64(img)
                    img_row = img.anchor._from.row  # 图片所在行
                    img_col = img.anchor._from.col  # 图片所在列

                    # 格式化数据
                    formatted_data = extract_and_format_date(
                        sheet.cell(row=img_row + 1, column=(first_row.index(allowed_fields['生产日期'])) + 1).value)
                    formatted_gender = format_gender_handler(
                        sheet.cell(row=img_row + 1, column=(first_row.index(allowed_fields['男/女'])) + 1).value)

                    product_id = sheet.cell(row=img_row + 1, column=(first_row.index(allowed_fields['款号'])) + 1).value
                    print(
                        f'正在上传{product_id}')
                    # GarmentKnowledge就是自己创建的模型类
                    g_obj, created = GarmentKnowledge.objects.update_or_create(
                        product_id=product_id,
                        defaults={
                            'user': request.user,
                            'product_type': sheet.cell(row=img_row + 1,
                                                       column=(first_row.index(allowed_fields['产品类型'])) + 1).value,
                            'needle_type': sheet.cell(row=img_row + 1,
                                                      column=(first_row.index(allowed_fields['针型'])) + 1).value,
                            'knitting_time': sheet.cell(row=img_row + 1,
                                                        column=(first_row.index(allowed_fields['织机时间'])) + 1).value,
                            'gram_weight': sheet.cell(row=img_row + 1,
                                                      column=(first_row.index(allowed_fields['克重'])) + 1).value,
                            'composition': sheet.cell(row=img_row + 1,
                                                      column=(first_row.index(allowed_fields['材质'])) + 1).value,
                            'technologist': sheet.cell(row=img_row + 1,
                                                       column=(first_row.index(allowed_fields['工艺师'])) + 1).value,
                            'description': sheet.cell(row=img_row + 1,
                                                      column=(first_row.index(allowed_fields['描述'])) + 1).value,
                            'manufactured_at': formatted_data,
                            'pattern': sheet.cell(row=img_row + 1,
                                                  column=(first_row.index(allowed_fields['针法'])) + 1).value,
                            'gender_type': formatted_gender,
                        }
                    )
                    img_obj = GarmentImagesFile(garment_knowledge=g_obj, image=img_file)
                    garment_knowledge_objects.append(g_obj)
                    garment_image_objects.append(img_obj)

            # 批量创建对象
            GarmentKnowledge.objects.bulk_create(garment_knowledge_objects)
            GarmentImagesFile.objects.bulk_create(garment_image_objects)
            print('上传成功')
        except Exception as e:
            print(f'错误信息:{e}')
            return APIResponse(code_msg='error', detail=e, data=None, status=status.HTTP_400_BAD_REQUEST)

        return APIResponse(code_msg='success', detail='上传成功', data=None, status=status.HTTP_200_OK)

调用函数

import io
import re

from django.core.files.uploadedfile import InMemoryUploadedFile

def format_gender_handler(gender_str):
    if gender_str.lower() == '男':
        return '男装'
    elif gender_str.lower() == '女':
        return '女装'
    else:
        return None

def extract_and_format_date(date_str):
    date_str = str(date_str)
    # 使用正则表达式提取字符串中的第一个四位数年份、月份和日期
    match = re.search(r'(\d{4}).*?(\d{1,2}).*?(\d{1,2})', date_str)
    if match:
        year = match.group(1)  # 提取年份
        month = match.group(2).zfill(2)  # 提取月份,补全两位数
        day = match.group(3).zfill(2)  # 提取日期,补全两位数
        return f"{year}-{month}-{day}"
    else:
        raise ValueError("无法从输入中提取日期")


def xlsx_img_to_base64(img_obj):
    """
    img_obj必须是一个xlsx文件中的图片对象
    例:sheet._images
    """
    img_bytes = io.BytesIO(img_obj._data())
    img_bytes.seek(0)
    img_file = InMemoryUploadedFile(
        file=img_bytes,  # 图像字节流
        field_name=None,  # 字段名,保持为 None
        name='image.png',  # 使用图像对象的名字或默认名
        content_type='image/png',  # 根据实际图像格式设置内容类型
        size=img_bytes.getbuffer().nbytes,  # 获取图像字节大小
        charset=None  # 字符编码,通常不需要
    )
    return img_file


def xlsx_first_row_validator(allowed_fields, first_row):
    """
    first_row必须是一个由表头字段组成的可遍历对象
    例:('款号', '产品类型', '针型', '克重(克)', '材质', '针法')
    返回值allowed_fields将会更新为由规定字段和接收字段组成的字典
    例:{'款号': '款号', '产品类型': '产品类型', '针型': '针型', '克重': '克重'}

    """
    for first_cell in first_row:
        for key, value in allowed_fields.items():
            if key in first_cell or first_cell in key:
                allowed_fields[key] = first_cell
    return allowed_fields
        for key, value in allowed_fields.items():
            if key in first_cell or first_cell in key:
                allowed_fields[key] = first_cell
    return allowed_fields

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2168803.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2-104 基于MATLAB的动态模式分解(Dynamic Mode Decomposition,DMD)

基于MATLAB的动态模式分解&#xff08;Dynamic Mode Decomposition&#xff0c;DMD&#xff09;,从人类步行数据中提取信息.动态模式分解是一种降维算法&#xff0c;在流体力学领域引入的。与提供内部坐标系和相应投影的SVD相似&#xff0c;DMD为您提供随不同时间行为演变的特定…

【架构】前台、中台、后台

文章目录 前台、中台、后台1. 前台&#xff08;Frontend&#xff09;特点&#xff1a;技术栈&#xff1a; 2. 中台&#xff08;Middleware&#xff09;特点&#xff1a;技术栈&#xff1a; 3. 后台&#xff08;Backend&#xff09;特点&#xff1a;技术栈&#xff1a; 示例场景…

PMOS的原理

PMOS&#xff08;金属氧化物半导体场效应晶体管&#xff09;是一种以空穴为主要载流子的场效应管&#xff0c;它的D极&#xff08;漏极&#xff09;、S极&#xff08;源极&#xff09;和G极&#xff08;栅极&#xff09;的工作原理如下&#xff1a; 1. D极&#xff08;漏极&am…

已存在的Python项目使用依赖管理工具UV

1. 文档 uv文档 2. 如何转换 初始化 uv initrequirements.txt转换成pyproject.toml uv add $(cat requirements.txt)删除requirements.txt 如果更新pyproject.toml之后&#xff0c;使用命令 uv sync替换项目环境 如果有库没有加入依赖&#xff0c;自己手动加一下&am…

详解电力物联网通常使用哪些通信规约?

在电力物联网行业中&#xff0c;通信规约是关键的技术之一&#xff0c;用于实现电网设备与控制中心之间的数据通信和信息管理。本篇就为大家简单说明电力物联网通常使用哪些通信规约。 1、IEC 60870-5-101/104 这是由国际电工委员会&#xff08;IEC&#xff09;制定的一系列标…

微信小程序配置prettier+eslint

虽然微信开发者工具是基于vscode魔改的.但是由于版本过低,导致很多插件也用不上新版本.所以在微信开发者工具限制的版本下使用的prettier,eslint也是有版本要求. 本文主要就是记录一下需要的版本号 1.微信开发者工具安装插件 2.package.json中添加以下依赖及安装依赖 "de…

【HarmonyOS】组件长截屏方案

【HarmonyOS】普通组件与web组件长截屏方案&#xff1a;原则是利用Scroll内的组件可以使用componentSnapshot完整的截屏 【普通组件长截屏】 import { componentSnapshot, promptAction } from kit.ArkUI import { common } from kit.AbilityKit import { photoAccessHelper }…

增量式编码器实现原理

目录 概述 1 认识增量式编码器 1.1 概述 1.2 增量式编码器的特性 1.3 编码器的硬件 2 增量式编码器实现原理 2.1 编码器信号 2.2 正反转判断 概述 本文主要介绍增量式编码器实现原理&#xff0c;包括增量式编码器的特性&#xff0c;信号特性&#xff0c;以及如何使用编…

【稳定且高效的分治排序 —— 归并排序算法】

【稳定且高效的分治排序 —— 归并排序算法】 归并排序&#xff08;Merge sort&#xff09;是建立在归并操作上的一种有效、稳定的排序算法&#xff0c;采用分治法的典型应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff0c;即先使每个子序列有序&#xff0…

深度探索与实战编码:利用Python与AWS签名机制高效接入亚马逊Product Advertising API获取商品详情

亚马逊商品详情接口技术贴及代码示例 在电商数据分析和产品管理中&#xff0c;获取商品的详细信息是至关重要的一环。亚马逊作为全球领先的电商平台&#xff0c;提供了丰富的商品数据和强大的API接口&#xff0c;使得开发者能够轻松获取商品的详细信息。本文将详细介绍如何使用…

NASA:ATLAS/ICESat-2 L3 A沿线内陆地表水数据V006数据集

目录 简介 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3A Along Track Inland Surface Water Data V006 简介 ATLAS/ICESat-2 L3 A沿线内陆地表水数据V006 ATLAS/ICESat-2 L3 A沿线内陆地表水数据V006是指由ATLAS/ICESat-2卫星获取的针对陆地…

矿石运输船数据集、散货船数据集、普通货船数据集、集装箱船数据集、渔船数据集以及客船数据集

海船&#xff1a;用于船只检测的大规模精准标注数据集 我们很高兴地介绍一个新的大规模数据集——海船&#xff0c;该数据集专为训练和评估船只目标检测算法而设计。目前&#xff0c;这个数据集包含31,455张图像&#xff0c;并涵盖了六种常见的船只类型&#xff0c;包括矿石运…

en造数据结构与算法C# 二叉排序树 泛型类的基本构成

前置知识&#xff1a;二叉树 en造数据结构与算法C# 二叉树的顺序存储和前中后序遍历-CSDN博客 二叉排序树基本规则 二叉排序树的特点就是有序&#xff0c;其基本规则分为两个点 1.按照顺序去存储节点(下图绿色的顺序) 2.其次&#xff0c;在第一点的基础上&#xff0c;比…

python之装饰器、迭代器、生成器

装饰器 什么是装饰器&#xff1f; 用来装饰其他函数&#xff0c;即为其他函数添加特定功能的函数。 装饰器的两个基本原则&#xff1a; 装饰器不能修改被装饰函数的源码 装饰器不能修改被装饰函数的调用方式 什么是可迭代对象&#xff1f; 在python的任意对象中&#xff…

Centos 7.9 Kubeadm安装k8s1.20.11

一、环境 主机用途192.168.76.140k8s-master1192.168.76.141k8s-node1 二、设置yum源 由于系统已经关闭&#xff0c;可以用centos9尝试 cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak vi /etc/yum.repos.d/CentOS-Base.repo# 使用阿里云的y…

ARM基础架构-文档导读系列

第一章 简介 Introducing the Arm architecture 第二章 指令集 Armv8-A Instruction Set ArchitectureLearn the architecture -A64 Instruction Set Architecture 第三章 指令集 ARM异常模型GICv3 v4 overviewGeneric Interrupt Controller v3 and v4, VirtualizationArm…

皮肤病检测-目标检测数据集(包括VOC格式、YOLO格式)

皮肤病检测-目标检测数据集&#xff08;包括VOC格式、YOLO格式 数据集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1XNTo-HsBCHJp2UA-dpn5Og?pwdlizo 提取码&#xff1a;lizo 数据集信息介绍&#xff1a; 共有 2025 张图像和一一对应的标注文件 标注文件格式提供…

工作安排 - 华为OD统一考试(E卷)

2024华为OD机试(C卷+D卷)最新题库【超值优惠】Java/Python/C++合集 题目描述 小明每周上班都会拿到自己的工作清单,工作清单内包含n项工作,每项工作都有对应的耗时时长(单位h)和报酬,工作的总报酬为所有已完成工作的报酬之和。那么请你帮小明安排一下工作,保证小明在指定…

说说海外云手机的自动化功能

在全球社交媒体营销中&#xff0c;通过自动化功能&#xff0c;企业不再需要耗费大量时间和精力手动监控和操作每台设备。这意味着&#xff0c;企业可以显著提升效率、节省成本&#xff0c;同时减少对人力资源的依赖。那么&#xff0c;海外云手机的自动化功能具体能带来哪些优势…

Linux云计算 |【第四阶段】NOSQL-DAY3

主要内容&#xff1a; redis主从复制、哨兵服务&#xff08;高可用&#xff09;、数据持久化&#xff08;RDB、AOF&#xff09; 一、Redis主从复制概述 Redis 主从复制是一种数据复制机制&#xff0c;用于在多个 Redis 实例之间同步数据&#xff0c;以提高系统的可用性、可靠…