前段时间有一个需求,利用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;
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编程有那么多技巧,你却还在等灵感乍现?!