Output Delivery System - Part 01: ODS Basics, Destinations, and Output Control
What Is ODS?
The Output Delivery System (ODS) is the part of SAS that controls how procedure output is rendered and delivered.
Before ODS, SAS procedure output was plain text sent to the listing output window. ODS allows the same procedure output to be sent simultaneously to multiple formats: PDF, RTF, Excel, HTML, and more.
ODS works by intercepting the output objects that each PROC produces and formatting them according to the specified destination.
ODS is always active — even when you are not using it explicitly, the default destination (ODS LISTING) is open and capturing plain text output.
ODS Destinations
An ODS destination is a target format or location where procedure output is sent. Multiple destinations can be open at the same time.
Common destinations: LISTING (plain text, the default), HTML (browser-ready HTML files), PDF (Adobe Acrobat format), RTF (Word-compatible rich text), EXCEL (Excel workbook via ODS), and GRAPHICS (for graphical output objects).
Each destination is opened with ODS destination-name ... ; and closed with ODS destination-name CLOSE; When you close a destination, SAS finalises the output file.
ODS CLOSE ALL; closes all open destinations at once — a useful cleanup statement at the end of a program.
Sending Output to a PDF File
ODS PDF opens a PDF destination that captures all subsequent PROC output into a PDF file.
The FILE= option specifies the path and filename of the PDF to create.
All procedure steps between ODS PDF and ODS PDF CLOSE contribute pages to that PDF file.
STYLE= controls the visual appearance. PDFTOC= controls the PDF table of contents depth.
SAS Log
The ODS PDF block is commented out to avoid errors if the output path does not exist — uncomment it and update the path to run it.
STYLE=JOURNAL applies a clean academic-style visual theme. Other common styles include LISTING, STATISTICAL, DEFAULT, and MEADOW.
TITLE sets a title that appears above each table in the output. TITLE; (with no text) clears the title after the procedure.
After running, open the PDF to confirm the PROC MEANS table appears with the expected treatment groups and statistics.
Sending Output to an RTF File
ODS RTF produces a Rich Text Format file that opens in Microsoft Word and is editable.
RTF is commonly used when clinical tables need to be delivered in Word format for medical writing teams.
BODYTITLE suppresses automatic column headers in the RTF body and allows the TITLE statement to serve as the table title.
SAS Log
STYLE=RTF is a Word-optimised style — it produces clean output that converts well when pasted into Word documents.
NOOBS removes the observation number column from PROC PRINT output — standard in delivery-quality tables.
LABEL causes variable labels to appear as column headings instead of variable names — always use this when delivering output to non-programmers.
Sending Output to Excel
ODS EXCEL produces a Microsoft Excel workbook (.xlsx). Each PROC step creates a new sheet in the workbook by default.
The SHEET_NAME= option in PROC options or via ODS EXCEL options controls the tab name for each sheet.
ODS EXCEL is available in SAS 9.4 maintenance release 3 and later. For earlier versions, use ODS TAGSETS.EXCELXP as the alternative.
SAS Log
The first ODS EXCEL statement opens the workbook and creates the first sheet named "Results".
The second ODS EXCEL OPTIONS(SHEET_NAME=...) mid-stream changes the sheet name for the next procedure's output without closing and reopening the workbook.
EMBEDDED_TITLES="yes" places the TITLE text inside the Excel cells rather than in a separate header area.
After running, open the Excel file to confirm two sheets were created with the expected content on each tab.
ODS SELECT and EXCLUDE - Controlling Which Output Objects Appear
Many PROC steps produce multiple output objects (tables). ODS SELECT and ODS EXCLUDE control which specific objects are sent to the destination.
ODS SELECT object-name; tells SAS to include only that named object and discard everything else from the next PROC step.
ODS EXCLUDE object-name; tells SAS to discard that object and send everything else.
Use PROC CONTENTS or run the PROC once with ODS TRACE ON to discover the names of output objects.
SAS Log
ODS TRACE ON writes a line to the log for every output object produced, showing its name and label. Run a PROC with TRACE ON to discover the object names before using SELECT.
ODS SELECT SUMMARY tells SAS to send only the object named "Summary" to the output destination for the next PROC step.
ODS SELECT ALL resets the selection — all output objects are sent again for subsequent PROCs. Always reset after using ODS SELECT to avoid accidentally suppressing output in later steps.
Check the SAS output and log: with ODS SELECT SUMMARY, only the statistics table should appear, not any other tables PROC MEANS might produce.
Closing All Destinations at Session End
It is good practice to close all ODS destinations explicitly at the end of a program.
ODS _ALL_ CLOSE; closes every open destination, finalising all output files. This ensures no files are left open or incomplete.
After ODS _ALL_ CLOSE, the default LISTING destination is also closed. Re-open it with ODS LISTING; if you want subsequent PROC output to appear in the output window again.
SAS Log
Include these two lines at the end of any program that uses ODS destinations, as a cleanup step.
Without ODS LISTING; after ODS _ALL_ CLOSE, subsequent PROC output will not appear anywhere — useful if you want to suppress all output, but a common source of confusion if accidentally left in place.
Key Points
ODS routes procedure output to one or more destinations simultaneously — PDF, RTF, EXCEL, HTML, and LISTING are the most commonly used.
Open a destination with ODS destination FILE=...; and close it with ODS destination CLOSE; — closing finalises the output file.
Multiple destinations can be open at the same time; all open destinations receive every output object until closed.
ODS SELECT object-name; restricts output to a specific named object from the next PROC step — always follow with ODS SELECT ALL; to restore normal output.
Use ODS TRACE ON to discover the names of output objects produced by any PROC step, then use those names with ODS SELECT or ODS EXCLUDE.
End every ODS program with ODS _ALL_ CLOSE; followed by ODS LISTING; to clean up all open destinations and restore default output behaviour.