AttributeError:“列表”对象没有属性“ iter_rows”

时间:2019-06-24 05:04:09

标签: python django

我已经阅读了一个excel文件,在那里我得到了所有工作表,但是这样做时 得到那个错误。

views.py

from Django.shortcuts import render
import openpyxl


def index(request):
    if "GET" == request.method:
        return render(request, 'file/index.html', {})
    else:
        excel_file = request.FILES["excel_file"]

        # you may put validations here to check extension or file size

        wb = openpyxl.load_workbook(excel_file)

        # getting all sheets
        worksheet = wb.sheetnames
        print(worksheet)

        excel_data = list()
        # iterating over the rows and
        # getting value from each cell in row
        for row in worksheet.iter_rows():
            row_data = list()
            for cell in row:
                row_data.append(str(cell.value))
            excel_data.append(row_data)

        return render(request, 'file/index.html', {"excel_data": excel_data})

2 个答案:

答案 0 :(得分:1)

根据文档,wb.sheetnames返回的工作表名称是列表,您需要先选择一个工作表,然后才能使用iter_rows。例如:

如果要使用第一张纸:

sheet_name = wb.sheetnames[0]
worksheet = wb[sheet_name]
for row in worksheet.iter_rows():
   ...

或者如果您想浏览所有工作表:

for sheet_name in wb.sheetnames:
    worksheet = wb[sheet_name]
    for row in worksheet.iter_rows():
        # rest of the code

保存到数据库

要保存,可以使用模型。假设您有一个名为WBData的模型,该模型具有与列匹配的字段,然后可以像这样保存它:

for row in worksheet.iter_rows():
    row_data = list()
    for cell in row:
        row_data.append(str(cell.value))
    WBData.objects.create(field1=row_data[0], field2=row_data[1],...)

答案 1 :(得分:1)

worksheet = wb.sheetnames实际上将工作表名称作为 list 返回。

如何获取工作表:

if 'sheet name' in wb.sheetnames:
    sheet = wb['sheet name']

您可以执行以下操作:

for name in wb.sheetnames:
    sheet = wb[name]
    for row in sheet.iter_rows():
        # Your code

更新(保存到数据库中): 如果图纸与模型相对应,并且您要将数据保存到数据库中,请参见以下部分:

sheet_to_model = {
    'sheet1':{
        'model': Model1, 
        'column_map': {
            'xl column 1': 'model_field_1',
            'xl column 2': 'model_field_2',
        }
    }

}

# Also map each sheet's column name to your model's field name

for name in wb.sheetnames:
    sheet = wb[name]
    for row in sheet.iter_rows():
        # Here get model name using sheet name and the sheet_to_model dict. 
        # Get each cell value from row and column name and create a dict using  
        # the model's field name and the cell value. Then inset using Model.objects.create(**data)

更新2(保存到数据库): 假设您的xl文件具有以下工作表和相应的列:

  • Sheet1(列:'s1c1','s1c2','s1c3')
  • Sheet1(列:'s1c1','s1c2','s1c3')

您拥有模型Model1Model2Sheet1的数据将被保存到Model中,而Sheet2的数据将被保存到Model2中。现在,请看下面的代码以了解数据如何存储在相应的模型中:

import openpyxl
from django import models


class Model1(models.Model):
    m1f1 = models.IntergerField()
    m1f2 = models.IntergerField()
    m1f3 = models.IntergerField()


class Model2(models.Model):
    m2f1 = models.CharField(max_length=128)
    m2f2 = models.CharField(max_length=128)
    m2f3 = models.CharField(max_length=128)


sheet_to_model = {
    'Sheet1':{
        'model': Model1, 
        'columns': ['s1c1', 's1c2', 's1c3'],
        'column_map': {
            's1c1': 'm1f1',
            's1c2': 'm1f2',
            's1c3': 'm1f3',
        }
    }, 
    'Sheet2':{
        'model': Model2, 
        'columns': ['s2c1', 's2c2', 's2c3'],
        'column_map': {
            's2c1': 'm2f1',
            's2c2': 'm2f2',
            's2c3': 'm2f3',
        }
    }

}

wb = openpyxl.load_workbook('./datas.xlsx')

print(wb.sheetnames)

for sheet_name in wb.sheetnames:
    sheet = wb[sheet_name]
    for index, row in enumerate(sheet.iter_rows()):
        data = {}
        if index: # First row is columns name
            for idx2, col in enumerate(row):
                # print(col.value)
                p = sheet_to_model[sheet_name]['columns'][idx2]
                # print(p)
                data[sheet_to_model[sheet_name]['column_map'][p]] = col.value
            # print(data)
            sheet_to_model[sheet_name]['model'].objects.create(**data)

您还可以学习和使用Pandas来更轻松地处理这种情况。