56
1
Paper SAS1880-2015
Staying Relevant in a Competitive World: Using the SAS
®
Output Delivery
System to Enhance, Customize, and Render Reports
Chevell Parker, SAS Institute Inc.
ABSTRACT
Technology is always changing. To succeed in this ever-evolving landscape, organizations must embrace
the change and look for ways to use it to their advantage. Even standard business tasks such as creating
reports are affected by the rapid pace of technology. Reports are key to organizations and their
customers. Therefore, it is imperative that organizations employ current technology to provide data in
customized and meaningful reports across a variety of media. The SAS
®
Output Delivery System (ODS)
gives you that edge by providing tools that enable you to package, present, and deliver report data in
more meaningful ways, across the most popular desktop and mobile devices.
To begin, the paper illustrates how to modify styles in your reports using the ODS CSS style engine,
which incorporates the use of cascading style sheets (CSS) and the ODS document object model (DOM).
You also learn how you can use ODS to customize and generate reports in the body of email messages.
Then the paper discusses methods for enhancing reports and rendering them in desktop and mobile
browsers by using the HTML and HTML5 ODS destinations. To conclude, the paper demonstrates the
use of selected SAS ODS destinations and features in practical, real-world applications.
INTRODUCTION
As times change, you can no longer depend on methods and techniques that were used to report and
analyze data in the past. Today's customers expect more than ever before. To stay business relevant,
especially in the area of business reports, you must use the latest reporting methods and techniques. If
you are a SAS
®
software user, you are in a great position to meet those ever-changing customer needs.
Gone are the days when a single-listing report works as a medium for all of your customers. That would
be like awakening after 20 years and looking for a phone booth or looking for your report on green-bar
computer paper! Staying business relevant requires ways of delivering and reporting information that
most benefit your customers.
This paper discusses the following methods for delivering and reporting your information in order to
maintain business relevancy:
customizing reports with cascading style sheets (CSSs)
delivering formatted reports through email
enhancing and rendering reports with HTML and HTML5
using the new SAS
®
9.4 features with the ODS Excel destination in practical applications
CUSTOMIZING REPORTS USING CASCADING STYLE SHEETS
Cascading style sheets (CSS) are an industry standard that are used to define the visual presentation for
web pages. However, CSS is not just for web pages anymore! Now, you can use a CSS also to define the
presentation of Adobe PDF files, Microsoft Excel worksheets, and RTF, and E-books. Creating styles with
a CSS enables you to generate styles that can be applied globally in your reports, and this method is a
worthy alternative to using the TEMPLATE procedure. The use of the CSSSTYLE= option and the ODS
HTML destination's STYLESHEET= option should not be confused. The STYLESHEET= option, in
combination with the URL= suboption in the HTML statement, simply passes the CSS style to the browser
for rendering. On the other hand, when you use the CSSSTYLE= option, the CSS style is mapped to the
PROC TEMPLATE elements and attributes.
58
2
Advantages of using a CSS for styles include the following:
A CSS provides more dynamic styling capabilities than PROC TEMPLATE.
CSS files offer greater portability because they are simply text files.
Style properties that are used with ODS CSS styles are based on the W3C standard.
Familiarity with CSS only requires a minimal learning curve.
The initial implementation of the CSS style engine in SAS
®
9.2 was limited to using class selectors for
targeting elements. This implementation simply converts the CSS class names to PROC TEMPLATE
style elements and the CSS style properties to PROC TEMPLATE attributes. It also includes the ability to
use the @Media rules, which enable you to set media types differently based on the output. Later, the
CSS style engine was extended to include type or element selectors. In addition, the engine's capability
was extended even further in SAS 9.4 to include several advanced methods of targeting elements (for
example, using attribute and pseudo-class selectors), which are discussed later in this section. The
complete feature set for the CSS style engine cannot be covered adequately in this paper. For a more
detailed discussion of the features, see Smith (2013).
CASCADING STYLE SHEETS: THE BASICS
The anatomy of a CSS file includes one or more individual CSS rules that consist of selectors, properties,
and values. The selector instructs the client about which elements should be matched when you generate
styles. A property defines either how the style should look or its behavior, while a value is the argument
that is passed.
The following example illustrates a basic rule that consists of a selector, two properties, and two values.
Selector {
property1: value1;
property2: value2;
}
As shown above, the properties and values are enclosed in braces, with the property and its respective
value separated by a colon.
THE ODS DOCUMENT OBJECT MODEL
It is easy to build the CSS that you need in order to add a style for HTML output because the HTML
markup is visible. Before targeting various elements with selectors, you must first understand the ODS
document object model (DOM), which is based on an HTML5 document tree and which enables you to
target elements. The ODS DOM is similar to the HTML version of the document object model in some
ways. However, the HTML DOM is an in-memory version of the HTML document. In SAS 9.4, you display
the ODS DOM either by adding the DOM option in the specific ODS destination or by using the ODS
TRACE DOM system option. Displaying the ODS DOM is necessary, initially, in order to view the
elements that are available to be targeted by selectors. The process for displaying the DOM is explained
in the next example. After you follow this process a few times, it becomes pretty familiar.
The following example code uses the DOM option in the ODS Excel destination (pre-production in SAS
9.4 TS1M1) to write the object model to the log. (Note: The ODS Excel destination is new in the first
maintenance release of SAS 9.4 [TS1M1]. It is planned that the destination will be a production feature in
SAS 9.4 TS1M3.)
ods excel file="c:\temp.xlsx" options(embedded_titles="yes"
sheet_name="Class_Selectors"
start_at="B2")
cssstyle="c:\class.css" dom;
proc print data=sashelp.orsales(obs=10) noobs;
var Year Product_group quantity Profit;
format profit dollar.;
sum quantity profit;
title 'Profit Summary for Company ABC';
run;
ods excel close;
45
3
The information that is written to the log by this code is verbose, so only an abbreviated portion of the
PRINT procedure output is shown below:
<!DOCTYPE html>
<html>
<body class="body">
<section id="idx" class="oo" proc="print">
<table class="systitleandfootercontainer">
<tr>
<td class="systemtitle">Profit Summary for Company
ABC</td>
</tr>
</table>
<table class="table">
<thead>
<tr>
<th class="header" type="char" index="1"
name="year" >Year</th>
</tr>
</thead>
<tbody>
<tr>
<td class="data" type="num" index="1" name="year" >1999
</td>
</tr>
</tbody>
</table>
</section>
</body>
</html>
CASCADING STYLE SHEET SELECTORS
Pattern-matching rules are called selectors in CSS. Selectors determine which CSS rules apply to
elements, making them one of the most important aspects of CSS. Selectors can range from very simple
(for example, class and element selectors) to very advanced (for example, the pseudo-class and attribute
selectors that are discussed later in this paper). Advanced selectors offer more flexibility, and with them,
you can match almost every element or parts or the output.
The next sections discuss both basic and advanced selectors, and the sections use examples to illustrate
how to apply these selectors to Microsoft Excel worksheets from within SAS.
Basic Selectors
This section discusses four types of basic selectors: class, element (type), ID, and universal. These
selectors are the ones used most often in modifying the style of your output.
Worksheet Body
Title
Table Header
Table Cell
51
4
CSS Class Selectors
The class selector selects elements that are based on a specific class attribute. This type of selector is
always preceded by a period. For example, the following code, which is from the ODS DOM, uses four
class selectors (.BODY, .SYSTEMTITLE, .HEADER, and .DATA) to modify Excel output:
.body {
background:white;
font-family:arial;
}
.systemtitle {
font-weight:bold;
font-size:12pt;
font-family:arial;
}
.header {
background-color:teal;
color:beige;
font-family:arial;
border:1px solid
black;
}
.data {
border:1px solid black;
font-family:arial;
background-color:beige;
}
This example illustrates how you can target various elements using class selectors. The class
selectors equate to (match) style element names in SAS.
In This Example:
The .BODY class modifies the style of the worksheet body.
The .SYSTEMTITLE class modifies the style of the worksheet title.
The .HEADER and .DATA classes modify, respectively, the table headers and the table definition
cells.
Adding class selectors to a file and referencing that file in the CSSSTYLE= option generates the output
that is shown above in Output 1.
CSS Element (Type) Selectors
An element (or type) selector matches every element that is referred to in the ODS DOM with the
corresponding element type name. The next example uses element (type) selectors to match the various
parts of output that were modified with class selectors in the previous code example.
body {background-color:beige}
td.systemtitle {
font-weight:bold;
font-size:12pt;
border-bottom:none;
}
(code continued)
Output 1. Class Selectors Applied to a Microsoft Excel
Worksheet
51
5
th {
background-color:brown;
color:beige;
font-weight:bold
font-family:arial;
border-bottom:1px solid
black;
}
td {
border-bottom:1px solid black;
font-family:arial;
font-weight:medium;
font-size:9pt;
}
In This Example:
The Body element selector modifies the background color of the worksheet.
Both the worksheet title and the data values use the TD element selector. Therefore, the selector
for the title also includes the class name .systemtitle to further identify that the title should be
targeted. Because of the way a CSS works, the styles that are listed in the .systemtitle class
override any styles that appear later in the CSS.
The TD selector modifies the data values.
The TH element selector modifies the table headers.
CSS ID Selectors
An ID selector matches elements that have specific ID attribute values. An ID selector begins with a
number sign (#), and the default ID value is IDX. Because the ID attribute must have a unique value, an
ID selector can never match more than one element in the document. For example, if you have the
default ID selector (#IDX) for one element, you must use a different ID selector (for example, #IDX1) for
another element.
The following example demonstrates how you can use an ID selector to apply a style that modifies the
font size of cells only in the first table in a worksheet:
<section id="idx" class="oo" proc="procprint"> /*Element from the DOM */
#IDX .data {
font-size:8pt;
}
In This Example:
To apply the new font size to the first table only, you add the ID for the first section (#IDX .data).
Note: You can modify the default ID by using the ANCHOR= option in the ODS destination.
CSS Universal Selectors
A universal selector is a wildcard that matches every element. You indicate the universal selector by
adding an asterisk (*). The example below generates text in Arial font for all of the elements in the
document.
* {
font-family:arial;
}
Output 2. ApplyingType Selectors in Microsoft Excel Output
t
61
6
ADVANCED CSS SELECTORS
Starting with SAS 9.4, ODS supports many advanced selectors that enable you to target, conceivably,
every element. This section discusses some of the advanced selectors such as pseudo-class selectors,
attribute selectors, adjacent selectors, and more.
Pseudo-Class Selectors
Pseudo-class selectors enable you to select elements according to their position relative to other
elements. These selector names all begin with a colon. Two examples of pseudo-class selectors are
:nth-child(N) and :nth-of-type(N). These two selectors provide dynamic styling capabilities. The
nth-child selector enables you to match an element that is the nth child, regardless of its element type
.
The argument (N) within these two pseudo-class selectors can be a keyword, a number, or an expression
of the form an+b.
The following sections describe three types of values (keywords, numbers, and expressions) that N can
take in a pseudo-class selector.
Keywords
The pseudo-class selector :nth-child(N)can take the keyword values where N has a value of odd for
selecting odd-numbered elements and a value of even for even-numbered elements. You can use these
keywords as a convenient way to highlight odd and even rows in table, making them easier to read in the
output. . For example, the following CSS code modifies the background color for even (red) and odd
(green) rows in the table:
table tbody tr:nth-child(even) td {
background-color:red;
}
table tbody tr:nth-child(odd) td {
background-color:green;
}
Numbers
The argument (N) can also take a number value that represents the position for the selected element. For
example, the following code uses the :nth-child pseudo-class selector to specify a red background for
row 5 of a table:
table tbody tr:nth-child(5) td {
background-color:red;
}
Expressions
The argument (N) can also be represented as (an+b), where a and b are integers that identify the number
of occurrences and where b is the first occurrence. For example, the expression (3n+1) indicates that the
action starts with the first element and then jumps to every third element in the sequence (in this case,
1,4,7,10, and so on). The expression (2n) is equivalent to using the keyword even, indicating that the
code should select every second element. The expression (4n+2) matches the second element and then
every fourth element (2, 6, 10, and so on).
Additional Pseudo-Class Selectors
There are several other pseudo-class selectors that you can specify, as shown in the list below.
:root
:first-child
:first-of-type
:nth-child
:nth-of-type
:empty
:before
:after
:not
42
7
The :first-child selector, for example, enables you to select the first element from a parent element.
Note: The list above is not the complete list of available pseudo-class selectors. ODS does not load the
entire document into memory. Therefore, certain pseudo-class selectors such as :last-child do not
appear in the list above.
The following example applies six style options to a table in the Excel ribbon that is duplicated using a
CSS with the ODS Excel destination. The six style options that will be applied are shown in the following
display in the Table Style Options section of an Excel spreadsheet:
Display 1. Modified Table in the Microsoft Excel Style Ribbon
Example Code
/* This statement modifies the font for all of the output. */
* th, td {font-family:arial;}
/* This segment targets all th elements within the first */
/* child of the tr element that are descendants of */
/* thead and table. */
table thead tr:first-child th {
background-color:royalblue;
color:white;
border:2px solid black;
}
/* Targets all td elements within even-numbered tr elements */
/* (rows) that are descendants of tbody and table. */
table tbody tr:nth-child(even) td {
background-color:lightblue;
border:2px solid black;
}
/* Targets the 3rd and 4
th
th element that are descendants of */
/* tbody and table. . */
table tbody th:nth-of-type(3), th:nth-of-type(4) {
background-color:yellow;
color:green;
border:2px double black;
}
/* Targets the td element in the 4th position (column) that */
/* is a descendants of tbody and table. */
table tbody td:nth-child(4) {
background-color:pink;
border:2px solid black;
}
(code continued)
23
8
/* Targets the first td element (column) and every other td */
/* element thereafter that are descendants of tbody and table. */
table tbody td:nth-child(2n-1){
background-color:orange;
border:2px solid black;
}
Display 2 shows the output from this example displayed in a mobile device.
Display 2. Applying Elements to a Table with Pseudo-Class Selectors
ATTRIBUTE SELECTORS AND COMBINATORS
With attribute selectors, you can target elements based on their attributes and the attribute values. For
example, consider the following record from the ODS DOM:
<th class="header" type="char" index="1" name="obs">Obs</th>
/* Targets th elements with index attributes. These elements */
/* are descendants of thead and table.
*/
table thead th[index] {
background-color:brown;
font-weight:bold;
color:beige;
border:1px solid black;
}
(code continued)
59
9
/* Targets th elements that have the attributes and values
*/
/* NAME="QUANTITY"and NAME="PROFIT". These elements
*/
/* are descendants of thead and table.
*/
table thead th[name="quantity"],
table thead th[name="profit"]
background-color:green;
font-weight:bold;
color:beige;
border:1px solid black;
}
/* Targets td elements with an attribute and value of */
/* LABEL='YEAR'. These elements are descendants of tbody */
/* and table. */
table tbody td[label="year"] {
background-color:orange;
}
/* Targets td elements that have an attribute and value of */
/* TYPE="CHAR". These elements are descendants of tbody and
*/
/* table.
*/
table tbody td[type="char"] {
background:beige;
}
/* Targets td elements that have an attribute and value */
/* INDEX="4". These elements are descendants of thead */
/* and table. */
table tbody td[index="4"] {
background:yellow;
font-weight=bold;
}
/* Targets th elements with the following attributes and */
/* values: NAME="QUANTITY" and NAME="PROFIT". These elements */
/* are descendants of tbody. */
table tbody th[name="quantity"],
table tbody th[name="profit"] {
background-color:lightgreen;
border-top:5pt solid red;
font-weight:bold;
}
/* This section uses an adjacent selector (td+td) to target td */
/* elements that are not the first element that are descendants */
/* of tbody and table. */
table tbody td+td {
color:darkblue;
background-color:lightblue;
}
In This Example:
In Output 4, you can see the various attributes that are added based on the color code.
The NAME= attribute enables you to apply a color to the column name.
The INDEX= attribute enables you to specify the position or column.
The TYPE= attribute enables you to add a color based on the data type.
40
10
Output 3 shows the output that is created by this example code displayed in the Apple iPad.
Output 3. Worksheet That Is Generated from Using Attribute Selectors
There are many other attributes that you can use, but this example is scaled down for demonstration
purposes. You can also use various sibling combinators (such as adjacent, general, and sibling selectors)
that are based on their positions relative to the other elements in the document tree.
ENHANCING FORMATTED REPORTS IN THE BODY OF AN EMAIL
In the business world, staying relevant also requires that you are one step ahead of what is happening
today. For example, some customers might view reports on a desktop machine while others use a mobile
device such as an Apple iPhone or iPad. Therefore, you must analyze your customers' needs in order to
determine the best medium of delivery for reports. As demonstrated by the examples in the previous
section, the ODS Excel destination is flexible enough to enable you to create reports for any medium. In
particular, email is a medium that you should consider for a quick and efficient way to review reports
because it is efficient for users of both mobile and desktop devices.
You can target delivery of reports through email on mobile devices, desktop computers, and web clients.
According to Litmus Analytics, the iPhone leads the market share overall with respect to email users on
the mobile platform.
1
Microsoft Outlook is the industry leader when it comes to desktop email, and Google
Gmail has the lead share for web email. This section discusses techniques for presenting highly
formatted (SMTP) reports across these various email platforms. The discussion centers on including
reports in the body of an email message using the under-utilized EMAIL access method in the SAS
FILENAME statement.
USING A FILENAME STATEMENT AND A ROUTING METHOD TO INCLUDE FORMATTED OUTPUT
IN AN EMAIL MESSAGE
To send formatted output to the body of an email, you need a FILENAME statement that includes the
EMAIL access method and a method of routing the formatted output (HTML) to your email device. The
routing method can be a DATA step or one of the ODS destinations that are used to generate HTML. The
following example shows a basic SAS program that uses the HTML destination to send email.
options emailsys=SMTP emailhost=your-mail-host;
filename temp email to="recipient-email-address"
content_type="text/html"
from="sender-email-address";
(code continued)
1
Beechler, Drew. 2015. "Top Trends from 2014's Email Client Market Share."
Blog. Salesforce Blog.
Available at
blogs.salesforce.com/company/2015/02/top-trends-from-2014s-email-client-market-
share.html. Last viewed March 30, 2015.
Documents you may be interested
Documents you may be interested