2010-03-17 12 views
7

브라우저에서 첨부 파일로 처리하도록 HttpResponse를 사용하여 CSV 파일을 다운로드하려고합니다. 제공된 지침 (here)을 따르지만 내 브라우저는 "다른 이름으로 저장"대화 상자를 표시하지 않습니다. 내 기능에 어떤 문제가 있는지 알 수 없다. 모든 도움을 주시면 감사하겠습니다.django에서 csv 파일 다운로드

 
    dev savefile(request): 
     try: 
      myfile = request.GET['filename'] 
      filepath = settings.MEDIA_ROOT + 'results/' 
      destpath = os.path.join(filepath, myfile) 
      response = HttpResponse(FileWrapper(file(destpath)), mimetype='text/csv') 
      response['Content-Disposition'] = 'attachment; filename="%s"' %(myfile) 
      return response 
     except Exception, err: 
      errmsg = "%s"%(err) 
      return HttpResponse(errmsg) 

행복한 패트의 날!

답변

1

감사합니다 모두 당신의 제안. 몇 가지 새로운 트릭을 선택했습니다 :) 그러나 여기에 내 문제에 대한 대답을 찾은 것 같아요 : Downloading CSV via AJAX "savefile"함수가 Ajax 요청을 통해 호출되었고 ajax에 "대화 상자로 저장" "HTTP 헤더가 무엇이든 관계없이 표시되지 않습니다.

나는이 함수를 호출하기 위해 Ajax를 사용 했음에 틀림 없다고 말했지만 결코 문제가 될 수 없었다. :) Thankyou StackOverflow!

5

콘텐츠 유형을 지정해 보셨습니까? 예 :

response['Content-Type'] = 'application/x-download'; 

편집 :

참고,이 코드가 성공적으로 나를 위해 대화 "다른 이름으로 저장"는 트리거합니다. 참고 mimetype 인수에서 "application/x-download"를 직접 지정합니다. 또한 코드를 다시 검사하고 파일 경로가 올바른지, FileWrapper()가 이상한 일을하지 않는지 확인할 수도 있습니다.

def save_file(request): 
    data = open(os.path.join(settings.PROJECT_PATH,'data/table.csv'),'r').read() 
    resp = django.http.HttpResponse(data, mimetype='application/x-download') 
    resp['Content-Disposition'] = 'attachment;filename=table.csv' 
    return resp 
+0

시도해도 여전히 작동하지 않습니다. FireBug에서 응답과 헤더를 볼 수 있지만 대화 상자가 표시되지 않습니다. – spyder

+0

현재 편집을 시도하십시오. – Cerin

+0

나는 그것을 시도했지만 작동하지 않았다. 내 회신을 참조하십시오, 문제가 장고와 아무 관련이없는 것으로 나타났습니다. 감사합니다 – spyder

7

파일이 어쨌든 장고를 통해 서비스를 제공해서는 안된다 (즉이 아닌 요청을 위해 특별히 생성) 정적 경우. 웹 서버가 제공하는 경로 (예 :/static /)를 구성하고 모든 django 오버 헤드를 저장해야합니다.

  1. 가 메모리에 생성하고 장고에서 봉사 :

    파일이 동적 경우

    2 가지 옵션이 있습니다.
  2. 디스크에 생성하고 HttpResponseRedirect를 반환하여 웹 서버가 다운로드 자체를 처리하도록합니다 (파일이 매우 큰 경우이 옵션을 사용해야합니다). 동적으로 역할에 관해서는

, 나는

import StringIO 
from django.db.models.query import ValuesQuerySet, QuerySet 

class CSVResponse(HttpResponse): 

    def __init__(self, data, output_name='data', headers=None, encoding='utf8'): 

    # Make sure we've got the right type of data to work with 
    valid_data = False 
    if isinstance(data, ValuesQuerySet): 
     data = list(data) 
    elif isinstance(data, QuerySet): 
     data = list(data.values()) 
    if hasattr(data, '__getitem__'): 
     if isinstance(data[0], dict): 
      if headers is None: 
       headers = data[0].keys() 
      data = [[row[col] for col in headers] for row in data] 
      data.insert(0, headers) 
     if hasattr(data[0], '__getitem__'): 
      valid_data = True 
    assert valid_data is True, "CSVResponse requires a sequence of sequences" 

    output = StringIO.StringIO() 
    for row in data: 
     out_row = [] 
     for value in row: 
      if not isinstance(value, basestring): 
       value = unicode(value) 
      value = value.encode(encoding) 
      out_row.append(value.replace('"', '""')) 
     output.write('"%s"\n' % 
        '","'.join(out_row))    
    mimetype = 'text/csv' 
    file_ext = 'csv' 
    output.seek(0) 
    super(CSVResponse, self).__init__(content=output.getvalue(), 
             mimetype=mimetype) 
    self['Content-Disposition'] = 'attachment;filename="%s.%s"' % \ 
     (output_name.replace('"', '\"'), file_ext) 

그냥 반환 CSVResponse (...)를 사용하여, 그것을 사용하려면 통과 (ExcelResponse의 단순화 된 버전입니다) 다음 코드를 사용하고 목록의 목록에서 (동일한 키를 사용하는) dicts 목록, QuerySet, ValuesQuerySet

+0

"이"요청에 대해 즉석에서 생성되어/static /에 일시적으로 저장됩니다. – spyder

+0

설명 후 편집 됨 –

+0

감사합니다. ! – spyder

0

큰 따옴표로 파일 이름을 묶지 않으면 어떤 차이가 있습니까? 샘플 코드는 파일 이름을 인용하지 않습니다

response['Content-Disposition'] = 'attachment; filename=foo.xls' 

을하지만 코드 수행합니다

response['Content-Disposition'] = 'attachment; filename="foo.xls"' 
+0

고마워, 그것을 시도 ... 아니 기쁨. – spyder

0

Thomas, 나는이 파일을 저장하고 다운로드하기 위해 Ajax 함수를 사용했다.이 경우 헤더에 관계없이 "다른 이름으로 저장"상자가 나타나지 않는 것으로 보입니다. 나는 그 파일을 다운로드하기 위해 자바 스크립트를 사용했다. window.open ("path/to/file"); 그리고 트릭을합니다. IE6과 Firefox에서 테스트를했는데 대화 상자가 나타납니다.