Django

Django openpyxl로 생성한 엑셀파일 templates으로 보내기

_베토디 2022. 7. 4. 23:39
반응형

* firebase의 firestore의 db사용 연결 방법 등은 이전 글 참조

 

firestore 에서 불러온 데이터를 메인페이지에서 엑셀파일로 다운로드 받을 수 있게 하고 싶다

 

# views.py

rom django.shortcuts import render
from django.http import HttpResponse
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
from openpyxl import Workbook
from openpyxl.writer.excel import save_virtual_workbook

#FIRESTORE INITIALIZING
cred = credentials.Certificate('./firestore.json') 
firebase_admin.initialize_app(cred)

db = firestore.client()


# Create your views here.
def index(request):
    #컬렉션명 리스트로 저장
    ref = db.collections()
    lst_col = []
    for col in ref:
        lst_col.append(col.id)  
        
    # main.html에 있는 다운로드 버튼을 누르면 엑셀파일 다운로드 실행    
    if 'download' in request.POST:
      
        fld_list = []
        for l in lst_col: 
            fld = db.collection(l).stream()
            now_fld = []
            for f in fld: 
                fld_name = list(f.to_dict().keys())
                for j in fld_name: 
                    if j not in now_fld:
                        now_fld.append(j)
            fld_list.append(now_fld)

        #엑셀파일만들기
        wb = Workbook()
        

        for k in range(len(lst_col)):  
            
            ref = db.collection(lst_col[k]).get()        
            ws = wb.create_sheet(lst_col[k])   
            ws.title = lst_col[k]
            ws['A1'] = 'num'
            n=1
            for fld in fld_list[k]:
                ws.cell(row=1, column=n+1).value = fld
                n += 1
    
            num = 1
            for i in ref:
                dict = i.to_dict()
                row_data = []
                row_data.append(num)
                for val in fld_list[k]:
                    try:
                        row_data.append(str(dict[val]))
                    except:
                        row_data.append('')
                num += 1
                ws.append(row_data)

        wb.remove_sheet(wb['Sheet'])
        
       """
       생성된 엑셀파일을 임시저장(?) 한 후 response로 클라이언트에 보내준다
       response['Content-Disposition'] = 'attachment; filename=파일명.xlsx'로 지정하면
       자동으로 파일이 다운로드 된다(다운로드 폴더로..) 파일명은 알아서 지정
       """
       
        response = HttpResponse(content=save_virtual_workbook(wb), content_type='application/ms-excel')
        response['Content-Disposition'] = 'attachment; filename=alldata.xlsx'
        return response
        
    else:
        return render(request, 'main.html', {'collections':lst_col})

openpyxl 로 엑셀파일 만드는 법은 구글링하면 엄청 많이 나오고

사용법이 어렵지 않다...나도 몇 번 만져보고 만들었으니까

 

결론은 백엔드에서 만든 엑셀파일을 클라이언트 로 보내주려면 

        response = HttpResponse(content=save_virtual_workbook(wb), content_type='application/ms-excel')
        response['Content-Disposition'] = 'attachment; filename=alldata.xlsx'
        return response

요 세 줄만 입력해주면 된다.

wb는 위에서 지정한 워크북생성할 때 변수고, filename 은 원하시는 대로..

response['Content-Disposition'] 이 reponse 객체 내에서 엑셀파일이 포함되어(?) 있는 곳이고

원래 디폴트는 inline 인데 attachment 로 바꾸면 첨부파일 다운로드 하는 식으로 바뀌는 것 같다..

궁금해서 찾아봤는데 무슨 말인지는 잘 모르겠다...ㅠㅠㅠ

 

 

+) json으로 넘겨주는 방법도 해 볼 생각

 

 

* 참조 : https://stackoverflow.com/questions/16016039/django-openpyxl-saving-workbook-as-attachment