Release notes
Tabula 0.33.0
Table headers, and the filter dropdowns that hang off them.
A table whose data is text under text labels — Name | City over Ada | London — was being created without a header row, and so without the ▾ filter buttons. The header guess came from the one written for sorting, which looks for a bold top row or a label sitting over numbers; an all-text table trips neither. Turning a range into a table now treats a first row of plain labels as headers, the way Excel's Insert Table ticks "My table has headers" by default.
Because no guess is always right, the Table tab gained a Header toggle beside Total. Switching it on gives an existing table its header row and its filter dropdowns; switching it off clears any filters with it, so no rows are left hidden behind a checklist that can no longer be opened.
Tables look like tables
A table's header and totals rows now render in bold, with a rule under the header and above the totals, so the structural rows read as structure rather than as differently-tinted data. As with the row banding, this is display only: the cells' own formatting is untouched, so a file round-trips unchanged and removing the table leaves everything looking as it did.
Bold text was rendering in the wrong typeface
Any bold cell was being drawn in a monospace face while its unbolded neighbours were proportional. The text engine's default sans-serif family was set to a font that ships on no Mac or Windows machine, and the fallback that followed was resolved separately per weight — landing on a sensible font for regular text and a monospace one for bold. The generic families are now pointed at fonts the machine actually has. Bold table headers made this impossible to miss; it had been affecting every bold cell.
Tabula 0.32.0
Increase and Decrease Decimal.
Two new buttons in the Home tab's Number group, beside $ % , — a .00 with a plus and with a minus. They add or remove one decimal place from whatever the selected cells already show, without disturbing anything else about the format: a percentage stays a percentage, currency stays currency, and a custom code keeps its text and its colour sections.
A cell on General steps from what it is currently displaying, so a cell showing 1.5 becomes 1.50 on the first click rather than jumping to some fixed precision.
Select several cells — or a whole column — and they all land on one number of decimal places, so a ragged column lines up on the first click and steps together after that. The shared count comes from the cell showing the most places, which means Increase never hides a digit that was on screen: a column of 1.5, 2.25, 3.756 and 1234 goes to four places, not down to one. Only the count is shared — a percentage in the selection stays a percentage, currency stays currency. A blank cell in the middle of the range doesn't skew the count, but it does take the format, so a number typed there later matches its neighbours.
Cells with no decimals to speak of — dates, times, text, fractions — are left alone. (Excel reinterprets a date as its serial number here and starts showing 45678.0; this seemed worth not copying.)
Computed numbers no longer show binary noise
A calculated value like 0.1 + 0.2 is stored as 0.30000000000000004, and a General cell used to display every digit of it. Numbers now show at 15 significant digits — the precision a spreadsheet carries, and what Excel shows — so that cell reads 0.3.
This is a display change only: the full value is kept, and editing a cell still shows every digit, so nothing is lost by opening a cell and pressing Enter. It also fixes a confusing interaction with the new decimal buttons, which act on the precision a cell is showing: against seventeen digits of noise, the first click on Increase Decimal collapsed the cell to two digits and zeros, looking for all the world like it had thrown the rest away.
Tabula 0.31.0
Absolute and mixed references — $A$1.
A $ pins the part of an address that follows it, so a formula copied elsewhere keeps pointing where it should. All four forms work:
| Written | When you copy it |
|---|---|
A1 | both parts move |
$A$1 | neither moves |
$A1 | the row moves, the column stays |
A$1 | the column moves, the row stays |
So =B1*$A$1 filled down a column multiplies every amount by the one rate in A1, instead of walking down the sheet and multiplying by blanks. The mixed forms handle the cases a single "absolute" flag can't — $A1 down a column of rates, A$1 across a header row, and both together for a multiplication table.
Each end of a range anchors on its own, so =SUM($A$1:A5) filled downward grows into =SUM($A$1:A6) — the usual way to write a running total.
Press F4 while editing to cycle the reference at the caret through the four forms, the way Excel does. With the caret in a range it anchors both ends at once, so pinning a lookup table is one keystroke.
Anchoring governs copying only. Inserting and deleting rows or columns still move every reference to the cells that moved, $ or not — $A$5 becomes $A$6 when a row is inserted above it, because the cell it names moved.
Previously Tabula accepted $ and then ignored it, so a formula written with anchors behaved as though it had none — and quietly broke when filled.
Tabula 0.30.1
A fix for the spell-check underline.
Misspelled words were marked with two rows of red dots, one above the other, instead of a single wavy underline. They now get a proper red squiggle — one continuous zig-zag that scales with the cell's font size and with zoom.
Tabula 0.30.0
Rich text — format individual characters inside a cell.
Per-character formatting
A cell no longer has to be all one style. Double-click into a cell, select some of the text, and the Font group applies to just that: bold, italic, underline, strikethrough, superscript, subscript, font size and text colour. So a single cell can read Total: $500 due now with Total: in bold and $500 in red.
The styling appears as you apply it, right in the cell you're editing, and it stays attached to the characters it belongs to as you keep typing — insert a word in front and the bold stays on the word that was bold. Typing at the end of a styled word continues in that style, as in any text editor. Pressing Escape abandons the styling along with the rest of the edit, and everything commits as one undo step.
With nothing selected, the Font buttons still format the whole cell as they always did — and doing so now correctly restyles a cell that already has per-character formatting.
Files from Excel keep their formatting
Excel files containing rich text — a bold word in a label, a coloured figure inside a sentence — now open, display and save with that formatting intact. Previously the styling was lost on save. Mixed sizes sit on a shared baseline, mixed fonts shape correctly together, and an underline that runs across a line break in a wrapped cell is underlined on both lines.
Rich text prints
PDF export renders each run in its own weight and slant, with underlines, strikethroughs, superscripts and subscripts — so a printed sheet matches what's on screen rather than flattening to one style.
Also in this release
- An I-beam cursor while editing. Inside the cell you're editing the pointer is a text caret, since clicking there positions the caret. Everywhere else it stays the cell cursor — clicking another cell mid-formula still points at it.
- AutoFit understands mixed sizes. Fitting a column to its contents now measures each run, so a large word inside an ordinary cell no longer produces a column too narrow to hold it.
- Spell check works on styled text, marking misspellings in a cell whose characters carry different formats.
Tabula 0.29.0
Merged cells and a right-click menu — plus a round of Excel-compatibility fixes for opening real-world files.
Merged cells
Merge a block of cells into one. The Home tab's Alignment group has a new Merge dropdown — and every command is in the right-click menu too — with:
- Merge & Center — merge the selection and centre the value.
- Merge Across — merge each row of the selection on its own.
- Merge Cells — merge without changing alignment.
- Unmerge Cells — split a merged region back into cells.
Merging keeps the upper-left value and, if the other cells hold data, asks before discarding them — all in a single undo step. A merged cell selects, navigates, and edits as one unit, and borders wrap the whole region.
Most importantly, existing .xlsx files that use merged cells now open, display, and save correctly. Before this release Tabula silently dropped merges on save; they now round-trip as standard Excel <mergeCells>.
Right-click menu on the grid
Right-click any cell or selection for the common actions: Cut, Copy, Paste, Paste Special, Clear Contents, the four Merge / Unmerge commands, Edit Note, and Format Cells. Items that don't apply are greyed out — Paste with an empty clipboard, Merge on a range that's already merged, Unmerge on one that isn't. Right-clicking outside your selection selects that cell first; right- clicking inside a multi-cell selection keeps the whole block, so a menu command acts on what you had selected.
A white sheet in dark mode
The spreadsheet area now stays paper-white with dark text regardless of the system theme, like Excel and Word — only the surrounding chrome (ribbon, tabs, menus, dialogs) follows dark mode. A file's own cell colours now land on the white background they were designed for.
Fixes — opening files from Excel
A batch of fidelity fixes, most of which show up when opening files created in Excel:
Theme and tinted colours. Excel writes most ribbon colours as a theme reference plus a tint (e.g. "Blue, Accent 1, Lighter 40%"), and older files use an indexed palette. Tabula previously read only literal RGB, so those fills and font colours came through blank. It now resolves theme colours (from the workbook's colour scheme), applies the tint, and understands the legacy indexed palette.
Accounting and Comma number formats. The common "Comma Style" format and its relatives weren't recognised, so those cells fell back to General — numbers lost their thousands separators and a zero showed as 0. They now format correctly: 11200 shows as 11,200.00, and an accounting zero shows as -, exactly as in Excel.
Wrong fonts on some rows. Two font bugs are fixed: a cell explicitly marked not bold could come out bold, and a quirk in how the style table was read could give some rows an entirely wrong (over-large) font.
Gridlines over filled cells. A cell with a background fill now hides its gridlines, the way Excel does — so a coloured block reads as solid instead of being boxed into a grid.
Text overflowing onto numbers. A long label in one column used to spill over and overlap the value in the next column. It now stops at the first filled cell, like Excel — spilling only across genuinely empty cells.
Tabula 0.28.0
Sort, Tables, Filter — the Data toolkit.
- Sort: Data tab → A→Z / Z→A sorts by the active cell's column. A single cell auto-expands to its data block, headers are detected and stay put, rows move whole (values, formats, notes), formulas re-anchor to their new row, blanks always sink, and it's one undo step.
- Tables: Insert tab → Table turns a range into a named table with an accent header band, banded rows, and an outline. A contextual Table tab appears whenever you're inside one, showing the table's name plus icon buttons for row/column insert & delete (which shift only within the table), a Total toggle, and Remove. Tables survive row/column edits and save as real Excel
<table>parts. - Filter: every table header gets a ▾ dropdown with a checklist of the column's values — uncheck to hide those rows. Filtered rows stay separate from manually hidden ones, print as shown, and round-trip the way Excel stores them.
- Live totals: the Total row uses
SUBTOTAL(109, …), newly implemented in the formula engine with Excel's visibility rules — so filtering a table recalculates its total to just the visible rows. All SUBTOTAL variants (SUM/AVERAGE/COUNT/COUNTA/MAX/MIN, 1–9 and 101–109) are available in your own formulas too. - Structured references: formulas can name a table column directly —
=SUBTOTAL(109,Table1[Amount])— case-insensitive, spaces allowed (Table1[Unit Price]), from any sheet in the workbook.
Tabula 0.27.1
A fix for auto-update, plus cross-sheet access for macros.
The updater used to apply a downloaded update only as the app quit, via a Rust destructor — but macOS skips that path when you quit with Cmd+Q, so the new version would download and then never install. The swap is now started the moment the update is downloaded; it still waits for the app to fully quit (any way you quit) before replacing the bundle, so nothing is disrupted mid-session and the next launch is the new version. Every step is now logged to ~/Library/Logs/Tabula/update.log, so a stuck update can be diagnosed.
> Note: because the currently installed app carries the old updater, this build > must be installed by hand once. Auto-update works from here forward — and a > release is only picked up if it's a full (non-pre-release) publish with a > higher version tag and a .zip of the signed, notarized app attached.
Macros can also now reach other sheets: set_cell("Data!A1", …) / get_cell("Data!A1") target a named sheet (case-insensitive, 'quoted' for spaces), while a bare A1 still means the active sheet.
Tabula 0.27.0
Python scripts can now change cells, not just return values from formulas.
Write a main() function in the Developer panel and click Run to execute it as a macro. Two new built-ins give it access to the sheet:
``python def main(): total = 0 for i in range(1, 11): set_cell("A" + str(i), i) # write A1..A10 = 1..10 total = total + i set_cell("B1", total) # write the running total set_cell("C1", get_cell("B1") * 2) # read a cell you just wrote ``
set_cell("A1", value)writes a value into a cell.get_cell("A1")reads a cell's current value (including writes made earlier in the same run).
Addresses can also reach other sheets: set_cell("Data!A1", …) writes the "Data" sheet, 'Q1 Actuals'!B2 quotes a name with spaces, and a bare A1 means the active sheet. Sheet names match case-insensitively.
All the writes are applied together as one undo step, and the sheet recalculates afterward — so a script can build tables, fill sequences, or transform data in one click. Scripts with no main() keep working exactly as before: their functions stay callable from formulas.
Tabula 0.26.0
Polish for the Format Painter. The Home-tab button is now a paintbrush icon instead of the word "Painter", and while it's armed the source cell shows a dashed outline — so you can always see which cell's formatting you're about to copy.
Tabula 0.25.0
Two familiar productivity tools: the Format Painter and AutoFit.
Format Painter
Click a cell, hit Painter in the Home tab's Clipboard group, then click (or drag across) the cells you want to copy that formatting onto — bold, colors, number format, borders, and the rest all come across in one step. The button stays lit while it's armed; press Esc to cancel. It's one undo step.
AutoFit column & row
On the View tab, Fit W resizes the selected columns to fit their widest content, and Fit H resizes the selected rows to their tallest font. Or just double-click a column or row border — the same shortcut you use in Excel. Handy after pasting data or bumping a font size.
Tabula 0.24.0
More text formatting: underline, strikethrough, and superscript / subscript.
Four new buttons in the Home tab's Font group apply these to the selection, toggling like Bold and Italic (superscript and subscript are mutually exclusive). Each button previews what it does — an underlined "U", a struck-through "S", and x² / x₂. Underline and strikethrough draw as crisp bars across the text; super/subscript shrink the run and raise or lower it. All of them round-trip to .xlsx as standard OOXML font attributes (<u/>, <strike/>, <vertAlign>), so files open correctly in Excel.
Tabula 0.23.0
Tabula now keeps itself up to date — completely on its own.
Automatic updates
On launch, Tabula quietly checks its release repository for a newer build in the background. If one is available it downloads it, and installs it when you quit — so the next time you open Tabula, it's the new version. No prompts, no interruptions, and it never closes or restarts while you're working.
Everything runs on a background thread, so the app never freezes while checking or downloading, and it adds no new dependencies — the network calls use the curl that ships with macOS, and the release metadata is parsed by a small built-in JSON reader, preserving Tabula's clean, C-free cross-compile. (macOS only for now; the release must ship a signed, notarized .zip of the app.)
Tabula 0.22.0
Complete, Excel-compatible number formats — including the ability to write your own custom format codes.
Format Cells dialog
A new Format… button in the Home tab's Number group (and the full dialog behind it) lets you pick from every standard category — General, Number, Currency, Accounting, Date, Time, Percentage, Scientific, Fraction, and Text — with a live Sample of the active cell and controls for decimal places, the thousands separator, fraction precision, and date/time styles.
Custom format codes
Pick the Custom category (or just start typing in the Type box) and write any Excel format code:
``` #,##0.00;Red 1,234.50 / (1,234.50) in red $#,##0.00 $1,234.50 0.00% 25.60% 0.00E+00 1.23E+04
?/? 2 1/2
yyyy-mm-dd 2025-01-05 h:mm AM/PM 6:00 AM [$€-407]#,##0.00 €1,234.50 ```
Under the hood is a from-scratch, pure-Rust format-code engine. It understands up to four sections separated by ; (positive; negative; zero; text), digit placeholders (0 # ?), thousands grouping and trailing-comma scaling, one or more %, scientific and engineering notation, fractions, quoted and escaped literals, [$symbol] currency, [Red]/[Blue]/… colours, [>=n] conditions, and the full set of date/time tokens including elapsed [h], [m], [s]. Negative-in-red and similar colour codes paint in the grid.
Faithful .xlsx round-trip
Custom codes are written to and read from .xlsx verbatim, so a format Excel (or anyone else) authored is preserved rather than flattened. The built-in presets round-trip as themselves, and the common Excel builtin format ids (dates, times, currency, scientific, fractions) are recognised on import.
Tabula 0.21.0
A round of work on Tabula's Python scripting: a quicker way to write Python in a cell, ranges that arrive as lists, and a much better code editor.
Python in a cell, without the quotes
You can now write a Python expression in a cell with =py, referencing other cells by their address directly:
`` =py A1 * 2 + B1 =py sum(A1:A10) =py round(sum(A1:A10) / len(A1:A10), 2) ``
This is the quote-free companion to the existing =PY("…", A1, B1) form. Write the expression after =py , and refer to cells by their uppercase address (A1, B2); a range like A1:A10 comes in as a list. References must be uppercase so they can be told apart from Python variables — a lowercase a1 is a variable, not a cell.
Behind the scenes =py is just shorthand: it rewrites to the PY(...) call it's equivalent to, so it recalculates, tracks which cells it depends on, and handles ranges exactly the same way. Autocomplete offers py alongside PY( as you type. A short guide with worked examples is in docs/PYTHON_IN_CELLS.md.
Two limits worth knowing: a =py cell references cells on its own sheet (use the PY("…", 'Sheet'!A1) form to reach another sheet), and because Excel has no equivalent, a =py cell opened in Excel shows its last computed value rather than the live expression.
Ranges as lists in your functions
A range argument now reaches a Python function as a list instead of an error. =py sum(A1:A10) works, and so does passing a range to one of your own functions:
``python def average(nums): return sum(nums) / len(nums) ``
`` =AVERAGE(A1:A10) ``
A single row or column arrives as a flat list; a rectangular range like A1:C3 arrives as a list of rows, so you can walk it with nested loops.
A real code editor
The Developer panel's code editor grew the things that make one usable:
- Line numbers down the left.
- Syntax highlighting — keywords, strings, comments, numbers and built-ins are coloured (and the colours follow the light/dark theme).
- Text selection by click-and-drag, Shift+click, Shift+arrows, or double-clicking a word.
- Cut, copy and paste, from a small toolbar at the top of the editor or with the usual ⌘/Ctrl+X / C / V, through the system clipboard — so you can move code in and out of other apps.
- An I-beam cursor over the code, and the caret now lands exactly where you click, on the right character, regardless of font width.
Tabula 0.20.0
Two reviewing features: cell notes and live spell check.
Cell notes
Attach a note to any cell — a comment that travels with the cell but stays out of its value. On the new Review tab, Note opens a small editor for the active cell (Shift+Enter for a new line, Enter or Save to keep it, Escape to cancel); saving an empty note deletes it. Delete removes the active cell's note. Both are undoable with Ctrl+Z.
A noted cell is marked by a small red triangle in its top-right corner, and hovering it shows the note as a floating yellow box — the familiar sticky-note look, which reads the same in light or dark mode. Notes move with their cells when you insert or delete rows and columns, and are dropped when the cell's row or column is deleted.
Notes are saved in the .xlsx file as standard cell comments, so they persist across save and reopen and interoperate with Excel. For now every note is saved without an author name and shown as "Note"; a per-user name will come later.
Spell check
Misspelled words are underlined in place with a red squiggle as you work, checked against a bundled English dictionary of about 128,000 words. It's on by default; the Spelling toggle on the Review tab turns it off.
The checker is deliberately conservative about what it flags, so the squiggles stay meaningful: it skips words shorter than two letters, all-capitals words (usually acronyms or codes), and words with accented or non-English letters (so names aren't underlined against an English list). Contractions like "don't" and possessives like "cat's" are understood and left alone.
This is a first version. The squiggles are informational only — there's no right-click list of suggested corrections yet, and no way to add a word to the dictionary. Both are planned.
Tabula 0.19.0
Two features for working with text and layout — Find & Replace, and Center Across Selection — plus a set of rendering fixes to zooming and cell borders.
Find and Replace
Search the active sheet for text and, when you want, replace it. Press ⌘F (Ctrl+F on Windows and Linux) to open Find, or ⌘H (Ctrl+H) to open the same dialog with the replacement field ready. Enter finds the next match; Tab moves between the Find and Replace fields; Escape closes.
Each match is selected and scrolled into view as you step through it, and the dialog shows your position — "3 of 12" — so you always know how many matches there are and where you are among them. Find Next and Prev wrap around the ends of the sheet.
Two options refine what counts as a match: Match case distinguishes Total from total, and Match entire cell requires the whole cell to equal the search text rather than merely contain it. Replace changes the current match and moves to the next; Replace All changes every match at once, and the whole operation is a single Ctrl+Z away.
What's searched is what you'd type into a cell — a formula's source for a formula cell, the value otherwise — so finding and replacing stay in step with how a cell is entered. Search covers the active sheet, which is Excel's default; whole- workbook search and regular expressions aren't included yet, and the dialog is keyboard-only for now with no ribbon button.
Center across selection
Center a heading across several columns without merging the cells. Put the text in the leftmost cell, select across the columns you want it centered over, and click the Center Across button in the Home tab's Alignment group. The text stays in its own cell — only its display spans the empty cells to the right — so none of the problems that merged cells cause for sorting, selection, copy and paste, or inserting and deleting rows apply here. Click the button again to turn it off.
This is the non-destructive alternative to Merge & Center, and it's exactly how Excel's "Center Across Selection" behaves. It saves to .xlsx in the standard way (as centerContinuous), so a centered heading round-trips with Excel unchanged.
To draw a box around a centered heading, select the span and use the Outline border preset — the box lands exactly on the edges of the centered run. Because the cells aren't actually merged, All Borders will show the interior column lines, just as Excel does.
The Wrap and Center Across controls in the Alignment group are now icons rather than text labels, which frees up room on the ribbon.
Fixes
Cell contents disappeared when zooming. Zooming in and out far enough could make the text in cells vanish. Each zoom level renders glyphs at a new size, and the cache that holds them is a fixed size; once it filled with sizes from earlier zoom levels, newly needed glyphs had nowhere to go and were silently dropped. The cache now clears and rebuilds itself when it runs out of room, so text keeps rendering at any zoom.
Borders between two bordered cells looked twice as thick. A line shared by two neighbouring cells was being painted once from each side, and the two strokes read as a single heavy line — noticeably thicker than a border along the edge of the block. Borders are now drawn so that each shared line has a single owner and is painted exactly once, giving uniform line weight throughout a bordered range — both on screen and in printed (PDF) output.
Default cell borders were invisible in dark mode. The standard border colour is a dark grey chosen to read on a white sheet, and it disappeared against the dark background in dark mode. Borders left at the default colour now follow the theme — the same dark grey in light mode, a light grey in dark mode — so they're visible either way. A border you've given an explicit colour is unaffected.
Tabula 0.12.0
Three features that make Tabula workable on real, larger spreadsheets: named ranges, frozen panes, and hiding rows and columns. All three persist to .xlsx, and all three are undoable with Ctrl+Z like any other edit.
Hiding rows and columns first shipped in 0.11.0; named ranges and frozen panes are new in 0.12.0.
Named ranges
Give a block of cells a name and use it in formulas. Select a range, click the Name Box at the left of the formula bar, type a name, and press Enter. From then on =SUM(Sales) works exactly as =SUM(B2:D10) would.
The Name Box does three jobs. Typing a name that already exists jumps to it and selects its range, so it doubles as Go To. Typing a cell reference such as D42 goes there. Anything else defines a new name over whatever is currently selected. When your selection happens to match a named range exactly, the Name Box shows the name instead of the cell reference — that's the confirmation that a definition took.
Named ranges appear in formula autocomplete alongside the built-in functions, labelled with the range they cover, so typing =SUM(Sa will offer Sales — Named range B2:D10. Unlike a function, accepting one inserts just the name with no opening bracket.
Names are case-insensitive, as in Excel: sales, Sales, and SALES all refer to the same range, and the spelling you typed is the one displayed. Names that would be ambiguous are refused — anything that reads as a cell reference (A1, ZZ100), anything starting with a digit, and anything containing spaces.
Two limitations worth knowing. A name currently resolves only on the sheet it points at; using a name from another sheet gives #NAME? rather than a value, and this will be resolved when cross-sheet references land. And there's no name manager dialog yet — to change a name's range, select the new range and define the same name again; there's no way to delete one from the interface.
Frozen panes
Pin heading rows and columns so they stay put while the rest of the sheet scrolls. Select the first cell that should scroll and use Freeze on the View tab. Selecting B2 pins row 1 and column A; selecting A2 pins the top row only; selecting B1 pins the first column only. Unfreeze clears both.
That "select the first cell that should scroll" rule is Excel's, and it's the one thing people usually get backwards the first time. A divider line marks each split so the pinned bands read as pinned rather than as a redraw glitch.
Freezing resets the scroll position, because pinning rows that had already been scrolled out of view would fix them somewhere you can't see them.
Frozen panes are saved with the file and restored on open. Excel's draggable (unfrozen) splits aren't modelled — a file that uses one opens without a split rather than with a guess at one.
Hiding rows and columns
Right-click a column or row header and choose Hide, or use the Hide and Unhide buttons on the View tab. The menu names what it will act on, so it reads "Hide 3 columns" when three are selected. Right-clicking a header that isn't already part of your selection selects it first, so the menu always acts on what you pointed at.
Hidden rows and columns keep their contents and their formulas — formulas that reference a hidden cell go on working exactly as before. Hiding is purely visual.
To bring something back, select across the gap and choose Unhide: selecting columns B through D reveals a hidden column C. This is how Excel works too, and it's a consequence of hidden columns having no width — there's nothing to click on, so you reach around them.
One limitation: a hidden row containing no data isn't currently saved to .xlsx, so it reappears when the file is reopened. Hidden rows with content are saved correctly, as are all hidden columns.
Fixes
Files with frozen panes were rejected by Excel. Saving a sheet with frozen panes produced a file that Excel opened with "we found a problem with some content" and offered to repair. The .xlsx format fixes the order in which elements may appear inside a worksheet, and the freeze-pane element was being written one position too early. Other tools — including openpyxl — accepted the file without complaint, which is what let it through.
This is fixed. If you saved a file with frozen panes on 0.12.0 before this fix, open it in Tabula and save it again to correct it; no data was lost, only the file's structure was wrong.
A saved named range wasn't offered by autocomplete. Names survived being saved and reloaded, but the autocomplete list was only rebuilt when a recalculation happened, and opening a file didn't trigger one. A name defined in one session and used in the next wasn't suggested until you happened to make an unrelated edit. Files are now recalculated on open.
Notes for this release
Everything above is undoable, including hiding, freezing, and defining a name.
The .xlsx writer now emits definedNames, pane, and the hidden attributes on rows and columns, and the reader understands all of them. Files written by Tabula continue to be regenerated from scratch rather than patched, so parts of a file that Tabula doesn't model — charts, conditional formatting, images — are still not preserved through a round trip.