SAS-输出文档生成目录的方法

2020-09-01 11:14:51 浏览数 (1)

前段时间有一个需求,利用SAS实现文档目录的自动生成。这里小编没有限定文档的类型,是因为本文将分享两种类型文档(PDF/RTF)通过SAS自动生成目录的方法。

正文

在SAS中,利用ODS输出文档前,通常都会定义Style通过proc template定义输出样式,在proc template中也可以对目录页的样式进行设置。proc template中相关的语句如下。

代码语言:javascript复制
 style ContentTitle from IndexTitle
      "Controls the title of the Contents file." /
      fillrulewidth = 0.5pt
      marginright = 1em
      marginleft = 1em
      width = 100%
      marginbottom = 4ex
      margintop = 3ex
      font = fonts('TitleFont')
      pretext = text('content title')
      textalign = center;
   style PrintedContentsLabel
      "Sort of a post-posttext for the CONTENTS" /
      posttext = " (*ESC*){leaders .  }(*ESC*){tocentrypage}"
      pretext = "(*ESC*){tocentryindent 2em}";
   style ContentItem from IndexItem
      "Controls the leafnode item in the Contents file." /
      marginright = 15%
      marginleft = 15%;
   style ContentFolder from IndexItem
      "Controls the generic folder definition in the Contents file." /
      marginright = 15%
      marginleft = 15%
      listentryanchor = off
      color = colors('confolderfg');
   style ContentProcName from IndexProcName
      "Controls the proc name in the Contents file." /
      marginright = 15%
      marginleft = 15%;
   style ContentProcLabel from ContentProcName
      "Controls the proc label in the Contents file." /
      posttext = _undef_
      pretext = _undef_;

关于如何查询proc template默认style中关于目录的设置的样式,可通过获取style样式源码,在源码中查找关于Content相关内容。

代码语言:javascript复制
proc  template ;
 source styles.default;
run;

template

下面是小编修改后的template。

代码语言:javascript复制
proc template;
  define style tp;
  parent = styles.rtf;
  replace   fonts /                                                         
    "TitleFont2" = ("宋体",9pt) 
    "TitleFont" = ("宋体",9pt)  
    "StrongFont" = ("宋体",9pt,Bold) 
    "EmphasisFont" = ("宋体",9pt,Italic)                                                              
    "FixedEmphasisFont" = ("宋体",9pt,Italic)                                                              
    "FixedStrongFont" = ("宋体",9pt)  
    "FixedHeadingFont" = ("宋体",10pt)      
    "BatchFixedFont" = ("宋体",10pt)        
    "FixedFont" = ("宋体",9pt)             
    "headingEmphasisFont" = ("宋体",10pt,Bold Italic)                                                      
    "headingFont" = ("宋体",10pt,Bold)
    "docFont" = ("宋体",9pt);
  replace Header from HeadersandFooters / font = ("宋体", 9pt, medium) 
    background = _undef_
    protectspecialchars = off;
  replace table from output / font = ("宋体", 9pt, medium)
    background = _undef_
    frame = void
    rules = none
    cellspacing = 0.5pt
    cellpadding = 1pt
    outputwidth = 100%;;
  replace cell from output / 
    font = ("宋体", 9pt, medium) ;
    *定义表头;
    style header /
    backgroundcolor=white 
    color=black
    fontweight=bold;
  *定义文件的布局;
  style body from document / 
    bottommargin = 15mm
    topmargin = 15mm
    rightmargin = 15mm
    leftmargin = 15 mm;
   class Contents /
      liststyletype = "decimal"
      tagattr = " onload=""expandAll()"""
      pagebreakhtml = html('break')
      color = colors('contentfg')
      backgroundcolor = colors('contentbg')
      marginright = 0
      marginleft = 0;
/*控制目录标题*/
   style ContentTitle from IndexTitle
      "Controls the title of the Contents file." /
      fillrulewidth = 0pt 
      marginright = 1em
      marginleft = 1em
      width = 100%
      marginbottom = 0ex
      margintop = 0ex
      font = ("宋体",12pt,Bold)  /*目录字体*/
       pretext = "(*ESC*){style   
  [fontweight=medium
     backgroundcolor=white
     fontsize=5
     color=black nobreakspace=off   borderbottomcolor=black borderbottomwidth=.5 ]目录}"
      textalign = center;
   style PrintedContentsLabel
      "Sort of a post-posttext for the CONTENTS" /
      posttext = " (*ESC*){leaders .}(*ESC*){tocentrypage}"
      pretext = "(*ESC*){tocentryindent 2em}";
   style ContentItem from IndexItem
      "Controls the leafnode item in the Contents file." /
      marginright = 5% 
      marginleft = 5%;
   style ContentFolder from IndexItem
      "Controls the generic folder definition in the Contents file." /
      marginright = 5%
      marginleft = 5%
      listentryanchor = off
      color = colors('confolderfg');
   style ContentProcName from IndexProcName
      "Controls the proc name in the Contents file." /
      marginright = 5%
      marginleft = 5%;
  end;
run;

PDF

SAS输出PDF文档生成目录的原理是利用ods pdf 结合Proc document过程步进行实现的。

效果展现

程序

代码语言:javascript复制


%macro setpaths;
%global setup_ runsetup ;
%let setup_= %upcase(%sysget(sas_execfilepath));
%let runsetup=%sysfunc(prxchange(s/(.*)\.*/1/,-1,&setup_));
proc datasets library=work kill nolist;
quit;


%mend;
%setpaths;


  ods escapechar='^';
  option nomprint nosymbolgen nomlogic nomfile;
  option nobyline nodate nonumber orientation="PORTRAIT" papersize=A4  ;
  title1  justify = c  "(*ESC*){style rowheader  [color=black nobreakspace=off   borderbottomcolor=black borderbottomwidth=.5 ]
                                https://www.sas-pharma.com                           }";
  footnote1  justify = c '第 ^{thispage} 页';
  ods document name=mydocrep1(write);




data class;
  set sashelp.class;
  holder=1;/*无实际作用:控制显示*/
run;


  proc report data=class nowd headskip headline split='|' missing nocenter contents="表1"
  style(report)={ pretext="表1"  };
      column NAME AGE holder;
      define NAME / display "" style(header)=[just=left] style(column)=[just=left cellwidth=70% asis=on];
      define AGE / display "" style(header)=[just=left] style(column)=[just=right cellwidth=26% asis=on];
      define holder / noprint order;
      break before holder / page contents='';


  run;


  proc report data=class nowd headskip headline split='|' missing nocenter contents="表2"
  style(report)={ pretext="表2"  };
      column NAME SEX holder;
      define NAME / display "" style(header)=[just=left] style(column)=[just=left cellwidth=70% asis=on];
      define SEX / display "" style(header)=[just=left] style(column)=[just=right cellwidth=26% asis=on];
      define holder / noprint order;
      break before holder / page contents='';


  run;
  ods document close;




%macro prodoc;
  /*
    利用document输出 PDF 添加目录 标签等信息
  */
  ods output properties=Props;
  proc document name=mydocrep1;
  list / levels=all;
  run;
  quit;
  data _null_;
  set props end=last;
     if type in("Table" "表") then do;
        count 1;
        call symputx('patht'||trim(left(count)),path);
     end;
  call symputx('total',count);
  run;
  proc document name=work.mydocrep1;
     %do i=1 %to &total;
        setlabel &&patht&i "表&i.";
        move &&patht&i to ^;
     %end;


  ods pdf file="&runsetup./Content_test.pdf" contents=yes style=tp startpage=yes  ;
       replay ;
  run;
  ods pdf close;
  quit;
%mend;
%prodoc;

这里主要需要掌握的知识点是proc document ,关于相关用法可在SAShelp中查找。详细了解代码思路,可以一步一步执行代码,这里小编就不在赘述了。

RTF

前面介绍了PDF文档输出目录页,下面在来看看RTF文档目录页生成的方式。关于RTF文档目录页目前查询SAS HELP得到的方法是通过toc_data结合Contents选项。

效果展现

程序

代码语言:javascript复制
proc template;
  define style tp_rtf;
  parent =tp;
   style ContentTitle from IndexTitle
      "Controls the title of the Contents file." /
      fillrulewidth = 10pt 
      marginright = 1em
      marginleft = 1em
      width = 100%
      marginbottom = 1ex
      margintop = 1ex
      font = ("宋体",12pt,Bold)  /*目录字体*/
      textalign = center
    pretext = "目录";
  end;
run;

  ods proclabel=' ';
  ods escapechar='^';
  option nomprint nosymbolgen nomlogic nomfile;
  option nobyline nodate nonumber orientation="PORTRAIT" papersize=A4  ;
  title1  justify = c  "(*ESC*)R/RTF'brdrbbrdrs https://www.sas-pharma.com";
  footnote1  justify = c '第 ^{thispage} 页';
  ods rtf file="&runsetup./Content_test.rtf" contents style=tp_rtf startpage=yes toc_data  ;
  ods proclabel=' ';
  proc report data=class nowd headskip headline split='|' missing nocenter contents="表1"
  style(report)={ pretext="outlinelevel2{表1}line" };
      column NAME AGE holder;
      define NAME / display "" style(header)=[just=left] style(column)=[just=left cellwidth=70% asis=on];
      define AGE / display "" style(header)=[just=left] style(column)=[just=right cellwidth=26% asis=on];
      define holder / noprint order;
      break before holder / page contents='';

  run;
  ods proclabel=' ';
  proc report data=class nowd headskip headline split='|' missing nocenter contents="表2"
  style(report)={ pretext="outlinelevel2{表2}line" };
      column NAME SEX holder;
      define NAME / display "" style(header)=[just=left] style(column)=[just=left cellwidth=70% asis=on];
      define SEX / display "" style(header)=[just=left] style(column)=[just=right cellwidth=26% asis=on];
      define holder / noprint order;
      break before holder / page contents='';
  run;


  ods rtf close;

相对来说RTF生成目录索引较PDF简单。当然理论上也可以采用其他方式生成,这里就不在介绍了。本文主要目的是提供一种思路和几种方法,程序代码均是可执行的简单示例。

代码下载

点击文章底部“看”后,再点击“阅读原文”即可下载本文所有代码相关文档,或前往https://www.sas-pharma.com/如下图位置进行下载。

联系方式

邮箱:setup@mail.sas-pharma.com

网站:https://www.sas-pharma.com/

SAS编程有那么多技巧,你却还在等灵感乍现?!

0 人点赞