Simple tutorial for programmers
SYLK – SYmbolic LinK
Creating .slk spreadsheet files: cells, formulas, number formatting, fonts, and alignment
SYLK (SYmbolic LinK) is a plain-text spreadsheet interchange format with the .slk file extension. The code below was derived by saving files from Excel in SYLK format and reverse-engineering the output. It works reliably in Excel; OpenOffice support is limited. SYLK resources on the web are sparse, which is why some of the required syntax is difficult to explain.
ID is the file header, C defines a cell, P defines a format or font, F applies formatting, and E marks the end of the file.
Basic cells and formulas
Each C record places a value in a cell. Y is the row number, X is the column number, and K is the cell value (quoted for text, unquoted for numbers). Formulas follow a E parameter using R1C1 notation — R1C2 means row 1, column 2.
Rendered spreadsheet
| A | B | |
|---|---|---|
| 1 | Row 1 | 11 |
| 2 | Row 2 | 22 |
| 3 | Total | 33 |
Relative and function-based formulas
Instead of absolute R1C1 references you can use relative addressing with bracket notation, or standard spreadsheet functions. All three variants produce the same result:
The sylk1.slk example file contains all three formula types.
Number formatting
Formatting requires two steps: first, a table of format definitions using P records, then an F record to apply a format to a cell, row, or column. Format definitions are indexed from 0 — so the first P;P… line is P0, the second is P1, and so on.
The example below adds a dollar-sign format (P1) and applies it to row 3 (the total row). New lines are highlighted in green:
Rendered spreadsheet (with dollar formatting on row 3)
| A | B | |
|---|---|---|
| 1 | Row 1 | 1.1 |
| 2 | Row 2 | 2.2 |
| 3 | Total | $3.30 |
The full set of format strings produced by Excel is listed below. Any of these can be used as a P;P… record:
Download sylk2.slk to see the number formatting example in action.
Bold text and font definitions
To apply bold (or any other font attribute) you must first declare a font table using P;F… records, then reference the desired font index via an F record. The font table entries use F for the font name, M for size in half-points (so M200 = 10pt), and SB for bold. The E prefix on a font record denotes an alternate encoding entry.
Rendered spreadsheet (total cell bold)
| A | B | |
|---|---|---|
| 1 | Row 1 | 11 |
| 2 | Row 2 | 22 |
| 3 | Total | 33 |
Applying formatting to rows, columns, and alignment
The F record scope is controlled by appending RN or CN. Right-justification uses FG0R:
| SYLK record | Effect |
|---|---|
| F;SDM4 | Bold — applies to the current cell only |
| F;SDM4;R3 | Bold — applies to the entire row 3 |
| F;SDM4;C2 | Bold — applies to the entire column 2 |
| F;FG0R | Right-justify the current cell |
Rendered — full row 3 bold + column 2 right-justified
| A | B | |
|---|---|---|
| 1 | Row 1 | 11 |
| 2 | Row 2 | 22 |
| 3 | Total | 33 |
Download sylk4.slk for a single file demonstrating all of the above — cells, formulas, number formatting, bold, and alignment.
Option records
Option records set global parameters for the workspace and should appear near the top of the file, immediately after the ID record. Two are particularly useful in practice.
A1 flag — O;L
By default, some spreadsheet applications may display grid headings numerically (row 1 / column 1, and so on) rather than in the familiar A1 letter-and-number notation. Adding O;L explicitly instructs the application to render column headers as alphabetical letters (A, B, C…) and row headers as integers (1, 2, 3…):
Rendered spreadsheet (A1 notation active)
| A | B | |
|---|---|---|
| 1 | Column A, Row 1 | Column B, Row 1 |
| 2 | 100 | 200 |
| Component | Meaning |
|---|---|
| O | Option record — sets a global workspace parameter |
| ;L | A1 mode flag — columns display as letters (A, B, C…), rows as integers (1, 2, 3…) |
Bounds record — B;YN;XN
The B record declares the outer dimensions of the spreadsheet grid — the maximum row count (Y) and maximum column count (X). When the importing application sees this record it can immediately allocate a contiguous block of memory sized to fit the entire grid, rather than resizing dynamically as each cell record is read. For small files the difference is imperceptible, but for large datasets omitting it causes measurable load-time degradation as the parser is forced into repeated memory reallocation.
Place the B record after ID and any O records, before the first C record:
| Component | Meaning |
|---|---|
| B | Bounds record — declares the grid dimensions to the parser |
| ;YN | Maximum row index in the file (e.g. ;Y100 for 100 rows) |
| ;XN | Maximum column index in the file (e.g. ;X25 for 25 columns) |
B record that slightly overestimates the grid wastes a small amount of memory but parses at full speed. One that underestimates forces the same dynamic reallocation penalty as having no B record at all — the initial pre-allocated block must be discarded and rebuilt the moment a cell coordinate exceeds the declared bounds.