% ooxml(n) | ooxml user documentation
# NAME

::ooxml::xl_sheets, ::ooxml::xl_read, ::ooxml::xl_write,
::ooxml::tablelist_to_xl - Read and create ECMA-376 Office Open XML
Spreadsheets (the .xlsx format)

# SYNOPSIS

    package require ooxml
    ::ooxml::xl_sheets file
    ::ooxml::xl_read file ?-option value ...?
    ::ooxml::xl_write new ?-option value ...?
    ::ooxml::tablelist_to_xl tablelist ?-option value ...?

# DESCRIPTION

The commands of this package read or create ECMA-376 Office Open XML
Spreadsheets (LibreOffice and Excel ".xlsx" files). The three most
important are:

    ::ooxml::xl_read - imports a .xlsx spreadsheet file into a Tcl array
    ::ooxml::xl_write - creates a spreadsheet object command
    ::ooxml::tablelist_to_xl - exports a Tcl tablelist to a .xlsx spreadsheet

In this documentation the term workbook means a whole spreadsheet
with all its tables. The term worksheet means a specific table of the
workbook it belongs to.

All row, column and sheet indices used by this package are zero-based.
Cell positions may be given numerically as *row,column* or in Excel
notation; see [CELL INDEX](#cell-index).

The package provides the following commands:

**::ooxml::arrayDeleteSheet** *arrayName* *sheetId* *?-sheetname?*

: Deletes one worksheet from an array read with *::ooxml::xl_read*
  and renumbers the remaining sheets. The array is passed by name
  (without `$`). By default *sheetId* is the zero-based sheet index;
  with the **-sheetname** option it is the worksheet name.

        ::ooxml::arrayDeleteSheet workbook 0
        ::ooxml::arrayDeleteSheet workbook "Sheet1" -sheetname

**::ooxml::CalcColumnWidth** *numberOfCharacters* *?maximumDigitWidth?* *?pixelPadding?*

: Returns the column width value (for the **column** method **-width**
  option) that fits the given number of characters. The optional
  arguments *maximumDigitWidth* (default 7) and *pixelPadding*
  (default 5) describe the metrics of the standard font.

        ::ooxml::CalcColumnWidth 16   ;# -> 16.7109375

**::ooxml::Column** *column*

: Converts the zero-based *column* number into the column name in
  Excel notation (0 -> A, 1 -> B, 26 -> AA, ...).

**::ooxml::Default** *name* *value*

: Sets a package wide default. The only currently supported *name* is
  *path*: the default directory of written files (used e.g. by
  *::ooxml::tablelist_to_xl* if no **-path** is given). An empty
  *value* resets it to the current directory.

**::ooxml::RowColumnToString** *rowcol*

: Converts a numerical cell index (*row,column*, zero-based) into
  Excel notation (0,0 -> A1).

**::ooxml::StringToRowColumn** *name*

: Converts a cell position in Excel notation into the numerical form
  (A1 -> 0,0).

**::ooxml::tablelist_to_xl** *tablelist* *?-option value ...?*

: Exports the content of the Tk tablelist widget *tablelist* to a
  .xlsx file. The recognized options are:

        -callback command: Command to be called once per workbook and
        once per column, to customize styles and column properties.
        See below for the arguments. Default is the built-in callback
        ::ooxml::tablelist_to_xl_callback.

        -path path: Directory of the output file.

        -file filename: Name of the output file (a .xlsx suffix is
        appended if missing).

        -creator name: Creator property of the spreadsheet.

        -name name: Name of the (single) worksheet.

        -rootonly: Export only the root level of the tablelist (no
        child items).

        -addtimestamp: Add a timestamp to the output file name.

        -globalstyle: Write the cells with the column styles set by
        the callback.

    The callback is called with the arguments

        spreadsheet sheet maxcol column title width align sortmode hide

    where *spreadsheet* is the spreadsheet object, *sheet* the
    worksheet handle and *maxcol* the number of columns. It is called
    once with *column* = -1 for the whole workbook (for example to
    set the default date style) and then once per column with the
    tablelist column properties *title*, *width*, *align*, *sortmode*
    and *hide*.

        proc myCallback {spreadsheet sheet maxcol column title width align sortmode hide} {
            if {$column == -1} {
                set datestyle [$spreadsheet style -numfmt [$spreadsheet numberformat -datetime]]
                $spreadsheet defaultdatestyle $datestyle
            } elseif {$align eq "right"} {
                $spreadsheet column $sheet -index $column -style [$spreadsheet style -horizontal right]
            }
        }

**::ooxml::xl_read** *file* *?-option value ...?*

: Reads the given .xlsx *file* and returns its contents as a flat Tcl
  array (to be caught with `array set`). See
  [RESULT ARRAY](#result-array) for the keys of the returned array.
  The recognized options are:

        -valuesonly: Read only the cell values, no formatting,
        formulas or sheet properties.

        -keylist: Additionally build the S,k key (see
        RESULT ARRAY), a dictionary of the non-empty columns per row.

        -sheets pattern: Read only the worksheets whose zero-based
        sheet index matches the glob pattern.

        -sheetnames pattern: Read only the worksheets whose name
        matches the glob pattern.

        If neither -sheets nor -sheetnames is given all worksheets
        are read.

        -datefmt format: [clock format] string used to convert date
        cells into the value keys (default "%Y-%m-%d %H:%M:%S").

        -as array: Format of the return value. Currently array is
        the only supported value.

    A simple example:

        array set workbook [::ooxml::xl_read file.xlsx]
        foreach key [lsort -dictionary [array names workbook 0,v,*]] {
            lassign [split $key ,] sheet tag row col
            puts "$row,$col = $workbook($key)"
        }

**::ooxml::xl_sheets** *file*

: Returns information about the worksheets of the given .xlsx *file*
  without reading any cell data. The result is a Tcl list with two
  elements per worksheet: the zero-based sheet index and a dictionary
  with the keys *sheetId* (the internal sheet id), *name* (the display
  name of the worksheet) and *rId* (the internal relationship id).

        foreach {index info} [::ooxml::xl_sheets file.xlsx] {
            puts "$index: [dict get $info name]"
        }

**::ooxml::xl_write** **new** *?-option value ...?*

: Creates a spreadsheet object command to build a workbook from
  scratch:

        set spreadsheet [::ooxml::xl_write new ?-option value ...?]

    The recognized options are:

        -creator name: The creator property of the spreadsheet.

        -created timestamp: The creation time property of the
        spreadsheet. The value is either an integer (seconds, as
        returned by [clock seconds]) or a date string in local time.

        -modifiedby name: The modified-by property of the
        spreadsheet.

        -modified timestamp: The modification time property of the
        spreadsheet. For the value see -created.

        -application name: The application property of the
        spreadsheet.

The created spreadsheet object commands currently support the
following methods:

**autofilter** *sheet* *indexFrom* *indexTo*

: Adds an autofilter (filter and sort controls on the header row) to
  the worksheet, spanning from cell *indexFrom* to cell *indexTo*
  (see [CELL INDEX](#cell-index)).

        $spreadsheet autofilter $sheet 0,0 0,5

**border** *?-option value ...?*

: Defines a border style for the current workbook and returns an ID
  (BORDERID) to refer to that style. The recognized options are:

        -list: Returns the list of currently defined border styles
        instead of a BORDERID.

        -leftstyle BORDERLINESTYLE
        -rightstyle BORDERLINESTYLE
        -topstyle BORDERLINESTYLE
        -bottomstyle BORDERLINESTYLE
        -diagonalstyle BORDERLINESTYLE

        See BORDERLINESTYLE for the valid values.

        -leftcolor COLOR
        -rightcolor COLOR
        -topcolor COLOR
        -bottomcolor COLOR
        -diagonalcolor COLOR

        See COLOR for the valid values.

        -diagonaldirection (up|down)

        -tag tagname: Gives the border style a name. This name may be
        used instead of the returned BORDERID.

: See [BORDERLINESTYLE](#borderlinestyle) and [COLOR](#color) for the
  valid option values.

**cell** *sheet* *?data?* *?-option value ...?*

: Writes the value *data* into a cell of the worksheet *sheet* and
  returns the position of the written cell as *row,column*. Without
  the **-index** option the cell is placed in the current row at the
  next column (see [CELL INDEX](#cell-index) for the autoincrement
  behaviour). The recognized options are:

        -index index: Position of the cell, either as row,column or
        in Excel notation. Also accepts a bare column number to place
        the cell in the current row with columns skipped.

        -style STYLEID: Style of the cell, from the method style.

        -formula formula: Enter an Excel formula (e.g. "A1+B1"). The
        data argument is usually empty then, the application
        computes the value.

        -formulaidx integer: Shared formula index. A cell defining a
        shared formula gives -formula, -formularef and -formulaidx;
        the dependent cells give only -formulaidx.

        -formularef range: The range the shared formula spans, either
        in Excel notation (C3:C5) or numerically (2,2:4,2).

        -string: Store the value as string in any case.

        -nostring: Override a column-level -string setting for this
        cell.

        -nozero: Do not output the value if it is zero.

        -zero: Override a column-level -nozero setting for this cell.

        -globalstyle: Apply the column style to this cell.

        -height height: Sets the row height of the current row.

        -hyperlink url: Makes the cell a hyperlink to url.

        -tooltip text: Tooltip for the hyperlink (only used together
        with -hyperlink).

**column** *sheet* *?-option value ...?*

: Defines the properties of a column of the worksheet *sheet* and
  returns the column number. Without the **-index** option the next
  column is used. The recognized options are:

        -index index: Column number.

        -to index: Last column number, if the definition should span
        a range of columns.

        -width width: Column width in characters of the standard font
        (may be fractional, see also ::ooxml::CalcColumnWidth).

        -style STYLEID: Default style for the cells of the column.
        Note that a cell only uses it if written with -globalstyle.

        -bestfit: Sets the bestFit flag of the column.

        -customwidth: Sets the customWidth flag of the column.

        -string: Store the values of the cells of this column as
        string in any case (a cell may override this with -nostring).

        -nozero: Do not output zero values in this column (a cell may
        override this with -zero).

        -calcfit: Calculates the column width from the length of the
        longest value written to the column (via
        ::ooxml::CalcColumnWidth) if that is wider than a given
        -width.

**defaultdatestyle** *STYLEID*

: Sets the default style for date cells. Values recognized as dates
  are formatted with this style if the cell does not have an explicit
  **-style**.

        set datestyle [$spreadsheet style -numfmt [$spreadsheet numberformat -datetime]]
        $spreadsheet defaultdatestyle $datestyle

**fill** *?-option value ...?*

: Defines a fill style for the current workbook and returns an ID
  (FILLID) to refer to that style. The recognized options are:

        -list: Returns the list of currently defined fills instead of
        a FILLID.

        -patterntype PATTERNTYPE: See PATTERNTYPE for the usual
        values (default "none").

        -fgcolor COLOR: Foreground (pattern) color. See COLOR for the
        valid values.

        -bgcolor COLOR: Background color. See COLOR for the valid
        values.

        -tag tagname: Gives the fill a name. This name may be used
        instead of the returned FILLID.

: See [PATTERNTYPE](#patterntype) and [COLOR](#color) for the valid
  option values.

**font** *?-option value ...?*

: Defines a font for the current workbook and returns an ID (FONTID)
  to refer to that font. The recognized options are:

        -list: Returns the list of currently defined fonts instead of
        a FONTID.

        -name name: Font name (default "Calibri").

        -family family: Font family number (default 2).

        -size size: Font size in points (default 12).

        -color COLOR: See COLOR for the valid values.

        -scheme scheme: Font scheme (default "minor").

        -bold: Bold text.

        -italic: Italic text.

        -underline: Underlined text.

        -tag tagname: Gives the font a name. This name may be used
        instead of the returned FONTID.

: See [COLOR](#color) for the valid **-color** values.

**freeze** *sheet* *index*

: Freezes the panes above and left of the given cell *index* (see
  [CELL INDEX](#cell-index)), so they stay visible while scrolling.

        $spreadsheet freeze $sheet 1,0   ;# freeze the first row

**merge** *sheet* *indexFrom* *indexTo*

: Merges the cell range with the corners *indexFrom* and *indexTo*
  (see [CELL INDEX](#cell-index)) into one cell.

        $spreadsheet merge $sheet 40,0 40,2
        $spreadsheet merge $sheet A42 A44

**numberformat** *?-option value ...?*

: Defines a number format for the current workbook and returns an ID
  (NUMFMTID) to refer to that format. The recognized options are:

        -format format: Any Excel format string (e.g. {#,##0.00 "€"}).

        -general: Excel general format.

        -date: Date format.

        -time: Time format.

        -datetime: Date/time format.

        -iso8601: Date/time in ISO 8601 notation.

        -number: Integer.

        -decimal: Decimal number with 2 decimal places.

        -red: Color negative values red (may be combined with -number
        and -decimal).

        -separator: Thousands separators (may be combined with
        -number and -decimal).

        -fraction: Fractions.

        -scientific: Scientific notation.

        -percent: Percentage.

        -text, -string: Text format.

        -tag tagname: Gives the format a name. This name may be used
        instead of the returned NUMFMTID.

**pageMargins** *sheet* *?-option value ...?*

: Sets the page margins of the worksheet *sheet*. The recognized
  options are:

        -left -right -top -bottom -header -footer

        All options expect a floating point value in inch.

    If some page margins of a worksheet are set with this method then
    all margins of that worksheet are set, either from the options
    given in the method call or from the current
    **pageMarginsDefault** values, if a margin was not in the method
    call.

**pageMarginsDefault** *?-option value ...?*

: Sets the page margins of all worksheets which do not have
  individual margin settings. The options are the same as for
  **pageMargins**. The default margins are:

    Margin   Inch
    -------- -------
    left     0.75
    right    0.75
    top      1
    bottom   1
    header   0.5
    footer   0.5

**pageSetup** *sheet* *?-option value ...?*

: Sets the page setup of the worksheet *sheet*.

    **Caveat**: If no page setup properties at all are set for a
    sheet, applications use defaults derived from other sources. But
    if at least one page setup property is explicitly set with this
    method, the other properties not set will get the default value
    from the specification, which may be another value than without
    any page setup at all. For example if you only set the
    **-orientation** of a sheet then this may also result in another
    page size (because the application page size default may differ
    from the default recommended by the specification, which is
    Letter paper).

    The recognized options are:

        -blackAndWhite boolean: Print black and white. Default:
        false.

        -cellComments (none|asDisplayed|atEnd): How to print cell
        comments. Default: none.

        -copies integer: Number of copies to print. Default: 1.

        -draft boolean: Print without graphics. Default: false.

        -errors (displayed|blank|dash|NA): How to print cell values
        of cells with errors. Default: displayed.

        -firstPageNumber integer: Page number of the first printed
        page; see -useFirstPageNumber. Default: 1.

        -fitToHeight integer: Number of vertical pages to fit on.
        Default: 1.

        -fitToWidth integer: Number of horizontal pages to fit on.
        Default: 1.

        -horizontalDpi integer: Horizontal print resolution of the
        device. Default: 600.

        -orientation (default|portrait|landscape): Orientation of the
        page. Default: default.

        -pageOrder (downThenOver|overThenDown): Order of the printed
        pages. Default: downThenOver.

        -paperHeight height: Height of custom paper as a number
        immediately followed by a unit identifier (as 297mm or 11in).
        No default.

        -paperWidth width: Width of custom paper as a number
        immediately followed by a unit identifier (as 210mm or
        8.5in). No default.

        The specification says that when -paperHeight and -paperWidth
        are specified, the rendering application shall ignore
        -paperSize.

        -paperSize paperSizeID: Specifies the paper size. Default: 1
        (Letter). See PAPER SIZE IDS for the defined values; the
        behaviour for other values is implementation-defined.

        -scale integer: Print scaling in percent. The rendering
        application may respect only values ranging from 10 to 400.
        Overridden when -fitToWidth and/or -fitToHeight are in use.
        Default: 100.

        -useFirstPageNumber boolean: Use the -firstPageNumber value
        for the first page number and do not auto number the pages.
        Default: false.

        -usePrinterDefaults boolean: Use the printer defaults (or the
        defaults of the print job).

        -verticalDpi integer: Vertical print resolution of the
        device. Default: 600.

: See [PAPER SIZE IDS](#paper-size-ids) for the possible
  **-paperSize** values.

**presetsheets** *arrayName*

: Creates worksheets from an array previously read with
  *::ooxml::xl_read*, including their data. The array is passed by
  name (without `$`). The sheets are created in their original order.
  The method adds the key *sheetmap* to the array: a dict mapping the
  original sheet index to the newly created worksheet handle. Usually
  combined with **presetstyles**:

        array set workbook [::ooxml::xl_read original.xlsx]
        set spreadsheet [::ooxml::xl_write new]
        $spreadsheet presetstyles workbook
        $spreadsheet presetsheets workbook

**presetstyles** *arrayName*

: Takes over the style definitions (number formats, fonts, fills,
  borders and cell styles) from an array previously read with
  *::ooxml::xl_read*. The array is passed by name (without `$`).

**printarea** *sheet* *indexFrom* *indexTo*

: Sets the print area of the worksheet *sheet*, spanning from cell
  *indexFrom* to cell *indexTo* (see [CELL INDEX](#cell-index)).

        $spreadsheet printarea $sheet A1 C3
        $spreadsheet printarea $sheet 1,1 2,2

**row** *sheet* *?-option value ...?*

: Starts a new row in the worksheet *sheet* and returns the row
  number. Without the **-index** option the next row is used; the
  column autoincrement is reset (see [CELL INDEX](#cell-index)). The
  recognized options are:

        -index index: Row number to jump to.

        -height height: Row height in points.

**rowheight** *sheet* *row* *height*

: Sets the height of the given *row* (zero-based) of the worksheet
  *sheet* to *height* points, independently of writing cells.

        $spreadsheet rowheight $sheet 33 20

**style** *?-option value ...?*

: Defines a cell style for the current workbook and returns an ID
  (STYLEID) to refer to that style. The recognized options are:

        -list: Returns the list of currently defined styles instead
        of a STYLEID.

        -numfmt NUMFMTID: From the method numberformat.

        -font FONTID: From the method font.

        -fill FILLID: From the method fill.

        -border BORDERID: From the method border.

        -xf XFID: Base cell format record to derive from.

        -horizontal alignment: Horizontal alignment of the cell
        content (e.g. left, center, right).

        -vertical alignment: Vertical alignment of the cell content
        (e.g. top, center, bottom).

        -rotate degree: Rotation of the cell content in degrees.

        -wrap: Enables text wrapping within the cell.

        -tag tagname: Gives the style a name. This name may be used
        instead of the returned STYLEID.

**view** *?-option value ...?*

: Sets the workbook view properties. The recognized options are:

        -activetab tab: Zero-based index of the worksheet shown when
        the file is opened.

        -x twips -y twips: Position of the workbook window.

        -width twips -height twips: Size of the workbook window.

        -list: Returns the current view settings instead of setting
        them.

**worksheet** *name*

: Creates a new worksheet with the given *name* and returns the sheet
  handle (SHEETID) used as first argument by the cell related
  methods. The characters `: \ / ? *` in the name are replaced and
  the name is truncated to the 31 characters allowed by the format.

**write** *filename*

: Writes the spreadsheet to the file *filename*. If the filename does
  not have the suffix .xlsx then it is appended. If *filename* is
  empty, spreadsheetml.xlsx is used.

# RESULT ARRAY

*::ooxml::xl_read* returns a flat array. In the following key table
*S* stands for the zero-based sheet index and *R*,*C* for the
zero-based row and column index:

Key             Content
--------------- ------------------------------------------------------
sheets          List of the sheet indices that have been read
S,n             Worksheet name
S,max_row       Largest used row index of the worksheet
S,max_column    Largest used column index of the worksheet
S,v,R,C         Cell value (present for every non-empty cell)
S,d,R,C         Raw date/time serial if the cell is a date cell
S,s,R,C         Style id of the cell
S,t,R,C         Cell type (*s* = shared string)
S,c,R,C         Cell position in Excel notation (e.g. B7)
S,f,R,C         Formula dict: keys *f* (formula), *i* (shared formula index), *r* (shared formula range)
S,l,IDX         Hyperlink dict: keys *l* (target), *t* (tooltip)
S,k             Dict row -> list of non-empty columns (only with the -keylist option)
S,filter        Autofilter ranges
S,freeze        Freeze pane position
S,merge         List of merged cell ranges
S,printarea     Print area range
S,rowheight     Row height settings
S,cols          Number of column definitions
S,col,N         Dict with the properties of column definition *N*
S,pageMargins   Page margin settings
S,pageSetup     Page setup settings
view            Workbook view settings
s,...           Style metadata (s,@ s,styles,N s,fonts,N s,fills,N s,borders,N s,numFmts,N s,numFmtsIds), consumed by **presetstyles** and **presetsheets**

With the **-valuesonly** option only the *sheets*, *S,n*, *S,max_row*,
*S,max_column* and *S,v,R,C* keys are present.

# CELL INDEX

Methods and options expecting a cell position accept it in two
equivalent forms: numerically as *row,column* with zero-based row and
column numbers, or in Excel notation (column letters followed by the
one-based row number). 0,0 and A1 describe the same cell, 3,2 and C4
also.

The methods **row**, **column** and **cell** work with an
autoincrement mechanism: without an explicit **-index** option
**row** starts the next row, **cell** writes to the next column of
the current row and **column** defines the next column. An explicit
**-index** repositions; the autoincrement continues from there.

    $spreadsheet row $sheet
    $spreadsheet cell $sheet A           ;# 0,0
    $spreadsheet cell $sheet B -index 4  ;# 0,4 (columns 1-3 stay empty)
    $spreadsheet cell $sheet C           ;# 0,5
    $spreadsheet row $sheet -index 3     ;# jump to row 3
    $spreadsheet cell $sheet D           ;# 3,0

For writing prefer the autoincrement wherever possible: call
`$spreadsheet row $sheet` once per row and write the cells in order
without **-index**. This avoids off-by-one and index bookkeeping
errors.

# OPTION VALUE TYPES

Several option values share the same value types. These types are:

## COLOR

There are several kinds of valid values:

The value may be *auto* or *none*.

If not, the value may be the index number of a predefined color (an
integer between 0 and 65 including). See the list below.

If not, the value may be the name of a predefined color. Case is
ignored. See the list below.

If not, the value may be a 6 digit hexadecimal number, which is then
used as RGB value.

The list of predefined colors is:

Color ID Name             (A)RGB
-------- ---------------  --------
0        Black            00000000
1        White            00FFFFFF
2        Red              00FF0000
3        Lime             0000FF00
4        Blue             000000FF
5        Yellow           00FFFF00
6        Fuchsia          00FF00FF
7        Aqua             0000FFFF
8        Black            00000000
9        White            00FFFFFF
10       Red              00FF0000
11       Lime             0000FF00
12       Blue             000000FF
13       Yellow           00FFFF00
14       Fuchsia          00FF00FF
15       Aqua             0000FFFF
16       Maroon           00800000
17       Green            00008000
18       Navy             00000080
19       Olive            00808000
20       Purple           00800080
21       Teal             00008080
22       Silver           00C0C0C0
23       Gray             00808080
24       Portage          009999FF
25       Lipstick         00993366
26       Cream            00FFFFCC
27       LightCyan        00CCFFFF
28       Purple           00660066
29       LightCoral       00FF8080
30       NavyBlue         000066CC
31       LavenderBlue     00CCCCFF
32       Navy             00000080
33       Fuchsia          00FF00FF
34       Yellow           00FFFF00
35       Aqua             0000FFFF
36       Purple           00800080
37       Maroon           00800000
38       Teal             00008080
39       Blue             000000FF
40       DeepSkyBlue      0000CCFF
41       LightCyan        00CCFFFF
42       BlueRomance      00CCFFCC
43       Canary           00FFFF99
44       LightSkyBlue     0099CCFF
45       CarnationPink    00FF99CC
46       Mauve            00CC99FF
47       PeachOrange      00FFCC99
48       RoyalBlue        003366FF
49       MediumTurquoise  0033CCCC
50       Citrus           0099CC00
51       TangerineYellow  00FFCC00
52       OrangePeel       00FF9900
53       SafetyOrange     00FF6600
54       Scampi           00666699
55       Nobel            00969696
56       PrussianBlue     00003366
57       Eucalyptus       00339966
58       Myrtle           00003300
59       Karaka           00333300
60       SaddleBrown      00993300
61       Lipstick         00993366
62       DarkSlateBlue    00333399
63       NightRider       00333333
64       SystemForeground n/a
65       SystemBackground n/a

## BORDERLINESTYLE

The list of possible values is:

    dashDot
    dashDotDot
    dashed
    dotted
    double
    hair
    medium
    mediumDashDot
    mediumDashDotDot
    none
    slantDashDot
    thick
    thin

## PATTERNTYPE

An ECMA-376 fill pattern type. The usual values are:

    none
    solid
    darkDown
    darkGray
    darkGrid
    darkHorizontal
    darkTrellis
    darkUp
    darkVertical
    gray0625
    gray125
    lightDown
    lightGray
    lightGrid
    lightHorizontal
    lightTrellis
    lightUp
    lightVertical
    mediumGray

## PAPER SIZE IDS

The possible **-paperSize** values and their meaning are:

Paper Size ID  Paper Size
-------------  ------------------
1              Letter paper (8.5 in. by 11 in.)
2              Letter small paper (8.5 in. by 11 in.)
3              Tabloid paper (11 in. by 17 in.)
4              Ledger paper (17 in. by 11 in.)
5              Legal paper (8.5 in. by 14 in.)
6              Statement paper (5.5 in. by 8.5 in.)
7              Executive paper (7.25 in. by 10.5 in.)
8              A3 paper (297 mm by 420 mm)
9              A4 paper (210 mm by 297 mm)
10             A4 small paper (210 mm by 297 mm)
11             A5 paper (148 mm by 210 mm)
12             B4 paper (250 mm by 353 mm)
13             B5 paper (176 mm by 250 mm)
14             Folio paper (8.5 in. by 13 in.)
15             Quarto paper (215 mm by 275 mm)
16             Standard paper (10 in. by 14 in.)
17             Standard paper (11 in. by 17 in.)
18             Note paper (8.5 in. by 11 in.)
19             #9 envelope (3.875 in. by 8.875 in.)
20             #10 envelope (4.125 in. by 9.5 in.)
21             #11 envelope (4.5 in. by 10.375 in.)
22             #12 envelope (4.75 in. by 11 in.)
23             #14 envelope (5 in. by 11.5 in.)
24             C paper (17 in. by 22 in.)
25             D paper (22 in. by 34 in.)
26             E paper (34 in. by 44 in.)
27             DL envelope (110 mm by 220 mm)
28             C5 envelope (162 mm by 229 mm)
29             C3 envelope (324 mm by 458 mm)
30             C4 envelope (229 mm by 324 mm)
31             C6 envelope (114 mm by 162 mm)
32             C65 envelope (114 mm by 229 mm)
33             B4 envelope (250 mm by 353 mm)
34             B5 envelope (176 mm by 250 mm)
35             B6 envelope (176 mm by 125 mm)
36             Italy envelope (110 mm by 230 mm)
37             Monarch envelope (3.875 in. by 7.5 in.).
38             6 3/4 envelope (3.625 in. by 6.5 in.)
39             US standard fanfold (14.875 in. by 11 in.)
40             German standard fanfold (8.5 in. by 12 in.)
41             German legal fanfold (8.5 in. by 13 in.)
42             ISO B4 (250 mm by 353 mm)
43             Japanese double postcard (200 mm by 148 mm)
44             Standard paper (9 in. by 11 in.)
45             Standard paper (10 in. by 11 in.)
46             Standard paper (15 in. by 11 in.)
47             Invite envelope (220 mm by 220 mm)
50             Letter extra paper (9.275 in. by 12 in.)
51             Legal extra paper (9.275 in. by 15 in.)
52             Tabloid extra paper (11.69 in. by 18 in.)
53             A4 extra paper (236 mm by 322 mm)
54             Letter transverse paper (8.275 in. by 11 in.)
55             A4 transverse paper (210 mm by 297 mm)
56             Letter extra transverse paper (9.275 in. by 12 in.)
57             SuperA/SuperA/A4 paper (227 mm by 356 mm)
58             SuperB/SuperB/A3 paper (305 mm by 487 mm)
59             Letter plus paper (8.5 in. by 12.69 in.)
60             A4 plus paper (210 mm by 330 mm)
61             A5 transverse paper (148 mm by 210 mm)
62             JIS B5 transverse paper (182 mm by 257 mm)
63             A3 extra paper (322 mm by 445 mm)
64             A5 extra paper (174 mm by 235 mm)
65             ISO B5 extra paper (201 mm by 276 mm)
66             A2 paper (420 mm by 594 mm)
67             A3 transverse paper (297 mm by 420 mm)
68             A3 extra transverse paper (322 mm by 445 mm)
69             Japanese Double Postcard (200 mm x 148 mm)
70             A6 (105 mm x 148 mm)
71             Japanese Envelope Kaku #2
72             Japanese Envelope Kaku #3
73             Japanese Envelope Chou #3
74             Japanese Envelope Chou #4
75             Letter Rotated (11 in x 8.5 in)
76             A3 Rotated (420 mm x 297 mm)
77             A4 Rotated (297 mm x 210 mm)
78             A5 Rotated (210 mm x 148 mm)
79             B4 (JIS) Rotated (364 mm x 257 mm)
80             B5 (JIS) Rotated (257 mm x 182 mm)
81             Japanese Postcard Rotated (148 mm x 100 mm)
82             Double Japanese Postcard Rotated (148 mm x 200 mm)
83             A6 Rotated (148 mm x 105 mm)
84             Japanese Envelope Kaku #2 Rotated
85             Japanese Envelope Kaku #3 Rotated
86             Japanese Envelope Chou #3 Rotated
87             Japanese Envelope Chou #4 Rotated
88             B6 (JIS) (128 mm x 182 mm)
89             B6 (JIS) Rotated (182 mm x 128 mm)
90             (12 in x 11 in)
91             Japanese Envelope You #4
92             Japanese Envelope You #4 Rotated
93             PRC 16K (146 mm x 215 mm)
94             PRC 32K (97 mm x 151 mm)
95             PRC 32K(Big) (97 mm x 151 mm)
96             PRC Envelope #1 (102 mm x 165 mm)
97             PRC Envelope #2 (102 mm x 176 mm)
98             PRC Envelope #3 (125 mm x 176 mm)
99             PRC Envelope #4 (110 mm x 208 mm)
100            PRC Envelope #5 (110 mm x 220 mm)
101            PRC Envelope #6 (120 mm x 230 mm)
102            PRC Envelope #7 (160 mm x 230 mm)
103            PRC Envelope #8 (120 mm x 309 mm)
104            PRC Envelope #9 (229 mm x 324 mm)
105            PRC Envelope #10 (324 mm x 458 mm)
106            PRC 16K Rotated
107            PRC 32K Rotated
108            PRC 32K(Big) Rotated
109            PRC Envelope #1 Rotated (165 mm x 102 mm)
110            PRC Envelope #2 Rotated (176 mm x 102 mm)
111            PRC Envelope #3 Rotated (176 mm x 125 mm)
112            PRC Envelope #4 Rotated (208 mm x 110 mm)
113            PRC Envelope #5 Rotated (220 mm x 110 mm)
114            PRC Envelope #6 Rotated (230 mm x 120 mm)
115            PRC Envelope #7 Rotated (230 mm x 160 mm)
116            PRC Envelope #8 Rotated (309 mm x 120 mm)
117            PRC Envelope #9 Rotated (324 mm x 229 mm)
118            PRC Envelope #10 Rotated (458 mm x 324 mm)

# DEPENDENCIES

    Tcl >= 8.6.7
    tdom >= 0.9.0

Reading .xlsx files uses the zlib command built into Tcl and needs no
additional package. Only if an archive cannot be handled by the
built-in reader (e.g. ZIP64), one of the optional fallback backends is
used: the Tcl 9 zipfs, tcllib's zipfile::decode or tclvfs vfs::zip >=
1.0.4.
