엑셀에 있는 데이터들을 해당 모델 인스턴스를 생성해서 저장하는 api와 특정 기간에 해당하는 인스턴스들을 불러와 그 데이터들을 다시 엑셀에 저장하는 api를 만들어보았다. django에서 excel에 접근하기 위해서 pandas라는 python 라이브러리를 사용했다.
python dataframe인 pandas를 사용하여 엑셀을 읽고 써볼 것이다. 우선 pandas를 설치해준다
pip install pandas
import pandas as pd
filename = '엑셀파일 이름 넣기'
df_excel = pd.read_excel(filename)
print(df_excel)
# 엑셀에 있는 데이터들이 출력
위에서는 read_excel에 파일명만 넣었었는데, 빈번하게 사용될만한 옵션들을 넣어봤다.
pandas.read_excel(filename,
sheet_name = '서울',
header = None,
names = ['일시','평균','최저','최고'],
index_col = None,
usecols = "C:F",
dtype = {'일시':str, '평균':float, '최저':float, '최고':float},
skiprows = 32,
nrows = 28,
na_values = 'nan',
thousands = ',')
import pandas as pd
df = pd.DataFrame([[11, 21, 31], [12, 22, 32], [31, 32, 33]],
index=['one', 'two', 'three'], columns=['a', 'b', 'c'])
print(df)
# a b c
# one 11 21 31
# two 12 22 32
# three 31 32 33
# 엑셀 파일 출력
df.to_excel('경로및 파일명/파일명만 적으면 현재 디렉토리내에 생성')
to_excel() 함수의 옵션을 몇개 살펴보면 다음과 같다.
우선 엑셀의 생김새는 다음과 같다.
15분 단위로 데이터들이 날짜별로 있다. 이 데이터들을 이제 모델 인스턴스를 만들어 주어서 넣어주어야 한다. Data라는 모델에는 timestamp와 위에 value 값들이 들어가면 된다.
@api_view(('POST',))
def uploadExcelDataToTargetTag(request):
try:
# 포스트요청으로 들어온 엑셀파일을 받아온다.
excel_file = request.FILES['excelFile']
filename, fileExtension = os.path.splitext(str(excel_file))
# 파일확장자를 통해 엑셀파일이 맞는지 체크해준다
if fileExtension != ".xlsx":
return Response("Unavailable file extension")
else:
df = pd.read_excel(excel_file, usecols='C:CU')
time_array = pd.read_excel(excel_file, usecols='D:CU').columns.to_numpy()
bulk_list = []
for row in df.itertuples():
date = row[1].replace('.', '-') # timestamp 포멧 변경
values = row[2:] # 00:15 ~ 24:00 까지의 values
timestamp = ""
for i, d in enumerate(list(values)):
if isinstance(d, (int, float)):
timestamp = f"{date} {time_array[i]}"
bulk_list.append(Data(
timestamp=timestamp,
value=d
))
Data.objects.bulk_create(bulk_list, batch_size=250)
return Response("Data Uploaded")
except Exception as e:
print(e)
return Response('Data Upload Failed')
입력으로 기간이 오고 출력으로는 기간에 해당하는 데이터들을 엑셀파일에 저장해주는 api를 만들어줄것이다. 우선은 이차배열에다가 데이터들을 저장해준다음 마지막에 한꺼번에 엑셀파일들을 생성해줄것이다.
@api_view(('POST',))
def downloadExcelData(request):
start_date = request.data['start_date'] # 시작날짜
end_date = request.data['end_date'] # 끝난 날짜
datas = Data.objects.filter(timestamp__range=[start_date, end_date])
columns = ['고객번호', '계기번호', '날짜', '00:00', '00:15', '00:30', '00:45', '01:00', '01:15', '01:30', '01:45', '02:00',
'02:15', '02:30', '02:45', '03:00', '03:15', '03:30', '03:45', '04:00', '04:15', '04:30', '04:45',
'05:00', '05:15', '05:30', '05:45', '06:00', '06:15', '06:30', '06:45', '07:00', '07:15', '07:30',
'07:45', '08:00', '08:15', '08:30', '08:45', '09:00', '09:15', '09:30', '09:45', '10:00', '10:15',
'10:30', '10:45', '11:00', '11:15', '11:30', '11:45', '11:00', '12:00', '12:15', '12:30', '12:45',
'13:00', '13:15', '13:30', '13:45', '14:00', '14:15', '14:30', '14:45', '15:00', '15:15', '15:30',
'15:45', '16:00', '16:15', '16:30', '16:45', '17:00', '17:15', '17:30', '17:45', '18:00', '18:15',
'18:30', '18:45', '19:00', '19:15', '19:30', '19:45', '20:00', '20:15', '20:30', '20:45', '21:00',
'21:15', '21:30', '21:45', '22:00', '22:15', '22:30', '22:45', '23:00', '23:15', '23:30', '23:45',
'합계(kWh)'] # 칼럼 우선 생성해주기,,,노가다,,,ㅎㅎ,,,
dates = [] # 인스턴스에서 날짜만 저장해주기
for r in raw_datas:
date, hour = str(r.timestamp).split(' ') # 타임스탬프에 날짜와 시간이 모두 있기 때문에 나눠주기
if date in dates: #중복이면 패스
pass
else:
dates.append(date)
excel_data = [[" " for j in range(len(columns))] for i in range(len(dates))]
for i in len(dates):
excel_data[i][2] = dates[i] # 날짜만 우선 넣어주기
for data in datas:
date, hour = str(raw_data.timestamp).split(' ')
hour = hour[:5] # 시간만 추출해주기
for j, column in enumerate(columns): 해당 시간에 데이터 저장해주기
if hour == column:
excel_data[dates.index(date)][j] = data.value
result = 0
for x in range(len(excel_data)):
for y in range(3, len(excel_data[x])):
if excel_data[x][y] != ' ':
result += excel_data[x][y]
excel_data[x][100] = result # 00:00~23:45분까지 데이터들의 합 저장해주기
df = pd.DataFrame(data, columns=columns)
df.to_excel('sample.xlsx', index=False)
return Response("Data Download")
{ "start_date":"2020-09-24", "end_date":"2020-09-25" }
위처럼 이제 해당 api로 요청을 보내주면 아래와 같이 엑셀이 만들어지면서 저장이 된다.