You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SAS存储过程(Stored Process)中生成多个CSV导出文件

问题根因

HTTP协议单请求仅支持返回1个附件,响应头会在内容输出前就发送到浏览器,你原有代码在同一个请求中多次修改Content-Disposition头、在同一个输出流拼接两份CSV内容的写法无效,浏览器只会识别首次返回的第一个CSV文件。

调整方案

提供两种可落地的实现方式:


方案1:点击按钮触发两次独立下载请求(无压缩包,直接得到两个CSV)

步骤1:调整前端HTML代码

替换原有表单逻辑,新增JS点击事件,一次点击触发两次下载请求:

data _null_;     
  format infile $char256.;     
  input;    
  infile = resolve(_infile_);    
  file _webout;    
  put infile;    
cards4;    
  
<style>   
input[type='submit'] {   
  border-radius: 10px;  
  cursor: pointer;
  padding: 8px 20px;
  font-size: 14px;
}   
</style>                          
<HTML>      
<BODY>       
  <H2 align="center">Deseja atualizar a Base?</H2>      
  <H3 align="center">(Tempo estimado: 15 minutos)</H3>      
      
  <div align="center">
    <input type="submit" value="Atualizar" id="downloadBtn">
  </div>

  <script>
    document.getElementById('downloadBtn').addEventListener('click', function() {
      // 触发第一个CSV下载,对应后端FILE1导出接口
      window.open('http://mydir?_program=/export_file1', '_blank');
      // 延迟200ms触发第二个CSV下载,避免浏览器拦截
      setTimeout(() => {
        window.open('http://mydir?_program=/export_file2', '_blank');
      }, 200);
    });
  </script>
</BODY>      
</HTML>                
;;;;      
run;

步骤2:拆分后端SAS核心代码为两个独立存储过程

存储过程1:/export_file1 仅导出FILE1

%let hoje = %sysfunc(today(),date9.);
%let rc=%sysfunc(stpsrv_header(Content-type,text/csv));  
%let rc=%sysfunc(stpsrv_header(Content-disposition,attachment%str(;) filename=FILE1_&HOJE..csv));  
%let _ODSSTYLE=PEARL;
  
ods csv file=_webout options(autofit_height='YES' FROZEN_HEADERS='YES' delimiter="|");
PROC PRINT DATA=FILE1 noobs LABEL 
style(HEADER)={color=black background=white font_weight=bold font_size=10pt font_face=CALIBRI width=1.8in just=c vjust=c} 
style(DATA) = {background=white font_size=10pt font_face=CALIBRI};
format MYVAR $char.;  
RUN;
ods csv close;

存储过程2:/export_file2 仅导出FILE2

%let hoje = %sysfunc(today(),date9.);
%let rc=%sysfunc(stpsrv_header(Content-type,text/csv));  
%let rc=%sysfunc(stpsrv_header(Content-disposition,attachment%str(;) filename=FILE2_&HOJE..csv));  
%let _ODSSTYLE=PEARL;
  
ods csv file=_webout options(autofit_height='YES' FROZEN_HEADERS='YES' delimiter="|");
PROC PRINT DATA=FILE2 noobs LABEL 
style(HEADER)={color=black background=white font_weight=bold font_size=10pt font_face=CALIBRI width=1.8in just=c vjust=c} 
style(DATA) = {background=white font_size=10pt font_face=CALIBRI};
RUN;
ods csv close;

方案2:单请求返回压缩包(仅一次下载,解压得到两个CSV)

无需修改前端,仅调整后端SAS代码,将两个CSV打包为ZIP返回:

%let hoje = %sysfunc(today(),date9.);
/* 先创建临时ZIP文件 */
filename outzip ZIP "%sysfunc(getoption(WORK))/output.zip" member='FILE1_&HOJE..csv';

/* 写入第一个CSV到ZIP */
ods csv file=outzip options(autofit_height='YES' FROZEN_HEADERS='YES' delimiter="|");
PROC PRINT DATA=FILE1 noobs LABEL 
style(HEADER)={color=black background=white font_weight=bold font_size=10pt font_face=CALIBRI width=1.8in just=c vjust=c} 
style(DATA) = {background=white font_size=10pt font_face=CALIBRI};
format MYVAR $char.;  
RUN;
ods csv close;

/* 切换ZIP成员,写入第二个CSV */
filename outzip ZIP "%sysfunc(getoption(WORK))/output.zip" member='FILE2_&HOJE..csv';
ods csv file=outzip options(autofit_height='YES' FROZEN_HEADERS='YES' delimiter="|");
PROC PRINT DATA=FILE2 noobs LABEL 
style(HEADER)={color=black background=white font_weight=bold font_size=10pt font_face=CALIBRI width=1.8in just=c vjust=c} 
style(DATA) = {background=white font_size=10pt font_face=CALIBRI};
RUN;
ods csv close;

/* 返回ZIP文件给前端 */
%let rc=%sysfunc(stpsrv_header(Content-type,application/zip));  
%let rc=%sysfunc(stpsrv_header(Content-disposition,attachment%str(;) filename=EXPORT_&HOJE..zip));  
/* 输出ZIP到_webout */
data _null_;
  infile "%sysfunc(getoption(WORK))/output.zip" recfm=n;
  file _webout recfm=n;
  input byte $char1. @;
  put byte $char1. @;
run;
filename outzip clear;

内容的提问来源于stack exchange,提问作者JOAO RF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 02:39:04