2014-03-02 75 views
0

在我的应用程序(Yii)中,我有一个Ajax Submit Button,它触发了一个Excel文件(使用PHPExcel)的生成。 成功时我用一个隐藏的表单提交文件得到它下载:从request.responseText下载Excel文件

<div class="reporting"> 
    <?php 
     $this->beginWidget('zii.widgets.jui.CJuiDialog',array(
      'id'=>'mydialog', 
      'options'=>array(
       'title'=>'Warning!', 
       'autoOpen'=>false, //true, 
       'modal'=>'true', 
       'width'=>'auto', 
       'height'=>'auto', 
       'open' => 'js:function(event, ui) { 
       }', 
       'close' => 'js:function(event, ui) { 
        $(".ui-dialog:has(#mydialog)").empty().remove(); 
       }', 
      ) 
     )); 
    ?> 
    <table class="contentheader"> 
     <tr> 
      <td> 
       <?php echo CHtml::DropDownList('dropDownId', $lastyear, $yearslist, array('options'=>array($lastyear=>array('selected'=>true)))); ?> 
      </td> 
     </tr> 
    </table> 
    <br /> 
    <?php echo CHtml::ajaxSubmitButton('Form Ajax Submit Button', 
     CHtml::normalizeUrl(array('/planning/xlsAbsences')), 
      array(
       'type'=>'POST', 
       'beforeSend' => "function(request) { console.log('beforeSend'); }", 
       'data'=>'js:$("#select-year-form").serialize()+"&year="+$("#dropDownId :selected").text()', 
       'success' => function(response, status, request){ 
        $("#mydialog").dialog("close"); 
        var disp = request.getResponseHeader("Content-Disposition"); 
        if (disp && disp.search("attachment") != -1) { 
         var filename = disp.substring(disp.indexOf("filename=") + 10, disp.length-1); 
         var form = $("<form method=\"POST\" action=\"index.php?r=planning/dl\">"); 
         form.append($("<input type=\"hidden\" name=\"content\" value=\"" + request.responseText + "\">")); 
         form.append($("<input type=\"hidden\" name=\"filename\" value=\"" + filename + "\">")); 
         $("body").append(form); 
         form.submit(); 
        } 
       } 
       'complete' => "function(request) { console.log(request); }", 
       'error' => "function(data) { alert('erro'+data); }", 
      ), 
      array('name' => 'run', 'class' => 'btn btn-success') 
    ); ?> 
    <?php $this->endWidget('zii.widgets.jui.CJuiDialog'); 
     echo CHtml::link(Yii::t('app','app.menu.reporting.planning.xlsabsence'), '#', array( 
      'onclick'=>'$("#mydialog").dialog("open"); return false;', 
     )); 
    ?> 
</div> 

问题是,生成的文件是不是有效的Excel文件。 我想Excelfile的内容是在request.responseText中。 我已经看到无法通过Excel打开的生成文件以UTF(不含BOM)编码。 如果我生成的文件没有Ajax Submit Button,那么文件就没问题。但它似乎是用ANSI编码的。 我使用Notpad ++来查看编码信息。当我将UTF(无BOM)转换为ANSI时,结果并不好。

我在这里错过了什么?

编辑: 我不知道我的描述是否不够清楚 - Excel文件不存在。在CJuiDialog中提交Ajax提交按钮时会生成Excel文件内容 - 例如,用户打开对话框并选择参数 - 根据用户选择的参数生成Excel文件。 由于该文件不存在,我看不到如何下载它。我发现唯一的解决方案是通过隐藏表单。

EDIT2: 我发表了整个视图代码(以上)

+0

你实际提交检索到Excel中返回到服务器,迫使它下载?这似乎是一个巨大的开销。只需从Ajax调用中返回下载URL(它设置content-disposition标头等)并对此URL执行JavaScript重定向。 –

+0

我编辑了我的帖子,使事情更清晰 - 你确定这可以做得更容易吗? –

回答

0

在这里,你走了,这是你想才达到什么:http://jqueryfiledownload.apphb.com/

查看更多有关在这里:Download a file by jQuery.Ajax

+0

我编辑我的文章,使事情更清楚 - 我想使用这个插件文件必须存在 - 这不是我的情况... –

+0

您正在生成服务器上的文件,你只是不保存它,但这并不意味着它不存在。它确实存在,因为你生成它。当然,你可以使用插件,因为它完全符合你的需求。 –

0

有不需要使用ajax调用。

如果您将数据提交到返回带有Content-Disposition标头集的内容的URL,浏览器将不会打开该页面,但会提示下载。

因此,可以说,这是你现在拥有的一切:

$.ajax({ 
    type: 'POST', 
    url: '/excel/generate.php', 
    'success' => function(response, status, request){ 
     $("#mydialog").dialog("close"); 
     var disp = request.getResponseHeader("Content-Disposition"); 
     if (disp && disp.search("attachment") != -1) { 
      var filename = disp.substring(disp.indexOf("filename=") + 10, disp.length-1); 
      var form = $("<form method=\"POST\" action=\"index.php?r=planning/dl\">"); 
      form.append($("<input type=\"hidden\" name=\"content\" value=\"" + request.responseText + "\">")); 
      form.append($("<input type=\"hidden\" name=\"filename\" value=\"" + filename + "\">")); 
      $("body").append(form); 
      form.submit(); 
     } 
    } 
}); 

您可以替换为

var form = $('<form/>', {method: 'POST', action: '/excel/generate.php'}); 
form.appendTo('body'); 
form.submit(); 
+0

我想,如果我尝试这个,我不能自动关闭对话框:( –

+0

只需关闭'form.submit();' –

+0

之前的对话框我不明白这一点:正如我所说我在编码PHP(Yii)和你的代码是javascript - 我编辑我的文章,以给出完整的视图操作代码 - 那么你可以告诉我要替换的是什么? –