Paper 016-2009 
A SAS
®
Output Delivery System Menu for All Appetites and Applications 
Chevell Parker, SAS Institute Inc., Cary, NC 
ABSTRACT 
This document describes how to unleash the power of various ODS destinations to generate fantastic applications 
and reports. This power is evident when generating spreadsheets using a variety of ODS destinations. The 
document describes how and when to harness the power of ODS destinations. It describes methods to generate that 
perfect presentation-quality output. This includes general formatting, creating styles with the addition of templates 
that are specifically generated for Excel output, and all those little things that lead to great-looking output. 
Other menu items include the following: 
arranging output on the page using several approaches, such as ODS LAYOUT; HTMLPanel and 
TableEditor tagsets; the report-writing features of the DATA step; customizing tables; enhancing output 
creating HTML, which adds the ability to sort, freeze, reorder, and export data dynamically and as other 
dynamic features 
modifying objects using the ODS Document facility to generate the desired table of contents and 
bookmarks 
enhancing styles using a variety of methods 
INTRODUCTION  
Beginning with SAS
®
7.0, generating effective, stylish, and functional reports became possible with the SAS Output 
Delivery System (ODS). The system began with one formatted destination, the ODS HTML destination, and it has 
evolved to other ODS destinations such as PDF, RTF, ExcelXP, and others.  
Regardless of what applications you use or your taste in reporting styles, ODS has a menu of offerings that enable 
you to build that perfect application or report.  This document highlights the ODS menu of destinations and practical 
applications that you can generate to create effective reports. 
MODIFYING THE TABLE OF CONTENTS AND BOOKMARKS 
The table of contents (TOC) in the HTML destination, or the bookmark list in a PDF destination, provides a 
navigational aide or outline to output. This navigational aide, created by ODS, points to specific tables or graphs. As 
the designer of the report, you must choose the appropriate description and appearance of this outline. To effectively 
name and organize this table of contents, you can choose from multiple items on the ODS menu, including the 
following: 
destination-specific items such as ODS Markup for HTML 
the new ODS PDF option in SAS
®
9.2, PDFTOC= 
the ODS PROCLABEL statement, the CONTENTS= procedure option, and the DESCRIPTION= option for 
graphics 
the ODS Document facility, which includes the ODS DOCUMENT statement, the DOCUMENT procedure, 
and the SASEDOC LIBNAME engine   
We will start with the simplest method of modifying the table of contents, naming and removing nodes, and will build 
then from there. 
NAMING AND REMOVING NODES 
A table of contents is created with ODS HTML and the ExcelXP tagset, while a bookmark list is created with ODS 
PDF. Renaming items in a table of contents or in a bookmark list is easy with the ODS PROCLABEL statement. You 
can use this statement to rename the top-most item (the procedure name) that is created from each output object. 
All output objects create two or more node levels by default. The subsequent levels of this output object vary 
depending on the procedure that generates it.  For example, the PRINT procedure creates a single sub-node, while 
multiple complex node levels are created by procedures such as the SHEWHART procedure.  Procedures such as 
PRINT, REPORT, TABULATE, and FREQ include the CONTENTS= option, which enables a sub-node to be 
renamed. Unless you use a BY statement in PROC PRINT and PROC REPORT, the sub-node will be the second 
level of the output object. You can use the CONTENTS= option with null quotation marks (CONTENTS="") to remove 
a sub-node. Some graphics procedures, such as GCHART and GPLAT, support the DESCRIPTION= option that you 
can use to label sub-nodes. 
Procedures that do not include the CONTENTS= option have table templates. Using these templates, you can 
rename a sub-node with the CONTENTS_LABEL attribute within the column attribute.   
Applications Development
t
SAS Global Forum 2009
09
9
Pdf rotate one page - rotate PDF page permanently in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Empower Users to Change the Rotation Angle of PDF File Page Using C#
how to rotate one page in a pdf file; pdf reverse page order online
Pdf rotate one page - VB.NET PDF Page Rotate Library: rotate PDF page permanently in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
PDF Document Page Rotation in Visual Basic .NET Class Application
rotate pdf page few degrees; rotate pdf page permanently
In the following example, Display 1 shows both a default TOC and bookmark output created by the sample code. 
Note that only the last level in the TOC is a link to the output by default; however, all levels of the PDF bookmark list 
link to the output.     
Example 1 
ods pdf file=”temp2.pdf”; 
proc print data=sashelp.class; 
run; 
proc sql; 
select * from sashelp.class; 
run; 
quit; 
proc gchart data=sashelp.class; 
vbar age; 
run; 
quit; 
proc tabulate data=sashelp.class; 
class age; 
var height weight; 
table age, height weight; 
run; 
ods pdf close;    
Display 1. Default TOC and bookmark list 
The next example uses the same procedures, and it adds the ODS PROCLABEL statement and the 
CONTENTS= option.  The ODS PROCLABEL statement renames the first level (the procedure name) of the 
output object, while CONTENTS="" removes the sub-node (the second level under 
The
Print 
Procedure
) and the second and third levels under 
The
Tabulate
Procedure
. The DESCRIPTION= 
option is used here to rename the sub-node under 
The GCHART Procedure
Example 2 
ods pdf file="temp.pdf"; 
ods proclabel "Detail Report"; 
proc print data=sashelp.class        
contents=""; 
run; 
ods proclabel "Query of Data"; 
proc sql; 
select * from sashelp.class; 
run; 
quit; 
ods proclabel "Chart of Data"; 
proc gchart data=sashelp.class; 
vbar age / description="Visual of    
Age"; 
run; 
quit; 
ods proclabel "Summary of Data"; 
proc tabulate data=sashelp.class    
contents=""; 
class age; 
var height weight; 
table age, height weight /  
contents=""; 
run;                                           
ods pdf close; 
Applications Development
SAS Global Forum 2009
09
9
VB.NET PDF Page Delete Library: remove PDF pages in vb.net, ASP.
If you are looking for a solution to conveniently delete one page from your PDF document, you can use this VB.NET PDF Library, which supports a variety of PDF
pdf save rotated pages; permanently rotate pdf pages
C# PDF File Merge Library: Merge, append PDF files in C#.net, ASP.
C# developers can easily merge and append one PDF document to document imaging toolkit, also offers other advanced PDF document page processing and
how to rotate a single page in a pdf document; rotate pdf pages in reader
Display 2. Modified bookmark list  
DESTINATION-SPECIFIC MODIFICATIONS 
Common methods are available for restructuring a TOC in a customized format, ODS also has destination-
specific methods you can use, such as ODS Markup Language for HTML or the new ODS PDF option that 
is available in SAS 9.2.  If you are creating HTML, you can use ODS Markup Language to customize and 
restructure your output. You can use the Markup Language to modify the underlying HTML4 tagset that 
renders output for the HTML destination.  The tagset consists of individual events (for example, the 
CONTENTS_BRANCH and the CONTENTS_LEAF events) that can be modified to restructure the individual 
parts of a TOC.  
To modify the node levels that are displayed, you can use ODS Markup Language to create an option that 
you include in the ODS statement, as shown in the next example. This is a simple example of HTML-
specific code that you can use to specify the number of levels you want to display.  
Example 3 
proc template; 
define tagset tagsets.test; 
parent=tagsets.html4; 
define event initialize; 
set $test $options['LEVEL']; 
end; 
define event contents_branch;                                            
start:  
break / if toc_level > $test;  
trigger do_link; 
trigger list;                                                                  
finish:                                                                           
trigger list finish;                                                                     
file=CONTENTS;                                                      
end;  
define event contents_leaf; 
break / if toc_level > $test; 
trigger do_link;                                           
file = CONTENTS;                                                      
end;  
end; 
run; 
Display 3. Default output that is generated  
Applications Development
SAS Global Forum 2009
09
9
VB.NET PDF File Merge Library: Merge, append PDF files in vb.net
all. This guiding page will help you merge two or more PDF documents into a single one in a Visual Basic .NET imaging application.
rotate all pages in pdf; how to rotate all pages in pdf at once
C# PDF Page Extract Library: copy, paste, cut PDF pages in C#.net
Extract PDF Pages, Copy Pages from One PDF File and Paste into Others in C#.NET Program. Free PDF document processing SDK supports PDF page extraction, copying
save pdf rotated pages; pdf rotate pages separately
ods tagsets.test file="temp.html"  
contents="temp1.html" 
options(level="1"); 
proc print data=sashelp.class; 
run; 
proc print data=sashelp.class; 
run; 
proc freq data=sashelp.class; 
run; 
ods tagsets.test close; 
Display 4. TOC generated using ODS Markup
In this example, you add the new option by including the INITIALIZE event in a DEFINE statement along 
with a SET statement. The SET statement creates a memory variable from the LEVEL= option in the ODS 
statement. The memory variable that is created is used as a conditional argument along with the 
TOC_LEVEL automatic markup variable, which contains the current nesting levels of various items. The 
CONTENTSBRANCH event represents the top node in the TOC. This node begins with the procedure 
name and contains one level under it. CONTENTS_BRANCH can also contain more than one level, as 
illustrated in Display 3. Links to the tables and graphs are controlled by the CONTENTS_LEAF event. Note 
that you can also modify the BREAK statement to show only a specific level.   
In the next example, the PDFTOC= option is added to the SAS 9.2 ODS PDF destination. Along with the 
methods discussed so far, the PDFTOC= option provides new functionality and control in SAS 9.2. It 
enables you to specify the number of levels that you want to appear in the bookmark list when the PDF file 
is open. By default, the option displays all levels in the list when the PDF file is open. This gives you more 
control than was available in past releases.  
Example 4 
ods pdf file="temp2.pdf" pdftoc=1; 
proc print data=sashelp.class; 
run; 
proc print data=sashelp.class; 
run; 
proc freq data=sashelp.class; 
run; 
ods pdf close
Display 5. Bookmarks created with the  
PDTOC = option 
Note: This option does not enable you to restructure or rename the items in the bookmark list.  
ODS DOCUMENT FACILITY 
Now that your appetite has been whetted with some examples of customizing reports, you are ready to 
move on to total customization, which is available with the ODS Document facility. The ODS Document 
facility gives you complete control over your output objects. It enables you to rename, reorder, delete, hide, 
and import objects. In addition, SAS 9.2 now supports using the REPORT procedure with the Document 
facility.   
The Document facility is useful for tasks such as creating a single node for each output object in the TOC or 
grouping together all of the PROC PRINT output. To use the Document facility, you first create an ODS 
document that will be generated from a procedure or a DATA step. Such a document prevents having to 
store a physical file. You create the document using an ODS DOCUMENT statement.    
You can modify objects either interactively (via the ODS Document window within the SAS Display Manager 
Applications Development
SAS Global Forum 2009
09
9
VB.NET PDF Annotate Library: Draw, edit PDF annotation, markups in
to display it. Thus, PDFPage, derived from REPage, is a programming abstraction for representing one PDF page. Annotating Process.
reverse page order pdf online; rotate pdf page by page
C# PDF Page Delete Library: remove PDF pages in C#.net, ASP.NET
Using RasterEdge Visual C# .NET PDF page deletion component, developers can easily select one or more PDF pages and delete it/them in both .NET web and Windows
save pdf after rotating pages; rotate one page in pdf
System) or by using the DOCUMENT procedure. To modify documents interactively, submit the ODSDOC 
command to display the ODS DOCUMENT window.  After you modify and replay your objects in the 
Document window, you can use the new Document Recorder to generate the code from the actions that 
you performed.  If you are familiar with UNIX commands, this process should be familiar.  
Once the document is created, you can use PROC DOCUMENT along with the LIST statement to list the 
contents and the path of items within a document. Then you can modify the paths to customize the output 
the way you want it. The output consists of directories, reports, tables, and graphs. To simplify the TOC 
structure, you can reduce the directory structure in order to make a new directory and copy only the reports, 
tables, and graphs to this directory. Then you can replay the output.  
The following example creates an ODS Document from the procedures used previously in Example 1.  
PROC DOCUMENT manipulates the objects in this example first by creating a new directory with the MAKE 
statement. Then, the COPY statement is added to copy the graph and tables from the current directory 
structure to the new directory 
\TEST
that is created. The branch 
\TEST
is then replayed to the PDF 
destination, thereby removing the directory structure and displaying just a single table or graph. Note: If you 
have existing graphics in the WORK.GSEG catalog, you might need to use the GREPLAY procedure to 
delete them before you run the following example. Otherwise, incremental versions of the image (or the 
GRSEG member) will be created.  
Example 5 
/* Create document. */ 
ods document name=test(write); 
/* Sample code used previously in Example 1. */ 
ods document close; 
proc document name=test; 
list/levels=all; 
run; 
quit; 
The following output lists all levels of the document TEST before it has been manipulated:  
Listing of: \Work.Test\ 
Order by: Insertion 
Number of levels: All 
Obs   Path                                    Type 
____________________________________________ 
1 \Print#1                                          Dir 
2 \Print#1\Print#1                              Report 
3 \SQL#1                                          Dir 
4 \SQL#1\SQL_Results#1                Table 
5 \Gchart#1                                       Dir 
6 \Gchart#1\Gchart1#1                     Graph 
7 \Tabulate#1                                    Dir 
8 \Tabulate#1\Report#1                    Dir 
9 \Tabulate#1\Report#1\Table#1      Table 
Applications Development
SAS Global Forum 2009
09
9
C# PDF: C# Code to Process PDF Document Page Using C#.NET PDF
for developers on how to rotate PDF page in different two different PDF documents into one large PDF C# PDF Page Processing: Split PDF Document - C#.NET PDF
rotate pdf pages on ipad; how to change page orientation in pdf document
C# PDF copy, paste image Library: copy, paste, cut PDF images in
This C#.NET example describes how to copy an image from one page of PDF document and paste it into another page. // Define input and output documents.
change orientation of pdf page; how to reverse page order in pdf
Example 6 
ods pdf file="temp5.pdf";                                          
proc document name=test; 
make \test; 
dir \test#1; 
setlabel \test#1 "Procedure  
output";                      
setlabel \print#1\Print#1 "Print   
Output"; 
setlabel \SQL#1\SQL_Results#1     
"SQL Output"; 
setlabel \Gchart#1\Gchart#1    
"Gchart Output"; 
setlabel     
\Tabulate#1\Report#1\Table#1  
"Tabulate Output"; 
copy \print#1\Print#1 to ^; 
copy \SQL#1\SQL_Results#1 to  ^; 
copy \Gchart#1\Gchart#1  to  ^; 
copy \Tabulate#1\Report#1\Table#1  
to  ^; 
replay \test#1; 
Display 6. Output created by PROC 
DOCUMENT
run; 
quit; 
ods pdf close;                               
The following output lists all levels of the document TEST before manipulating the document:  
Listing of: \Work.Test\test#1 
Order by: Insertion 
Number of levels: All 
Obs    Path                                              Type 
_______________________________________ 
1 \test#1\Print#1                                 Report 
2 \test#1\SQL_Results#1                   Table 
3 \test#1\Gchart#1                              Graph 
4 \test#1\Table#1                                Table      
ODS DOCUMENT MACRO 
You can also use the ODS Document facility with a macro to automate the process of manipulating a table 
of contents. Example 7 replicates the prior example, but it uses PROC DOCUMENT along with a macro to 
automate the process.  An output data set is created by the LEVELS statement in PROC DOCUMENT. 
Macro variables are created from each observation where the output is a table, report, or graph. The macro 
variables are then resolved within the COPY statement and the DOCUMENT procedure. The SET 
statement labels the items that are replayed. As in Example 6, the MAKE statement creates a new directory 
where only the tables and graphs are copied and are replayed to the ODS PDF destination, thereby 
creating a single node for each table and graph.  
Example 7 
ods document name=temp(write);                                                                 
/* Procedures from Example 1. */ 
ods document close;                                                                            
ods output properties=temp;                                                                    
Applications Development
SAS Global Forum 2009
09
9
proc document name=temp;                                                                      
list / levels=all;                                                                         
run;                                                                                          
quit;                                                                                         
data _null_;                                                                                  
set temp end=last;                                                                         
if type in("Table","Report","Graph") then do; 
count+1;  
call symput('path'||trim(left(count)),path);  
end;  
if last then call symput('total',count);  
run;   
%macro test;   
ods pdf file="temp.pdf";  
proc document name=temp;  
make \newfolder;  
setlabel \newfolder "Procedure  
Output"; 
%do i=1 %to &total;  
%let proc=%substr  
(%scan(&&path&i,1,"#"),2); 
setlabel &&path&i "&proc  
Output";  
copy &&path&i to  
\newfolder#1
%end;                                                                                      
replay \newfolder;                                                                         
run;                                                                                          
quit;  
ods pdf close;  
%mend;                                                                                        
%test     
F 
Display 7. Output that is replayed from PROC 
DOCUMENT
ARRANGING AND PANELING OUTPUT                            
SAS 9.2 software provides more features than ever before to generate output in exactly the layout you want 
by placing data in a specific spot or by paneling output. In this environment, paneling refers to arranging 
tables or graphs across or down a page. Whether you want to place data in a specific spot on a page or to 
panel output, you can accomplish these tasks with the following items from ODS:   
the ODS LAYOUT feature, which currently works only works with the PDF destination 
the report-writing features of the DATA step  
the HTMLPanel and the TableEditor tagsets  for HTML, which is made possible with ODS Markup 
Language  
the GREPLAY procedure, which has many functions, including the ability to panel output 
new SAS 9.2 graphics procedures (such as the SGPANEL procedure)  
The following section provides the syntax for each of these methods as well as a description of how to use 
them.  
ODS LAYOUT 
The ODS LAYOUT feature is supported currently only by the PDF destination. However, more destinations 
might support the feature in future versions of the software. ODS LAYOUT enables you to place output on a 
page based on the requirements that you specify.  ODS LAYOUT permits two types of layouts: absolute 
and gridded. Both types of layouts start with an ODS LAYOUT statement, contain one or more ODS 
REGION statements, and end with an ODS LAYOUT END statement. 
Absolute layout enables you to explicitly place items on the page. With the absolute layout method, you can 
match an existing format such as a form, a specialized report (for example, a credit card bill), or any other 
type of output that requires exact positioning on a page. Such formatting was impossible in previous 
versions of SAS software. Using this method, you can place the items within a defined region by specifying 
Applications Development
SAS Global Forum 2009
09
9
the height and width as a standard number or a percentage and by defining the starting coordinates for the 
output with the X= and Y= options in the ODS REGION statement. If the region is not specified, the 
coordinates default to 
0,0
, which is the top left corner of the page (excluding the margins). This method 
can be problematic, however, in that if you do not define a large enough area, you might lose the output. If 
that happens, a warning appears in your log. 
Gridded layout enables you to define how many columns or rows you want. With this method, ODS 
LAYOUT dynamically determines how large the region needs to be. Unlike absolute layout, this method 
enables you to span output across multiple pages.  
Example 8 – Absolute Layout 
ods pdf file='c:\temp\trash\temp9.pdf' notoc style=styles.sasweb; 
ods layout start width=7in height=10in; 
ods region x=.5in  y=0in width=4in height=5in; 
proc print data=sashelp.class(obs=10); 
run; 
ods region  x=4in y=-1.5in width=4in height=5in; 
proc gchart data=sashelp.class; 
hbar3d age / patternid=midpoint; 
run; 
quit; 
ods region x=.5in  y=4in width=4in height=5in; 
proc print data=sashelp.retail(obs=10); 
run; 
ods region x=4in y=2.5in width=5in height=5in; 
proc gchart data=sashelp.retail; 
block month / patternid=midpoint discrete sumvar=sales type=sum; 
run; 
quit; 
ods layout end; 
ods pdf close;
Display 8. Output generated with ODS LAYOUT (absolute layout) 
Example 9 – Gridded Layout 
ods pdf file='c:\temp\trash\temp9.pdf'; 
ods layout start columns=2; 
ods region; 
proc print data=sashelp.class(obs=15); 
run; 
Applications Development
SAS Global Forum 2009
09
9
ods region; 
proc print data=sashelp.retail(obs=15); 
run; 
ods layout end; 
ods pdf close; 
Display 9. Output generated with ODS LAYOUT (gridded layout)                  
HTMLPANEL TAGSET 
The HTMLPanel destination, or tagset, generates HTML output for the Web just as the LAYOUT feature is 
used to generate PDF output. This tagset enables you to panel output. Paneled output is similar to the 
gridded layout available with ODS LAYOUT. With the HTMLPanel tagset, you can create simple output that 
panels tables and graphs across a page or complex output that panels across and down a page.  
Because the HTMLPanel tagset is a member of ODS Markup Language, it has defined options that 
determine how many tables or graphs to panel, or span, across or down a page. Manual methods of 
paneling are also available. For example, you can instruct the tagset where to begin and end paneling by 
using the EVENT= option in the ODS statement. You can also use the EVENT= option to create row-wise 
and column-wise panels.  Note: To see the syntax for all options that are available with this tagset, use the 
option DOC=”HELP”. 
Example 10 
goptions hsize=5in vsize=5in ftext=swissbb; 
ods tagsets.htmlpanel file="temp1.html"  style=sasweb event=panel(start); 
proc gchart data=sashelp.class; 
vbar3d age / discrete sumvar=height type=sum patternid=midpoint; 
run; 
quit; 
proc print data=sashelp.class; 
run; 
ods tagsets.htmlpanel event=panel(finish); 
ods tagsets.htmlpanel close; 
Applications Development
SAS Global Forum 2009
09
9
10 
Display 10. Output generated from the HTMLPanel tagset 
TABLEEDITOR TAGSET 
The TableEditor destination, or tagset, also enables simple paneling of HTML output through the use of the 
PANELCOLS= option in the ODS statement. With the TableEditor tagset, you can add tables and graphs side by 
side in addition to down a page. This tagset also many other features that you can use in conjunction with paneling 
functionality just by supplying options to the tagset. The TableEditor tagset inherits from the HTML4 tagset, which is 
used to render the HTML destination. The paneling feature of this tagset is not as robust as the HTMLPanel tagset.  
This tagset also enables you to add tabs along with paneled output. This feature is useful if you want to view or print 
only a subset of your data. Tabs are created with the WEB_TABS= option, which works similarly to creating sheet 
names in Microsoft Excel. Clicking on a specific tab displays only the selected output in the browser window. All 
other output remains hidden until you select the appropriate tab. You can find more information about the 
TableEditor tagset in the section “ODS Markup Language and the TableEditor Tagset”.  
As shown in the following example, you indicate where you want paneling to be by using the PANELCOLS= option in 
the OPTIONS parameter of the ODS TAGSETS.TABLEEDITOR statement. To add tabs to your paneled output, 
name each piece of output, separated by quotation marks, in the WEB_TABS= option. To prevent a tab from being 
displayed, use the name HIDE in the OPTIONS parameter. In Example 11, the first and third procedures display the 
tabs, while the tabs for the second and fourth procedures are hidden.  
Example 11 
goptions  hsize=5in vsize=5in cback=white; 
ods tagsets.tableeditor file="temp1.html" 
options(panelcols="2" 
web_tabs="Graph/Summary,Hide,Detail,Hide" 
pageheight="500") style=styles.sasweb; 
proc gchart data=sashelp.shoes; 
vbar3d region / sumvar=sales type=sum patternid=midpoint; 
title "Sales by Region"; 
run; 
quit; 
proc means data=sashelp.shoes; 
class region; 
var sales;run; 
ods tagsets.tableeditor options(panelcols="2"); 
proc gplot data=sashelp.shoes; 
plot region*sales; 
run; 
quit; 
proc print data=sashelp.shoes; 
title "Sales Detail by Region"; 
run; 
quit; 
ods tagsets.tableeditor close;
Applications Development
SAS Global Forum 2009
09
9
Documents you may be interested
Documents you may be interested