Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

How To Output RTF-formatted Documents with ASP : Page 3

HTML isn't your only choice for displaying content from ASP. Learn how to build a simple class to generate RTF documents and tables on the fly with basic text and paragraph formatting.


advertisement
Output to an RTF Table
So far, you've seen how to create basic RTF text markup and how to create a class to hold a library of 'atomic' formatting switches to help you produce a RTF-formatted documents in a simpler and less error-prone way. Unfortunately, none of this helps very much when it comes to outputting tables in RTF. RTF does not provide a table class; rather, RTF tables are a special type of paragraph. Unlike simpler formatting, such as bold and italic text, RTF has no equivalent to HTML's simple table, row, and cell formatting tags, such as <table>, <tr>, and <td>.

So, while it's possible to output tables in RTF, it quickly becomes complex to output tables with even a minimum of formatting. For example, to apply borders to a table in HTML, you do so in the initial <table> line. In RTF, borders must be applied at the paragraph level and each side of the border must be declared individually:

   \trbrdrt\brdrs\brdrw10 'top border
   \trbrdrl\brdrs\brdrw10 'left border
   \trbrdrb\brdrs\brdrw10 'bottom border
   \trbrdrr\brdrs\brdrw10 'right border
   \trbrdrh\brdrs\brdrw10 'horizontal border (inside)
   \trbrdrv\brdrs\brdrw10 'vertical border (inside)
The same thing applies to each cell in the row:

   \clbrdrt\brdrs\brdrw10
   \clbrdrl\brdrs\brdrw10
   \clbrdrb\brdrs\brdrw10
   \clbrdrr\brdrs\brdrw10
And you must write this formatting block for each cell in a row. Moreover, to maintain backward compatibility, good RTF markup for a table must specify the cell and paragraph formatting before and after the actual text stream dealing with the contents of the row/cell in question. Listing 1 shows how a standard, simple table generated from Word looks when saved as RTF markup. In contrast, Listing 2 shows a stripped-down, virtually unformatted two-row, three-column table generated using the simple RTF table markup shown in this article.

The RTF specifications contain a huge variety of table formatting options, including provisions for a header row, individual row and cell shading, nested cells and the like. While it's possible to create such complex tables using RTF output methods such as the ones shown here, my recommendation is to output a very plain unformatted table and apply formatting in Word or another RTF-capable editor if possible. Doing that frees you from coding for any specific format and gives you a clean output to work on later. If you use Word for the final product, you can also write macros to help you format the RTF table once it is generated. Unfortunately, that also either limits your ability to automatically create RTF output, or forces you to use Word automation anyway—which, as you've already seen, carries permission and performance problems as baggage.

Generating a Table in RTF
With these caveats in mind, here's the basic process for generating a table in RTF. This example provides a function that generates an RTF table from an ASP page, pulling the table data from a database using a SQL query. The generated table has a header row that lists the column names returned by the query and the table body displays all the returned records. To begin, here's the code for a basic, virtually unformatted two-row, three-column table in RTF:

   \trowd\trautofit1
   \intbl
   \cellx1
   \cellx2
   \cellx3
   {1 cell 1\cell 1 cell 2\cell 1 cell 3\cell }
   {\trowd\trautofit1
   \intbl
   \cellx1
   \cellx2
   \cellx3
   \row }
   \trowd\trautofit1
   \intbl
   \cellx1
   \cellx2
   \cellx3
   {2 cell 1\cell 2 cell 2\cell 2 cell 3\cell }
   {\trowd\trautofit1
   \intbl
   \cellx1
   \cellx2
   \cellx3
   \row }
Notice that the actual row with its contents is determined by the code block {1 cell 1\cell 1 cell 2\cell 1 cell 3\cell }. The initial table row is declared in \trowd. The second command, \trautofit1, is not technically necessary, but if you leave it out the output table will have the thinnest columns possible and may be very hard to even select, much less format. Following the \trowd is the line \intbl, which is a tag indicating that the following paragraph(s) are table paragraphs, not regular paragraphs. Next, there's a new RTF group with a reference \cellxn, where n is a unique number. There must be exactly the same number of \cellxn as there are \cell tags listed in the row output RTF group. Next, comes the RTF group for the actual cell contents and number of cells. Each \cell denotes a new cell/paragraph. The same reference to the cells in the row (a \cellxn for each cell) follows the code for the row/cell content. Finally, the \row closes the opening \trowd tag.

The second row begins with another \trowd, with the same code blocks as before. This code will produce a 2 x 3 table with no borders and with columns sized to fit the longest content in the cells in the column. If you paste the RTF table into Excel it behaves like a tab-separated file.

A function for producing an RTF table needs to know a few things: the number of cells per row in order to match \cellxn with the \cell arguments, and the header row information in order to define the column names for the data passed by the SQL query. The following function dynamically determines the column count and header names from a Recordset object retrieved from an Access database. It uses that information to write the header row and body of the table. SQL Server provides several mechanisms for reading column names; use whatever method you prefer. This article has a good discussion of reading column names in a query.

Public Sub RTF_BuildTable(myRS)
   
   ' Load NumCells variable to write table 
   ' row properties
   NumCells = myRs.Fields.Count
      
   ' load NumRows variable to set up table 
   ' contents loop for recordset
   NumRows = myRS.RecordCount
      
   ' populate header row
   MyFile.WriteLine "\trowd\trautofit1\intbl"
      
   j = 1
   For i = 1 To NumCells
      MyFile.WriteLine "\cellx" & j
      j = j + 1
   Next
      
   MyFile.WriteLine "{"
      
   ' loop thru and write the column name from the db
   For Each column In myRS.Fields
      MyFile.WriteLine column.name & "\cell "
   Next
      
   MyFile.WriteLine "}"
      
   MyFile.WriteLine "{"
   MyFile.WriteLine "\trowd\trautofit1\intbl"
      
   j = 1
   For i = 1 To NumCells
      MyFile.WriteLine "\cellx" & j
      j = j + 1
   Next
   MyFile.WriteLine "\row }"
      
   ' write table contents
   For k = 1 To NumRows
      MyFile.WriteLine "\trowd\trautofit1\intbl"
      j = 1
      For i = 1 To NumCells
         MyFile.WriteLine "\cellx" & j
         j = j + 1
      Next
      MyFile.WriteLine "{"
            
      For Each column In myRS.Fields
         MyFile.WriteLine column & "\cell "
      Next
            
      MyFile.WriteLine "}"
            
      MyFile.WriteLine "{"
      MyFile.WriteLine "\trowd\trautofit1\intbl"
      j = 1
      For i = 1 To NumCells
         MyFile.WriteLine "\cellx" & j
         j = j + 1
      Next
      MyFile.WriteLine "\row }"   
      myRS.MoveNext
   Next      
End Sub 
This code should be self-explanatory, especially if you refer to the 'bare-bones' RTF table structure in Listing 2. You can use this code as a function in your RTF markup library class or implement it on the ASP output page. Implementation is simple:

mySQL = "Select Field1, Field2, Field3 from Table;"
myRS.Open mySQL, DataConnection, _
   adOpenStatic, adCmdTable
      
If Not myRS.EOF Then
   p.RTF_BuildTable(myRS)
End If
You've seen how to create the basic building-blocks for using ASP to produce RTF files and to apply simple formatting to blocks of text. In addition, you should be able to produce clean and easy-to-format tables produced from Recordsets created by your favorite SQL-aware database. You are now ready to go forward and use ASP to produce reports and other output for distribution to any audience.

Depending on your needs, you can begin to compile a library of formatting functions internally in ASP and, if necessary, a library of macros in VBA/Word to select and apply more complex formatting to RTF tables. After running your ASP to RTF conversion code, to return the completed document, read the file, set the MIME type (the Response.Content type) to application/rtf and return the file contents. The client's browser will open the file in the appropriate application.



Steven Skelton is an administrative technician for the Health and Human Services Commission of the State of Texas. You can reach him .
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap