SAS报表高级样式设置与图像插入技巧
1. 高级颜色和边框分配
在一个程序中更改输出的多个部分是一项重要的技能,它结合了诸如创建临时变量、使用多标签格式为跨变量添加值以及更改单个边框等多种技术。
1.1 对一个单元格应用多种样式
示例展示了如何在现有样式属性的基础上进行构建,并展示这些样式属性如何相互作用。最终报告将有四个部分,每个部分对应
PRODUCT_LINE
的一个值,每个部分需要不同的背景颜色和粗边框,日期列中的年份总计列需要有左边框和更粗的右边框。
- 创建格式并更改样式模板
data crfmt;
fmtname=‘mydatef’;
hlo=‘MS’;
begin=‘01JAN2003’D;
finish=‘31DEC2007’D;
numq=intck(‘qtr’,begin,finish);
numy=intck(‘year’,begin,finish);
do i=0 to numq;
start=intnx(‘qtr’,begin,i);
end=intnx(‘qtr’,begin,i,‘E’);
label=put(start,yyq6.);
output;
end;
do i=0 to numy;
start=intnx(‘year’,begin,i);
end=intnx(‘year’,begin,i,‘E’);
label=year(start);
output;
end;
run;
proc sort data=crfmt;
by end descending start;
run;
proc format cntlin=crfmt;
run;
proc template;
define style mypearl;
parent=styles.pearl;
style Table from Table /
cellpadding = 4pt
borderspacing = 0pt
borderwidth = 1pt
frame = box
rules = rows
bordercolor = black
bordercollapse = collapse;
end;
run;
操作步骤:
1. 创建一个包含格式信息的数据集,该格式将为
BEGIN
和
FINISH
值之间的每个季度以及每个相应年份设置一个标签。
2. 对数据集进行排序,确保每年的季度标签出现在年份标签之前。
3. 创建一个自定义样式模板,更改
RULES=
、
BORDERCOLOR=
和
BORDERSPACING=
属性。
- 在行和列级别应用各种样式更改
ods escapechar=”^”;
options missing=” orientation=landscape nocenter;
ods rtf file=‘test.rtf’ style=mypearl;
proc report data=orders spanrows style(header)=[background=vpap];
column (‘^{style[borderrightcolor=black borderrightwidth=2pt]}’
(‘^{style[borderrightcolor=black
borderrightwidth=1pt]Product}’ product_line)
(‘^{style[borderrightcolor=black
borderrightwidth=2pt]Customer Groups}’ customer_group))
order_date,total_retail_price;
define product_line / group ”
style(column)=[borderrightcolor=black borderrightwidth=1pt
vjust=c just=c];
define customer_group / group ”
style(column)=[borderrightcolor=black borderrightwidth=2pt];
define order_date / across format=mydatef. ‘Order Date’ mlf
preloadfmt order=data;
define total_retail_price / ”;
break after product_line / summarize suppress;
compute before product_line;
pcnt+1;
endcomp;
compute product_line;
if pcnt = 1 then call define(_row_,‘style’,
‘style={background=vlibg}’);
else if pcnt = 2 then call define(_row_,‘style’,
‘style={background=khaki}’);
else if pcnt = 3 then call define(_row_,‘style’,
‘style={background=aliceblue}’);
else if pcnt = 4 then call define(_row_,‘style’,
‘style={background=ligy}’);
if product_line ne ” and _break_ = ” then do;
call define(_row_,‘style/merge’,
‘style={bordertopcolor=black bordertopwidth=2pt}’);
if pcnt = 1 then call define(_col_,‘style’,
‘style={borderbottomcolor=vlibg}’);
else if pcnt = 2 then call define(_col_,‘style’,
‘style={borderbottomcolor=khaki}’);
else if pcnt = 3 then call define(_col_,‘style’,
‘style={borderbottomcolor=aliceblue}’);
else if pcnt = 4 then call define(_col_,‘style’,
‘style={borderbottomcolor=ligy}’);
end;
endcomp;
compute after product_line / style={background=lightgrey
bordertopcolor=black borderbottomcolor=black
borderbottomwidth=2pt bordertopwidth=2pt};
line ‘ ‘;
customer_group = ‘Totals’;
call define(‘customer_group’,‘style’,
‘style=[font_weight=bold font_style=italic]’);
endcomp;
compute total_retail_price;
call define(‘_c7_’,‘style’,‘style={borderleftcolor=black
borderleftwidth=1pt borderrightcolor=black
borderrightwidth=2pt}’);
call define(‘_c8_’,‘style’,‘style={borderleftcolor=black}’);
call define(‘_c12_’,‘style’,‘style={borderleftcolor=black
borderleftwidth=1pt borderrightcolor=black
borderrightwidth=2pt}’);
call define(‘_c13_’,‘style’,‘style={borderleftcolor=black}’);
call define(‘_c17_’,‘style’,‘style={borderleftcolor=black
borderleftwidth=1pt borderrightcolor=black
borderrightwidth=2pt}’);
call define(‘_c18_’,‘style’,‘style={borderleftcolor=black}’);
call define(‘_c22_’,‘style’,‘style={borderleftcolor=black
borderleftwidth=1pt borderrightcolor=black
borderrightwidth=2pt}’);
call define(‘_c23_’,‘style’,‘style={borderleftcolor=black}’);
if upcase(_break_) = ‘PRODUCT_LINE’ then do i=3 to 27;
call define(i,‘format’,‘dollar10.’);
end;
endcomp;
run;
ods rtf close;
操作步骤:
1. 指定在
PROC TEMPLATE
步骤中创建的自定义样式模板。
2. 为
PRODUCT_LINE
和
CUSTOMER_GROUP
列的跨标题右侧添加粗黑色边框,将这些报告项的标题与日期列的标题在视觉上分开。
3. 为
CUSTOMER_GROUP
列添加粗右侧边框,将其与日期列在视觉上分开。
4. 创建一个计数器变量
PCNT
,为
PRODUCT_LINE
值计数,每个值将有一个唯一的计数值。
5. 为每个
PRODUCT_LINE
值内的所有行分配背景颜色。
6. 在标题和第一个详细行之间放置一个粗边框,使用
STYLE/MERGE
选项将此规范添加到其他
CALL DEFINE
语句的规范中。
7. 在详细行和
BREAK
语句创建的汇总行之间创建一个边框,通过将
PRODUCT_LINE
列的边框颜色更改为与背景颜色匹配来移除该边框。
8. 通过此计算块更改
LINE
语句输出的样式属性,将行的背景颜色更改为浅灰色,并添加粗顶部和底部边框。
9. 为每个年份列添加黑色左侧边框和更粗的黑色右侧边框。
10. 更改汇总行中所有分析列的格式,这些列通过列号3 - 27引用。
1.2 为每隔一行着色
可以根据行号本身来决定是否更改属性,而不是基于数据中已有的值。例如,可以为最终报告中的每隔一行或每三行应用背景颜色属性。
proc report data=orders;
column customer_country customer_group quantity total_retail_price;
define customer_country / group format=$cntry.;
define customer_group / group;
compute customer_country;
row_num + 1;
if mod(row_num,2) = 0 then
call define(_row_,‘style’,‘style=[background=lightgrey]’);
endcomp;
run;
操作步骤:
1. 任何与报告项关联的计算块都会在每一行执行,通常使用
COLUMN
语句中的第一个或最后一个变量作为报告项。
2. 每次执行计算块时(即每一行),递增一个临时变量
ROW_NUM
。
3. 使用
MOD
函数确定第一个参数除以第二个参数的余数,除以2时,偶数行的余数为0,将偶数行的背景颜色设置为浅灰色。
1.3 更改HTML输出中的边框
HTML中的边框行为并不总是与其他目标相同。一般来说,可以在
STYLE<(location(s))>=
选项中更改颜色或厚度,也可以使用内联格式命令更改,但前提是单元格有文本。移除HTML中的边框是一项棘手的任务。
proc report data=orders2
style(report)=[rules=groups]
style(header)=[bordercolor=cxEDF2F9]
style(column)=[borderrightwidth=0pt borderleftwidth=0pt];
column product_line last_gender customer_gender quantity
total_retail_price;
define product_line / group;
define customer_gender / group;
define last_gender / group noprint;
compute last_gender;
if not missing(last_gender) then hold=last_gender;
endcomp;
compute customer_gender;
if hold = customer_gender then do;
call define(_row_,‘style’,‘style=[borderbottomwidth=.1pt
borderbottomcolor=cx919191]’);
end;
else do;
call define(_row_,‘style’,‘style=[borderbottomwidth=1pt
borderbottomcolor=white]’);
end;
endcomp;
run;
操作步骤:
1. 将
BORDERCOLOR
属性值更改为与标题背景颜色匹配的蓝色(
cxEDF2F9
)。
2. 将报告列(数据)部分的垂直边框宽度设置为零,以避免在
CALL DEFINE
语句绘制的灰色水平边框中出现缺口。
3. 对于组中不是最后一行的所有行,将底部边框颜色更改为白色,与报告的白色背景匹配。
1.4 为ODS目标提供特殊指令
STYLE=
选项的一个高级功能是允许
PROC REPORT
将特定于目标的特殊指令传递给报告正在呈现的ODS目标。例如,
TAGATTR=
属性可以传递Excel特定的指令,
RTF
命令代码可以传递给Microsoft Word,
HTML
标签可以传递给基于HTML的输出。
ods excel file=“Output6-28.xlsx”;
proc report data=orders;
column customer_age_group customer_gender quantity
total_retail_price new;
define customer_age_group / group;
define customer_gender / group;
define new / computed ‘Price per Unit’
style(column)={tagattr=‘format:Currency formula:RC[-1]/RC[-2]’};
compute new;
new = 0;
endcomp;
run;
ods excel close;
操作步骤:
1. 在应用公式之前,计算变量需要一个值,将
NEW
设置为零确保公式被应用,并且最终表中有一个值。
2. 图像插入
图像对于许多类型的报告至关重要,如公司标志、图表和照片等。可以将图像放置在报告的顶部或底部,也可以放置在表格的单元格内。
2.1 在报告表格上方或下方放置图像
可以使用
PREIMAGE=
和
POSTIMAGE=
属性在报告表格上方或下方插入图像。
- 在表格上方放置图像
proc report data=orders style(report)=[preimage=“cologo.tif”];
column customer_type n;
define customer_type / group;
run;
操作步骤:使用
PREIMAGE=
将图像放置在表格上方,由于它是表格的一部分,如果表格跨越多页,图像不会重复。
- 在表格下方放置图像
proc report data=orders style(report)=[postimage=“saslogo.jpg”];
column customer_type n;
define customer_type / group;
run;
操作步骤:使用
POSTIMAGE=
将图像放置在报告下方,但图像仍被视为表格的一部分,由于它位于表格底部,如果表格跨越多页,图像不会重复。
2.2 在表格内放置图像
- 在有值的单元格中插入图像
proc report data=orders;
column customer_type n;
define customer_type / group;
compute n;
if index(customer_type,‘Gold’) then
call define(_col_,‘style’,‘style=[postimage=“check.gif”]’);
endcomp;
run;
操作步骤:使用
CALL DEFINE
语句在单元格中放置图像,
POSTIMAGE=
属性将图像放置在值之后。
- 在计算列中插入图像
proc report data=orders;
column customer_type n check;
define customer_type / group;
define check /computed ‘ ‘;
compute check /char length=20;
if index(customer_type,‘Gold’) then
call define(_col_,‘style’,‘style=[postimage=“check.gif”]’);
endcomp;
run;
操作步骤:将检查标记放置在一个单独的列中,定义
CHECK
为字符型,以避免在未设置
MISSING
系统选项时在单元格中放置句点。
- 为每个值插入不同的图像
proc format;
value mypic
1 = “goldmedal.png”
2 = “silvermedal.png”
3 = “bronzemedal.png”;
value blank other=” “;
run;
proc report data=orders;
column order_type image;
define order_type / group format=typef.;
define image / computed ‘ ‘ style(column)=[preimage=mypic.]
format=blank.;
compute image;
image = order_type;
endcomp;
run;
操作步骤:
1. 创建格式信息,将所需的图像文件链接到感兴趣的变量的特定值,标签值应包含适当的文件路径。
2. 创建一个格式,将显示的值更改为空白。
3. 在
STYLE(COLUMN)=
中为
PREIMAGE=
分配包含图像名称的格式名称。
4. 为
FORMAT=
选项分配在步骤2中创建的
BLANK.
格式,以防止
IMAGE
变量的值出现在最终输出中。
5. 将
IMAGE
设置为
ORDER_TYPE
的值,通过
DEFINE
语句上应用的格式将图像放置在单元格中。
-
插入背景图像
可以使用BACKGROUNDIMAGE=属性将图像设置为单元格的背景图像,但该属性仅在少数ODS目标中有效,并且图像的大小与单元格的宽度和高度对报告的最终外观起着重要作用。为了获得最佳效果,应创建具有特定高度和宽度的图像,并在PROC REPORT步骤中将相同的高度和宽度应用于单元格。
SAS报表高级样式设置与图像插入技巧(续)
3. 总结与应用建议
在前面的内容中,我们详细介绍了SAS报表的高级颜色和边框分配以及图像插入的相关技巧。下面通过一个表格来总结这些内容及其应用场景:
| 功能类别 | 具体操作 | 应用场景 |
| ---- | ---- | ---- |
| 高级颜色和边框分配 | 对一个单元格应用多种样式 | 需要对报表的不同部分进行精细样式设置,如区分不同产品线、客户组等 |
| | 为每隔一行着色 | 使报表数据更具可读性,突出显示某些行 |
| | 更改HTML输出中的边框 | 优化报表在HTML格式下的显示效果,避免不必要的边框 |
| | 为ODS目标提供特殊指令 | 向不同的ODS目标(如Excel、RTF等)传递特定指令,实现特殊功能 |
| 图像插入 | 在报告表格上方或下方放置图像 | 为报表添加公司标志、版权信息等 |
| | 在表格内放置图像 | 在报表中展示相关的图标、图片等,增强报表的可视化效果 |
下面是一个mermaid格式的流程图,展示了在SAS中创建一个具有高级样式和图像插入功能的报表的整体流程:
graph LR
A[开始] --> B[设置高级颜色和边框样式]
B --> C{是否需要插入图像}
C -- 是 --> D[选择图像插入位置]
C -- 否 --> E[生成报表]
D --> F{图像位置}
F -- 表格上方 --> G[使用PREIMAGE=插入图像]
F -- 表格下方 --> H[使用POSTIMAGE=插入图像]
F -- 表格内 --> I{插入方式}
I -- 有值单元格 --> J[使用CALL DEFINE插入图像]
I -- 计算列 --> K[定义计算列并插入图像]
I -- 不同值不同图像 --> L[创建格式并插入图像]
I -- 背景图像 --> M[使用BACKGROUNDIMAGE=插入图像]
G --> E
H --> E
J --> E
K --> E
L --> E
M --> E
E --> N[结束]
4. 注意事项
在使用这些高级技巧时,还需要注意以下几点:
1.
文件路径和格式
:在插入图像时,要确保图像文件的路径正确,并且使用的格式(如
.png
、
.jpg
、
.gif
等)被支持。同时,在创建格式指向图像文件时,要包含完整的路径名。
2.
ODS目标兼容性
:不同的ODS目标(如RTF、Excel、HTML等)对样式和图像的支持可能不同。例如,
BACKGROUNDIMAGE=
属性仅在少数ODS目标中有效,在Tagsets.ExcelXP目的地不能使用图像,PowerPoint目的地不能在单元格内放置图像。在进行样式设置和图像插入时,要考虑目标输出格式的兼容性。
3.
性能问题
:插入大量高分辨率的图像可能会影响报表的生成速度和文件大小。因此,图像文件应保持高质量且相对较小,避免使用过大尺寸的图像。
4.
样式冲突
:在使用多个
CALL DEFINE
语句或样式属性时,可能会出现样式冲突的问题。例如,使用
STYLE
选项可能会覆盖之前设置的背景颜色等属性,此时可使用
STYLE/MERGE
选项来避免冲突。
5. 实际案例演示
假设我们要创建一个销售报表,展示不同产品线的销售情况,并在报表顶部插入公司标志,同时为每隔一行着色以提高可读性。以下是实现该目标的完整代码:
/* 高级颜色和边框分配 - 创建格式和样式模板 */
data crfmt;
fmtname=‘mydatef’;
hlo=‘MS’;
begin=‘01JAN2003’D;
finish=‘31DEC2007’D;
numq=intck(‘qtr’,begin,finish);
numy=intck(‘year’,begin,finish);
do i=0 to numq;
start=intnx(‘qtr’,begin,i);
end=intnx(‘qtr’,begin,i,‘E’);
label=put(start,yyq6.);
output;
end;
do i=0 to numy;
start=intnx(‘year’,begin,i);
end=intnx(‘year’,begin,i,‘E’);
label=year(start);
output;
end;
run;
proc sort data=crfmt;
by end descending start;
run;
proc format cntlin=crfmt;
run;
proc template;
define style mypearl;
parent=styles.pearl;
style Table from Table /
cellpadding = 4pt
borderspacing = 0pt
borderwidth = 1pt
frame = box
rules = rows
bordercolor = black
bordercollapse = collapse;
end;
run;
/* 高级颜色和边框分配 - 应用样式更改 */
ods escapechar=”^”;
options missing=” orientation=landscape nocenter;
ods rtf file=‘sales_report.rtf’ style=mypearl;
proc report data=orders spanrows style(header)=[background=vpap];
column (‘^{style[borderrightcolor=black borderrightwidth=2pt]}’
(‘^{style[borderrightcolor=black
borderrightwidth=1pt]Product}’ product_line)
(‘^{style[borderrightcolor=black
borderrightwidth=2pt]Customer Groups}’ customer_group))
order_date,total_retail_price;
define product_line / group ”
style(column)=[borderrightcolor=black borderrightwidth=1pt
vjust=c just=c];
define customer_group / group ”
style(column)=[borderrightcolor=black borderrightwidth=2pt];
define order_date / across format=mydatef. ‘Order Date’ mlf
preloadfmt order=data;
define total_retail_price / ”;
break after product_line / summarize suppress;
compute before product_line;
pcnt+1;
endcomp;
compute product_line;
if pcnt = 1 then call define(_row_,‘style’,
‘style={background=vlibg}’);
else if pcnt = 2 then call define(_row_,‘style’,
‘style={background=khaki}’);
else if pcnt = 3 then call define(_row_,‘style’,
‘style={background=aliceblue}’);
else if pcnt = 4 then call define(_row_,‘style’,
‘style={background=ligy}’);
if product_line ne ” and _break_ = ” then do;
call define(_row_,‘style/merge’,
‘style={bordertopcolor=black bordertopwidth=2pt}’);
if pcnt = 1 then call define(_col_,‘style’,
‘style={borderbottomcolor=vlibg}’);
else if pcnt = 2 then call define(_col_,‘style’,
‘style={borderbottomcolor=khaki}’);
else if pcnt = 3 then call define(_col_,‘style’,
‘style={borderbottomcolor=aliceblue}’);
else if pcnt = 4 then call define(_col_,‘style’,
‘style={borderbottomcolor=ligy}’);
end;
endcomp;
compute after product_line / style={background=lightgrey
bordertopcolor=black borderbottomcolor=black
borderbottomwidth=2pt bordertopwidth=2pt};
line ‘ ‘;
customer_group = ‘Totals’;
call define(‘customer_group’,‘style’,
‘style=[font_weight=bold font_style=italic]’);
endcomp;
compute total_retail_price;
call define(‘_c7_’,‘style’,‘style={borderleftcolor=black
borderleftwidth=1pt borderrightcolor=black
borderrightwidth=2pt}’);
call define(‘_c8_’,‘style’,‘style={borderleftcolor=black}’);
call define(‘_c12_’,‘style’,‘style={borderleftcolor=black
borderleftwidth=1pt borderrightcolor=black
borderrightwidth=2pt}’);
call define(‘_c13_’,‘style’,‘style={borderleftcolor=black}’);
call define(‘_c17_’,‘style’,‘style={borderleftcolor=black
borderleftwidth=1pt borderrightcolor=black
borderrightwidth=2pt}’);
call define(‘_c18_’,‘style’,‘style={borderleftcolor=black}’);
call define(‘_c22_’,‘style’,‘style={borderleftcolor=black
borderleftwidth=1pt borderrightcolor=black
borderrightwidth=2pt}’);
call define(‘_c23_’,‘style’,‘style={borderleftcolor=black}’);
if upcase(_break_) = ‘PRODUCT_LINE’ then do i=3 to 27;
call define(i,‘format’,‘dollar10.’);
end;
endcomp;
/* 为每隔一行着色 */
compute customer_group;
row_num + 1;
if mod(row_num,2) = 0 then
call define(_row_,‘style’,‘style=[background=lightgrey]’);
endcomp;
run;
/* 在报表顶部插入图像 */
ods rtf style(report)=[preimage=“company_logo.tif”];
ods rtf close;
通过以上代码,我们实现了一个具有高级样式和图像插入功能的销售报表。在实际应用中,可以根据具体需求对代码进行调整和扩展。
总之,掌握SAS报表的高级样式设置和图像插入技巧,可以帮助我们创建出更加专业、美观和具有可视化效果的报表,提升数据展示的质量和效率。
超级会员免费看
9

被折叠的 条评论
为什么被折叠?



