2016-07-29 4 views
0

docxtpl을 사용하여 워드 문서를 생성하고 cherrypy를 사용하여 생성 한 파일을 사용자가 어떻게 다운로드 할 수 있는지 궁금 할 경우 아래 코드를 참조하십시오.docpypl 생성 cherrypy로 파일 생성

내가 해결할 수있는 유일한 해결책은 www 폴더에 저장하고 위치에 대한 링크를 만드는 것입니다. 그러나 이것이 단순화 될 수 있다고 확신합니다.

코드 :

import os, os.path 
import random 
import string 
import cherrypy 
from docxtpl import DocxTemplate 
import sys 
from auth import AuthController, require, member_of, name_is 
import socket 

reload(sys) 
sys.setdefaultencoding('utf8') 
cherrypy.config.update({'server.socket_port': 8000}) 
cherrypy.server.socket_host = '0.0.0.0' 
cherrypy.engine.restart() 

class Root(object): 

    _cp_config = { 
     'tools.sessions.on': True, 
     'tools.auth.on': True } 

    @cherrypy.expose() 
    def default(self, **kwargs): 
     print kwargs  
     if kwargs.get('csa_no'): 
#    print kwargs.get('csa_no') 
      tpl=DocxTemplate('csa_tpl.docx')    
      sd = tpl.new_subdoc() 
      p = sd.add_paragraph('This 1st insert') 
      sd2 = tpl.new_subdoc() 
      p = sd2.add_paragraph('This 2nd insert') 
      context1 = { 
        'date': 'jkh', 
        'company_name' : 'Test Footer', 
        'cost' : '10,000', 
        'project_description': kwargs['project_description'], 
        'site': kwargs['site'], 
        'sp': kwargs['sp'], 
        'wo': kwargs['WO'], 
        'contract_manager': kwargs['contract_manager'], 
        'csa_no': kwargs['csa_no'], 
        'variation_reason': kwargs['variation_reason'], 
        'variation_scope_of_works': kwargs['variation_scope_of_works'], 

        'Initial_Contract_Value': '$300,000', 
        'variation_total': '$20,000', 
        'Ammended_Contract_Value': '$320,000', 
        'project_manager': kwargs['project_manager'], 
        'construction_manager': 'Dane Wilson', 
        'date': '30/04/2016',  
       } 
      tpl.render(context1) 
      file_name_with_path = '/var/www/html/csa_documents/' + kwargs['sp'] + '-'+ kwargs['WO'] + '_' + kwargs['site'] + '_-_' + 'CSA' + kwargs['csa_no'] +'.docx' 
      file_name = kwargs['sp'] + '-'+ kwargs['WO'] + '_' + kwargs['site'] + '_-_' + 'CSA' + kwargs['csa_no'] +'.docx' 
      print file_name 
      print file_name_with_path 
      tpl.save(file_name_with_path) 
      return ''' 

      <!DOCTYPE html> 
      <html> 
      <head> 
      <meta name="viewport" content="width=device-width, initial-scale=1"> 
      <meta charset="utf-8" http-equiv="X-UA-Compatible" content="IE=9" /> 
      <link href="//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.2/jquery.mobile.min.css" rel="stylesheet"> 
      <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 
      <script src="//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.2/jquery.mobile.min.js"></script> 
      <title>Broadspectrum</title> 
      </head> 
      <body> 
      <div data-role="header" data-theme="b"> 
      <h1>TCSS Gateway</h1> 
      </div> 
      <h2>Success</h2> 
      <a href="http://192.168.1.7">another submission</a> 
      <a href="http://192.168.1.7/csa_documents/%s">Download & Review CSA Document</a> 
      </body> 

      ''' % file_name 

답변

1

짧은 대답은 기본적으로 당신이 어떤 메모리 스트림 (예를 들어, BytesIO)를 작성해야한다는 것입니다, 일부 HTTP 헤더를 미리 설정하고 file_generator을 반환합니다. 귀하의 질문은 한달 전에 한 질문과 거의 동일하며 here 내 답변입니다.

내가 python3에 당신을 위해 작은 조각을 초안 한

:

from io import BytesIO 

import cherrypy 
from cherrypy.lib import file_generator 

from docxtpl import DocxTemplate 


class GenerateDocx: 
    @cherrypy.expose 
    def build_docx(self, *args, **kwargs): 
     iostream = BytesIO() 

     tpl = DocxTemplate('csa_tpl.docx') 
     ... 
     # build your tpl here 
     ... 
     tpl.get_docx().save(iostream) 

     cherrypy.response.headers['Content-Type'] = (
      # set the correct MIME type for docx 
      'application/vnd.openxmlformats-officedocument' 
      '.wordprocessingml.document' 
     ) 
     cherrypy.response.headers['Content-Disposition'] = (
      'attachment; filename={fname}.docx'.format(
       fname='put your file name here' 
      ) 
     ) 

     iostream.seek(0) 
     return file_generator(iostream) 

UPD : 난 그냥 the response body gets automatically wrapped with file_generator if the return value of a handler has read() method support

+0

덕분에, 내가 파일을 얻을 수 있음을 확인하지만, DOCX에 보이는 한의 콘텐츠 처분은 zip.please 도움말 – Ossama

+0

에서 설정 한 것 같습니다. cherrypy.response.headers [ 'Content-Disposition'] = ( '첨부 파일, 파일 이름 = "file.docx"' )를 사용하여 docx를 얻을 수 있지만 파일이 비어 있습니다. – Ossama

+0

아, 필자는 그 확장 기능이 docx 여야한다고 확신했다. – webKnjaZ