\documentclass[a4paper]{book} \usepackage{fullpage} \usepackage{fancyvrb} \usepackage{color} \usepackage[ascii]{inputenc} \usepackage{hyperref} \usepackage[pdftex]{graphicx} \usepackage{wrapfig} \usepackage{multicol} \newcommand\PYZat{@} \newcommand\PYZlb{[} \newcommand\PYZrb{]} \newcommand\PYbh[1]{\textcolor[rgb]{0.00,0.50,0.00}{\textbf{#1}}} \newcommand\PYbg[1]{\textcolor[rgb]{0.73,0.40,0.53}{\textbf{#1}}} \newcommand\PYbf[1]{\textcolor[rgb]{0.82,0.25,0.23}{\textbf{#1}}} \newcommand\PYbe[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}} \newcommand\PYbd[1]{\textcolor[rgb]{0.73,0.13,0.13}{#1}} \newcommand\PYbc[1]{\textcolor[rgb]{0.00,0.50,0.00}{\textbf{#1}}} \newcommand\PYbb[1]{\textcolor[rgb]{0.00,0.50,0.00}{#1}} \newcommand\PYba[1]{\textcolor[rgb]{0.00,0.00,0.50}{\textbf{#1}}} \newcommand\PYaJ[1]{\textcolor[rgb]{0.69,0.00,0.25}{#1}} \newcommand\PYaK[1]{\textcolor[rgb]{0.73,0.13,0.13}{#1}} \newcommand\PYaH[1]{\textcolor[rgb]{0.50,0.00,0.50}{\textbf{#1}}} \newcommand\PYaI[1]{\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{#1}} \newcommand\PYaN[1]{\textcolor[rgb]{0.74,0.48,0.00}{#1}} \newcommand\PYaO[1]{\textcolor[rgb]{0.00,0.00,1.00}{\textbf{#1}}} \newcommand\PYaL[1]{\textcolor[rgb]{0.00,0.00,1.00}{#1}} \newcommand\PYaM[1]{\textcolor[rgb]{0.73,0.73,0.73}{#1}} \newcommand\PYaB[1]{\textcolor[rgb]{0.73,0.13,0.13}{#1}} \newcommand\PYaC[1]{\textcolor[rgb]{0.67,0.13,1.00}{#1}} \newcommand\PYaA[1]{\textcolor[rgb]{0.00,0.50,0.00}{#1}} \newcommand\PYaF[1]{\textcolor[rgb]{0.63,0.00,0.00}{#1}} \newcommand\PYaG[1]{\textcolor[rgb]{1.00,0.00,0.00}{#1}} \newcommand\PYaD[1]{\textcolor[rgb]{0.00,0.50,0.00}{\textbf{#1}}} \newcommand\PYaE[1]{\textcolor[rgb]{0.25,0.50,0.50}{\textit{#1}}} \newcommand\PYaZ[1]{\textcolor[rgb]{0.00,0.50,0.00}{\textbf{#1}}} \newcommand\PYaX[1]{\textcolor[rgb]{0.00,0.50,0.00}{#1}} \newcommand\PYaY[1]{\textcolor[rgb]{0.73,0.13,0.13}{#1}} \newcommand\PYaR[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}} \newcommand\PYaS[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}} \newcommand\PYaP[1]{\textcolor[rgb]{0.00,0.00,0.50}{\textbf{#1}}} \newcommand\PYaQ[1]{\textcolor[rgb]{0.49,0.56,0.16}{#1}} \newcommand\PYaV[1]{\textcolor[rgb]{0.00,0.00,1.00}{\textbf{#1}}} \newcommand\PYaW[1]{\textcolor[rgb]{0.73,0.13,0.13}{#1}} \newcommand\PYaT[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}} \newcommand\PYaU[1]{\textcolor[rgb]{0.25,0.50,0.50}{\textit{#1}}} \newcommand\PYaj[1]{\textcolor[rgb]{0.00,0.50,0.00}{#1}} \newcommand\PYak[1]{\textcolor[rgb]{0.73,0.40,0.53}{#1}} \newcommand\PYah[1]{\textcolor[rgb]{0.63,0.63,0.00}{#1}} \newcommand\PYai[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}} \newcommand\PYan[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}} \newcommand\PYao[1]{\textcolor[rgb]{0.73,0.40,0.13}{\textbf{#1}}} \newcommand\PYal[1]{\textcolor[rgb]{0.25,0.50,0.50}{\textit{#1}}} \newcommand\PYam[1]{\textbf{#1}} \newcommand\PYab[1]{\textit{#1}} \newcommand\PYac[1]{\textcolor[rgb]{0.73,0.13,0.13}{#1}} \newcommand\PYaa[1]{\textcolor[rgb]{0.50,0.50,0.50}{#1}} \newcommand\PYaf[1]{\textcolor[rgb]{0.25,0.50,0.50}{\textit{#1}}} \newcommand\PYag[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}} \newcommand\PYad[1]{\textcolor[rgb]{0.00,0.25,0.82}{#1}} \newcommand\PYae[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}} \newcommand\PYaz[1]{\textcolor[rgb]{0.00,0.63,0.00}{#1}} \newcommand\PYax[1]{\textcolor[rgb]{0.60,0.60,0.60}{\textbf{#1}}} \newcommand\PYay[1]{\textcolor[rgb]{0.00,0.50,0.00}{\textbf{#1}}} \newcommand\PYar[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}} \newcommand\PYas[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{#1}}} \newcommand\PYap[1]{\textcolor[rgb]{0.00,0.50,0.00}{\textbf{#1}}} \newcommand\PYaq[1]{\textcolor[rgb]{0.53,0.00,0.00}{#1}} \newcommand\PYav[1]{\textcolor[rgb]{0.67,0.13,1.00}{\textbf{#1}}} \newcommand\PYaw[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}} \newcommand\PYat[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}} \newcommand\PYau[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}} \title{Surpass Manual} \author{Ana Nelson} \begin{document} \maketitle \tableofcontents To compile this documentation requires \LaTeX and the gems Gorgyrella and Webby. This documentation refers to Surpass version 0.0.5. \chapter{Installation and Hello World} % (fold) \label{cha:installation_and_hello_world} \section{Dependencies} % (fold) \label{sec:dependencies} Surpass only needs basic Ruby. It has been tested using Ruby 1.8.6 and JRuby 1.1.5. For development, you will want to have access to something that can open Microsoft Excel files. This could be Microsoft Excel, Open Office, Google Docs or even a gmail account. % section dependencies (end) \section{Gem Installation} \begin{verbatim} sudo gem install surpass \end{verbatim} \section{Source Installation} \begin{verbatim} bzr branch http://ananelson.com/code/surpass cd surpass sudo rake gem:install \end{verbatim} \section{Hello World} Let's do a minimal "Hello World" script. We'll need to take care of any imports, initialize a Workbook object, create a Worksheet within the workbook, then write some text. Here's how. \subsection{Surpass} \begin{Verbatim}[commandchars=@\[\]] @PYaX[require] @PYbd['rubygems'] @PYaX[require] @PYbd['surpass'] book @PYbe[=] @PYaq[Workbook]@PYbe[.]new sheet @PYbe[=] book@PYbe[.]add_sheet sheet@PYbe[.]write(@PYag[0], @PYag[0], @PYaW["]@PYaW[Hello World!]@PYaW["]) book@PYbe[.]save(@PYaW["]@PYaW[content/examples/hello-world.xls]@PYaW["]) \end{Verbatim} \subsection{Result} And, here's how it looks. \includegraphics[width=15cm]{examples/hello-world.png} % chapter installation_and_hello_world (end) \chapter{Writing Data} % (fold) \label{cha:writing_data} \section{write} % (fold) \label{sec:write} The basic method for writing data to cells is the worksheet's write method. \begin{Verbatim}[commandchars=@\[\]] @PYay[def] @PYaL[write](r, c, label @PYbe[=] @PYaW["]@PYaW["], style @PYbe[=] @PYaj[nil]) row(r)@PYbe[.]write(c, label, style) @PYay[end] \end{Verbatim} There are two required arguments, the row and column. These are zero-based indexes for the row and column. To write to the first cell in the spreadsheet, you would pass 0, 0. The next argument is the label, this is the value you want written in the cell. This defaults to an empty string (for no particular reason). You can write nil, a String, a Boolean, a Numeric or a Date format. If you pass an object belonging to an unsupported class, you will get an error message, and in this case you should call some method on your object which will return a String or whatever the appropriate label is. The fourth argument is for style, which should be either nil, true, a hash or an instance of the StyleFormat class. See the chapter on Formatting for more information. The style parameter defaults to nil, which means that the default Excel format will be applied. \section{Writing Arrays of Data} % (fold) \label{sec:writing_arrays_of_data} Frequently, you may want to write more than one value at a time, and so Surpass has convenience methods which handle arrays for you. In the background, these are just looping over the array and calling write() for each value you pass. There's no magic here and, for now at least, no clever optimization. The available methods are write\_array\_to\_row, write\_array\_to\_column, and write\_arrays. The write\_arrays method expects an array of arrays, the first two expect a single array. \begin{Verbatim}[commandchars=@\[\]] @PYay[def] @PYaL[write_array_to_row](array, r, c @PYbe[=] @PYag[0], style @PYbe[=] @PYaj[true]) array@PYbe[.]each_with_index @PYay[do] @PYbe[|]a, i@PYbe[|] row(r)@PYbe[.]write(c @PYbe[+] i, a, style) @PYay[end] @PYay[end] @PYay[def] @PYaL[write_array_to_column](array, c, r @PYbe[=] @PYag[0], style @PYbe[=] @PYaj[true]) array@PYbe[.]each_with_index @PYay[do] @PYbe[|]a, i@PYbe[|] row(r @PYbe[+] i)@PYbe[.]write(c, a, style) @PYay[end] @PYay[end] @PYay[def] @PYaL[write_arrays](r, c, array_of_arrays, style @PYbe[=] @PYaj[true]) array_of_arrays@PYbe[.]each_with_index @PYay[do] @PYbe[|]a, i@PYbe[|] @PYay[raise] @PYaW["]@PYaW[not an array of arrays!]@PYaW["] @PYay[unless] a@PYbe[.]is_a?(@PYaX[Array]) write_array_to_row(a, r @PYbe[+] i, c, style) @PYay[end] @PYay[end] \end{Verbatim} % section writing_arrays_of_data (end) % section write (end) \section{Autoformatting} % (fold) \label{sec:autoformatting} Autoformats are number formats which are automatically applied to Dates, Floats and similar classes. To have autoformats applied, then pass true as the style parameter to the write function. Here is the relevant code from row.rb: \begin{Verbatim}[commandchars=@\[\]] @PYay[when] @PYaq[TrueClass] @PYaf[# Automatically apply a nice numeric format.] @PYay[case] label @PYay[when] @PYaq[DateTime], @PYaq[Time] style @PYbe[=] @PYaS[@PYZat[]parent_wb]@PYbe[.]styles@PYbe[.]default_datetime_style @PYay[when] @PYaq[Date] style @PYbe[=] @PYaS[@PYZat[]parent_wb]@PYbe[.]styles@PYbe[.]default_date_style @PYay[when] @PYaX[Float] style @PYbe[=] @PYaS[@PYZat[]parent_wb]@PYbe[.]styles@PYbe[.]default_float_style @PYay[else] style @PYbe[=] @PYaS[@PYZat[]parent_wb]@PYbe[.]styles@PYbe[.]default_style @PYay[end] \end{Verbatim} And here are the default formats being defined in style.rb: \begin{Verbatim}[commandchars=@\[\]] @PYay[def] @PYaL[default_date_style] @PYaS[@PYZat[]default_date_style] @PYbe[||]@PYbe[=] @PYaq[StyleFormat]@PYbe[.]new(@PYau[:number_format_string] @PYbe[=]@PYbe[>] @PYbd['dd-mmm-yyyy']) @PYay[end] @PYay[def] @PYaL[default_datetime_style] @PYaS[@PYZat[]default_datetime_style] @PYbe[||]@PYbe[=] @PYaq[StyleFormat]@PYbe[.]new(@PYau[:number_format_string] @PYbe[=]@PYbe[>] @PYbd['dd-mmm-yyyy hh:mm:ss']) @PYay[end] @PYay[def] @PYaL[default_float_style] @PYaS[@PYZat[]default_float_style] @PYbe[||]@PYbe[=] @PYaq[StyleFormat]@PYbe[.]new(@PYau[:number_format_string] @PYbe[=]@PYbe[>] @PYbd['#,##0.00']) @PYay[end] \end{Verbatim} If you use any of the array-writing methods, then autoformatting will be applied by default. To override this behaviour you can pass your own StyleFormat or nil to use the generic default format. \begin{Verbatim}[commandchars=@\[\]] @PYaX[require] @PYbd['rubygems'] @PYaX[require] @PYbd['surpass'] book @PYbe[=] @PYaq[Workbook]@PYbe[.]new(@PYaA[__FILE__]@PYbe[.]gsub(@PYak[/]@PYak[rb$]@PYak[/], @PYaW["]@PYaW[xls]@PYaW["])) sheet @PYbe[=] book@PYbe[.]add_sheet @PYaf[# Passing true for the style parameter to write will invoke autoformatting.] sheet@PYbe[.]write(@PYag[0], @PYag[0], @PYaW["]@PYaW[Hello World!]@PYaW["], @PYaj[true]) sheet@PYbe[.]write(@PYag[1], @PYag[0], @PYag[1], @PYaj[true]) sheet@PYbe[.]write(@PYag[2], @PYag[0], @PYag[1]@PYbe[.]@PYag[0], @PYaj[true]) sheet@PYbe[.]write(@PYag[3], @PYag[0], @PYaq[Date]@PYbe[.]today, @PYaj[true]) sheet@PYbe[.]write(@PYag[4], @PYag[0], @PYaq[DateTime]@PYbe[.]now, @PYaj[true]) sheet@PYbe[.]write(@PYag[5], @PYag[0], @PYaq[Time]@PYbe[.]now, @PYaj[true]) array_of_arrays @PYbe[=] @PYbe[@PYZlb[]] @PYbe[@PYZlb[]]@PYag[1], @PYag[2], @PYag[3]@PYbe[@PYZrb[]], @PYbe[@PYZlb[]]@PYag[1]@PYbe[.]@PYag[0], @PYag[2]@PYbe[.]@PYag[0], @PYag[3]@PYbe[.]@PYag[0]@PYbe[@PYZrb[]], @PYbe[@PYZlb[]]@PYaq[Date]@PYbe[.]today, @PYaq[DateTime]@PYbe[.]now@PYbe[@PYZrb[]], @PYbb[%w{]@PYbb[a b c]@PYbb[}] @PYbe[@PYZrb[]] @PYaf[# Writing arrays will automatically autoformat.] sheet@PYbe[.]write(@PYag[7], @PYag[0], @PYaW["]@PYaW[With autoformat:]@PYaW["]) sheet@PYbe[.]write_arrays(@PYag[8], @PYag[0], array_of_arrays) @PYaf[# Unless you specify your own format, or nil for a generic default.] sheet@PYbe[.]write(@PYag[13], @PYag[0], @PYaW["]@PYaW[Without autoformat:]@PYaW["]) sheet@PYbe[.]write_arrays(@PYag[14], @PYag[0], array_of_arrays, @PYaj[nil]) sheet@PYbe[.]set_column_widths(@PYag[0]@PYbe[.].@PYag[2], @PYag[20]) book@PYbe[.]save \end{Verbatim} \includegraphics[width=15cm]{examples/autoformat.png} % section autoformatting (end) % chapter writing_data (end) \chapter{Formatting} % (fold) \label{cha:formatting} \section{Reference} There is a command line tool included with Surpass which provides some useful reference data: \begin{Verbatim}[commandchars=@\[\]] surpass -h \end{Verbatim} \begin{verbatim} Usage: surpass-info [options] -c, --colors, --colours List available colors -p, --patterns List available patterns -h, --help Show this message \end{verbatim} And since you are running this on the command line, you can save or pipe the output to other commands: \begin{Verbatim}[commandchars=@\[\]] surpass -c | grep green \end{Verbatim} \begin{verbatim} bright-green dark-green green light-green olive-green sea-green \end{verbatim} \section{StyleFormat Class} The StyleFormat class is a wrapper for the various types of formatting you can apply to a cell. StyleFormat has attributes: \begin{itemize} \item number\_format\_string \item font \item alignment \item borders \item pattern \item protection \end{itemize} Each of these attributes (except for number\_format\_string) has a corresponding class, and you can look in lib/formatting.rb for the source. There are two basic ways to set formatting options. You can pass a hash with formatting options when you initialize a new StyleFormat instance, or you can set individual attributes of the formatting classes. You can also combine both approaches, initializing with a hash and then modifying attributes. \section{Number Format Strings} % (fold) \label{sec:number_format_strings} This attribute is a simple string, specifying the numeric/date format to be applied to the value stored in a cell. \newpage \begin{Verbatim}[commandchars=@\[\]] @PYaX[require] @PYbd['rubygems'] @PYaX[require] @PYbd['surpass'] book @PYbe[=] @PYaq[Workbook]@PYbe[.]new(@PYaA[__FILE__]@PYbe[.]gsub(@PYak[/]@PYak[rb$]@PYak[/], @PYaW["]@PYaW[xls]@PYaW["])) sheet @PYbe[=] book@PYbe[.]add_sheet date_format @PYbe[=] @PYaq[StyleFormat]@PYbe[.]new(@PYau[:number_format_string] @PYbe[=]@PYbe[>] @PYbd['DDD MMM YYYY']) sheet@PYbe[.]write(@PYag[0], @PYag[0], @PYaq[Date]@PYbe[.]today, date_format) two_dp_format @PYbe[=] @PYaq[StyleFormat]@PYbe[.]new two_dp_format@PYbe[.]number_format_string @PYbe[=] @PYaW["]@PYaW[#]@PYaW[,]@PYaW[#]@PYaW[#]@PYaW[0.00]@PYaW["] sheet@PYbe[.]write(@PYag[0], @PYag[1], @PYag[1002]@PYbe[.]@PYag[71828], two_dp_format) book@PYbe[.]save \end{Verbatim} \includegraphics[width=16cm]{examples/number-format-string.png} % section number_format_strings (end) \subsection{Specifying Colours} Here is a list of available colours: \begin{multicols}{3} \begin{verbatim} aqua black blue blue-grey bright-green brown coral cornflower-blue dark-blue dark-green dark-red dark-teal dark-yellow fuchsia gold gray green grey grey-25-percent grey-40-percent grey-50-percent grey-80-percent indigo lavender lemon-chiffon light-blue light-cornflower-blue light-green light-orange light-turquoise light-yellow lime magenta maroon olive-green orange orchid pale-blue pink plum purple red rose royal-blue sea-green silver sky-blue tan teal turquoise violet white yellow \end{verbatim} \end{multicols} \includegraphics[width=16cm]{examples/colours.png} \subsection{Border Formats} Here is a list of available border line types: \begin{verbatim} none thin medium dashed dotted thick double hair medium-dashed thin-dash-dotted medium-dash-dotted thin-dash-dot-dotted medium-dash-dot-dotted slanted-medium-dash-dotted \end{verbatim} \includegraphics[width=16cm]{examples/borders.png} \subsection{Fill Patterns} Here is a list of available fill patterns: \begin{verbatim} none solid fine-dots alt-bars sparse-dots thick-horz-bands thick-vert-bands thick-backward-diag thick-forward-diag big-spots bricks thin-horz-bands thin-vert-bands thin-backward-diag thin-forward-diag squares diamonds less-dots least-dots \end{verbatim} \includegraphics[width=16cm]{examples/patterns.png} \subsection{Surpass} \begin{Verbatim}[commandchars=@\[\]] @PYaX[require] @PYbd['rubygems'] @PYaX[require] @PYbd['surpass'] book @PYbe[=] @PYaq[Workbook]@PYbe[.]new(@PYaA[__FILE__]@PYbe[.]gsub(@PYak[/]@PYak[rb$]@PYak[/], @PYaW["]@PYaW[xls]@PYaW["])) sheet @PYbe[=] book@PYbe[.]add_sheet(@PYaW["]@PYaW[Demo Worksheet]@PYaW["]) @PYaf[# You can name your worksheets.] @PYaf[# Let's set up some formatting.] @PYaf[# Remember to use Excel-style formatting directives, not sprintf.] date_format @PYbe[=] @PYaq[StyleFormat]@PYbe[.]new(@PYau[:number_format_string] @PYbe[=]@PYbe[>] @PYaW["]@PYaW[DDDD DD MMM YYYY]@PYaW["]) fancy_format @PYbe[=] @PYaq[StyleFormat]@PYbe[.]new( @PYau[:font_name] @PYbe[=]@PYbe[>] @PYbd['Times New Roman'], @PYau[:font_colour] @PYbe[=]@PYbe[>] @PYbd['green'], @PYau[:font_italic] @PYbe[=]@PYbe[>] @PYaj[true] ) sheet@PYbe[.]write(@PYag[0], @PYag[0], @PYaW["]@PYaW[Hello World!]@PYaW["], fancy_format) sheet@PYbe[.]write(@PYag[0], @PYag[1], @PYaq[Date]@PYbe[.]today, date_format) @PYaf[# You can also set up formatting by passing attributes directly to the constituents of StyleFormat] @PYaf[# Font colours.] @PYaq[Formatting]@PYbe[::]@PYaq[COLOURS]@PYbe[.]keys@PYbe[.]each_with_index @PYay[do] @PYbe[|]c, i@PYbe[|] @PYaX[format] @PYbe[=] @PYaq[StyleFormat]@PYbe[.]new @PYaX[format]@PYbe[.]font@PYbe[.]name @PYbe[=] @PYbd['Verdana'] @PYaX[format]@PYbe[.]font@PYbe[.]color @PYbe[=] c @PYaX[format]@PYbe[.]font@PYbe[.]size @PYbe[=] i @PYbe[+] @PYag[5] sheet@PYbe[.]write(i, @PYag[5], c, @PYaX[format]) @PYay[end] @PYaf[# Font underlining.] @PYbe[@PYZlb[]]@PYau[:none], @PYau[:single], @PYau[:single_accounting], @PYau[:double], @PYau[:double_accounting], @PYaj[nil], @PYaj[true], @PYaj[false]@PYbe[@PYZrb[]]@PYbe[.]each_with_index @PYay[do] @PYbe[|]u, i@PYbe[|] @PYaX[format] @PYbe[=] @PYaq[StyleFormat]@PYbe[.]new @PYaX[format]@PYbe[.]font@PYbe[.]underline @PYbe[=] u sheet@PYbe[.]write(i, @PYag[7], u@PYbe[.]to_s, @PYaX[format]) @PYay[end] @PYaf[# Font bold, italic, strikethrough, outline are simple booleans.] @PYbe[@PYZlb[]]@PYau[:bold], @PYau[:italic], @PYau[:struck_out], @PYau[:outline]@PYbe[@PYZrb[]]@PYbe[.]each_with_index @PYay[do] @PYbe[|]s, i@PYbe[|] attribute @PYbe[=] (@PYaW["]@PYaW[font_]@PYaW["] @PYbe[+] s@PYbe[.]to_s)@PYbe[.]to_sym sheet@PYbe[.]write(i, @PYag[8], s@PYbe[.]to_s, @PYaq[StyleFormat]@PYbe[.]new(attribute @PYbe[=]@PYbe[>] @PYaj[true])) @PYay[end] @PYaf[# Cell alignment.] sheet@PYbe[.]write(@PYag[15], @PYag[2], @PYaW["]@PYaW[top left]@PYaW["], @PYau[:text_align] @PYbe[=]@PYbe[>] @PYbd['top left'], @PYau[:border_top] @PYbe[=]@PYbe[>] @PYbd['pink'], @PYau[:border_left] @PYbe[=]@PYbe[>] @PYbd['pink'] ) sheet@PYbe[.]write(@PYag[15], @PYag[3], @PYaW["]@PYaW[top center]@PYaW["], @PYau[:text_align] @PYbe[=]@PYbe[>] @PYbd['top center']) sheet@PYbe[.]write(@PYag[15], @PYag[4], @PYaW["]@PYaW[top right]@PYaW["], @PYau[:text_align] @PYbe[=]@PYbe[>] @PYbd['top right']) sheet@PYbe[.]write(@PYag[16], @PYag[2], @PYaW["]@PYaW[bottom left]@PYaW["], @PYau[:text_align] @PYbe[=]@PYbe[>] @PYbd['bottom left']) sheet@PYbe[.]write(@PYag[16], @PYag[3], @PYaW["]@PYaW[bottom centre]@PYaW["], @PYau[:text_align] @PYbe[=]@PYbe[>] @PYbd['bottom centre']) sheet@PYbe[.]write(@PYag[16], @PYag[4], @PYaW["]@PYaW[bottom right]@PYaW["], @PYau[:text_align] @PYbe[=]@PYbe[>] @PYbd['bottom right'], @PYau[:border_bottom] @PYbe[=]@PYbe[>] @PYbd['pink'], @PYau[:border_right] @PYbe[=]@PYbe[>] @PYbd['pink'] ) @PYaf[# Borders] sheet@PYbe[.]write(@PYag[3], @PYag[1], @PYaW["]@PYaW[borders]@PYaW["], @PYau[:border_right] @PYbe[=]@PYbe[>] @PYbd['medium blue'], @PYau[:border_left] @PYbe[=]@PYbe[>] @PYbd['yellow'], @PYaf[# thin by default] @PYau[:border_top] @PYbe[=]@PYbe[>] @PYbd['dotted purple'], @PYau[:border_bottom] @PYbe[=]@PYbe[>] @PYbd['dashed'] @PYaf[# black by default] ) @PYaf[# Or the hash-free option.] crazy_border_format @PYbe[=] @PYaq[StyleFormat]@PYbe[.]new crazy_border_format@PYbe[.]borders@PYbe[.]all @PYbe[=] @PYbd['slanted-medium-dash-dotted grey'] crazy_border_format@PYbe[.]pattern@PYbe[.]fill @PYbe[=] @PYbd['light-cornflower-blue'] sheet@PYbe[.]write(@PYag[5], @PYag[1], @PYaW["]@PYaW[borders]@PYaW["], crazy_border_format) sheet@PYbe[.]write(@PYag[7], @PYag[1], @PYaW["]@PYaW[fill]@PYaW["], @PYau[:fill_color] @PYbe[=]@PYbe[>] @PYbd['yellow']) book@PYbe[.]save \end{Verbatim} And, here's how it looks. \includegraphics[width=16cm]{examples/formatting.png} % chapter formatting (end) \chapter{Saving} % (fold) \label{cha:saving} Typically, you will call the workbook's save() method to write that workbook to a file. You can pass the filename as an argument to save(), or as an argument to new() when you first instantiate a workbook object. However, you can also call a workbook's data() method, which gives you direct access to a workbook's binary data. You can write this to a file manually, as in this example: \begin{Verbatim}[commandchars=@\[\]] @PYaX[require] @PYbd['rubygems'] @PYaX[require] @PYbd['surpass'] book @PYbe[=] @PYaq[Workbook]@PYbe[.]new sheet @PYbe[=] book@PYbe[.]add_sheet sheet@PYbe[.]write(@PYag[0], @PYag[0], @PYaW["]@PYaW[Hello World!]@PYaW["]) @PYaq[File]@PYbe[.]open(@PYaA[__FILE__]@PYbe[.]gsub(@PYak[/]@PYak[rb$]@PYak[/], @PYaW["]@PYaW[xls]@PYaW["]), @PYaW["]@PYaW[w]@PYaW["]) @PYay[do] @PYbe[|]f@PYbe[|] f@PYbe[.]write book@PYbe[.]data @PYay[end] \end{Verbatim} Or, you could use this data as an argument to Rails' send\_data method. % chapter saving (end) \end{document}