RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Nano-Sheets: A Small but Mighty Spreadsheet Engine in REBOL, Part 2

Building on Part 1 of this article, not only can you create a working spreadsheet in just a few bytes using REBOL, but you can extend it to support printing, standard keyboard navigation, macros containing code, and even make it shareable and dynamically updatable—while still using only a few bytes of code.

he first part of this article described how to build the Nano-Sheets spreadsheet engine, and then extended it by adding the following features:

  • Dynamic generation and sizing of cells
  • Automatic data types in cells
  • Formulas including REBOL code
  • Loading and saving spreadsheet files
This part extends Nano-Sheets even further.

Adding Pretty Printing
The basic Nano-Sheets engine doesn't supply users with a way to print the spreadsheet. This section of the article extends it by emitting HTML, so users can print from the browser. Of course, developers can also use the generated HTML for other purposes.

You create a context for this bit of code. A context in REBOL is basically an object, and is a handy way to create namespaces and group code.

The HTML-export context contains some boilerplate HTML, with replaceable tags where the specific values and generated data from the spreadsheet should go. The emit helper function makes the generation loop cleaner. The generation loop works very much like the one that built the UI; but it emits HTML rather than a REBOL VID layout. For testing purposes, the following code just writes the HTML to a file and opens the browser to display it. Note how the code uses REBOL's tag data type directly; you don't need to wrap tags in quoted strings. In REBOL, tags are a first class data type—a special type of string—so REBOL functions that work on strings generally also work on tags.

   ctx-html-export: context [
       out-buff: make string! 10'000
   html-template: {
   <!--Page generated by Nano-Sheets-->
   <style type="text/css">
   html, body, p, td, li {font-family: arial, sans-serif, 
      helvetica; font-size: 10pt;}
   table, tr {border-collapse: collapse;}
   th, td {font-size: 12px; border: 1px solid #C0C0C0; 
      padding: 0.5em 0.5em 0;}
   th {background: #8E806E; font-weight: bold; 
      text-align: center; color: #404040;}
   <body bgcolor="white">
   emit: func [data] [repend out-buff 
      [reduce data newline]]
   set 'emit-html func [/to file /local val] [
       clear out-buff
       emit <table>
       repeat row 1 + sheet-size/y [
           emit [<tr><th> either 1 = 
              row [""] [form row - 1]</th>]
           repeat col sheet-size/x [
              emit either 1 = row 
              [[<th> col-lbl col </th>]] [
                   [<td width="110"> any 
                   [get/any mk-var col row - 1 ""] </td>]
           emit </tr>
       emit </table>
       out-buff: replace copy html-template 
          "$table" out-buff
       write %rebolcalc-out.html out-buff browse 

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date