AttributeError: у объекта 'list' нет атрибута 'iter_rows' - PullRequest
1 голос
/ 24 июня 2019

Я бы прочитал файл 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 ]

1 голос
/ 24 июня 2019

worksheet = wb.sheetnames фактически возвращает имена листов в виде список .

Как получить лист:

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имеет следующие листы и соответствующие столбцы:

  • Лист1 (столбцы: 's1c1', 's1c2', 's1c3')
  • Лист1 (столбцы: 's1c1', 's1c2', 's1c3')

А у вас есть модели maned Model1 и Model2.Данные Sheet1 будут сохранены в 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 для более легкого управления этими типами ситуаций.

1 голос
/ 24 июня 2019

Согласно документации, 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],...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...