2022-05-16 03:26:04 +00:00
|
|
|
# Spreadsheet Features
|
|
|
|
|
2022-06-27 02:05:36 +00:00
|
|
|
import DocCardList from '@theme/DocCardList';
|
|
|
|
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
|
|
2022-05-16 03:26:04 +00:00
|
|
|
Even for basic features like date storage, the official Excel formats store the
|
|
|
|
same content in different ways. The parsers are expected to convert from the
|
|
|
|
underlying file format representation to the Common Spreadsheet Format. Writers
|
2022-08-25 08:22:28 +00:00
|
|
|
are expected to serialize SheetJS workbooks in the underlying file format.
|
2022-05-16 03:26:04 +00:00
|
|
|
|
2022-06-27 02:05:36 +00:00
|
|
|
The following topics are covered in sub-pages:
|
|
|
|
|
|
|
|
<ul>{useCurrentSidebarCategory().items.map((item, index) => {
|
2022-10-04 20:37:38 +00:00
|
|
|
const cP = item.customProps;
|
|
|
|
const listyle = (cP?.icon) ? { listStyleImage: `url("${cP.icon}")` } : {};
|
|
|
|
return ( <li style={listyle} {...(cP?.class ? {className: cP.class}: {})}>
|
|
|
|
<a href={item.href}>{item.label}</a>{cP?.summary && (" - " + cP.summary)}
|
|
|
|
</li> );
|
2022-06-27 02:05:36 +00:00
|
|
|
})}</ul>
|
|
|
|
|
2022-05-16 03:26:04 +00:00
|
|
|
## Row and Column Properties
|
|
|
|
|
|
|
|
<details>
|
|
|
|
<summary><b>Format Support</b> (click to show)</summary>
|
|
|
|
|
|
|
|
**Row Properties**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK, DOM, ODS
|
|
|
|
|
|
|
|
**Column Properties**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK, DOM
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
|
|
Row and Column properties are not extracted by default when reading from a file
|
|
|
|
and are not persisted by default when writing to a file. The option
|
|
|
|
`cellStyles: true` must be passed to the relevant read or write function.
|
|
|
|
|
|
|
|
_Column Properties_
|
|
|
|
|
|
|
|
The `!cols` array in each worksheet, if present, is a collection of `ColInfo`
|
|
|
|
objects which have the following properties:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
type ColInfo = {
|
|
|
|
/* visibility */
|
|
|
|
hidden?: boolean; // if true, the column is hidden
|
|
|
|
|
|
|
|
/* column width is specified in one of the following ways: */
|
|
|
|
wpx?: number; // width in screen pixels
|
2022-05-27 14:59:53 +00:00
|
|
|
width?: number; // width in Excel "Max Digit Width", width*256 is integral
|
2022-05-16 03:26:04 +00:00
|
|
|
wch?: number; // width in characters
|
|
|
|
|
|
|
|
/* other fields for preserving features from files */
|
|
|
|
level?: number; // 0-indexed outline / group level
|
2022-05-27 14:59:53 +00:00
|
|
|
MDW?: number; // Excel "Max Digit Width" unit, always integral
|
2022-05-16 03:26:04 +00:00
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
_Row Properties_
|
|
|
|
|
|
|
|
The `!rows` array in each worksheet, if present, is a collection of `RowInfo`
|
|
|
|
objects which have the following properties:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
type RowInfo = {
|
|
|
|
/* visibility */
|
|
|
|
hidden?: boolean; // if true, the row is hidden
|
|
|
|
|
|
|
|
/* row height is specified in one of the following ways: */
|
|
|
|
hpx?: number; // height in screen pixels
|
|
|
|
hpt?: number; // height in points
|
|
|
|
|
|
|
|
level?: number; // 0-indexed outline / group level
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
_Outline / Group Levels Convention_
|
|
|
|
|
|
|
|
The Excel UI displays the base outline level as `1` and the max level as `8`.
|
|
|
|
Following JS conventions, SheetJS uses 0-indexed outline levels wherein the base
|
|
|
|
outline level is `0` and the max level is `7`.
|
|
|
|
|
|
|
|
<details>
|
|
|
|
<summary><b>Why are there three width types?</b> (click to show)</summary>
|
|
|
|
|
|
|
|
There are three different width types corresponding to the three different ways
|
|
|
|
spreadsheets store column widths:
|
|
|
|
|
|
|
|
SYLK and other plain text formats use raw character count. Contemporaneous tools
|
|
|
|
like Visicalc and Multiplan were character based. Since the characters had the
|
|
|
|
same width, it sufficed to store a count. This tradition was continued into the
|
|
|
|
BIFF formats.
|
|
|
|
|
|
|
|
SpreadsheetML (2003) tried to align with HTML by standardizing on screen pixel
|
|
|
|
count throughout the file. Column widths, row heights, and other measures use
|
|
|
|
pixels. When the pixel and character counts do not align, Excel rounds values.
|
|
|
|
|
|
|
|
XLSX internally stores column widths in a nebulous "Max Digit Width" form. The
|
|
|
|
Max Digit Width is the width of the largest digit when rendered (generally the
|
|
|
|
"0" character is the widest). The internal width must be an integer multiple of
|
2022-08-19 06:42:18 +00:00
|
|
|
the width divided by 256. ECMA-376 describes a formula for converting between
|
|
|
|
pixels and the internal width. This represents a hybrid approach.
|
2022-05-16 03:26:04 +00:00
|
|
|
|
|
|
|
Read functions attempt to populate all three properties. Write functions will
|
|
|
|
try to cycle specified values to the desired type. In order to avoid potential
|
|
|
|
conflicts, manipulation should delete the other properties first. For example,
|
|
|
|
when changing the pixel width, delete the `wch` and `width` properties.
|
|
|
|
</details>
|
|
|
|
|
|
|
|
<details>
|
|
|
|
<summary><b>Implementation details</b> (click to show)</summary>
|
|
|
|
|
|
|
|
_Row Heights_
|
|
|
|
|
|
|
|
Excel internally stores row heights in points. The default resolution is 72 DPI
|
|
|
|
or 96 PPI, so the pixel and point size should agree. For different resolutions
|
|
|
|
they may not agree, so the library separates the concepts.
|
|
|
|
|
|
|
|
Even though all of the information is made available, writers are expected to
|
|
|
|
follow the priority order:
|
|
|
|
|
|
|
|
1) use `hpx` pixel height if available
|
|
|
|
2) use `hpt` point height if available
|
|
|
|
|
|
|
|
_Column Widths_
|
|
|
|
|
2022-08-25 08:22:28 +00:00
|
|
|
Given the constraints, it is possible to determine the `MDW` without actually
|
2022-05-16 03:26:04 +00:00
|
|
|
inspecting the font! The parsers guess the pixel width by converting from width
|
2022-08-25 08:22:28 +00:00
|
|
|
to pixels and back, repeating for all possible `MDW` and selecting the value
|
|
|
|
that minimizes the error. XLML actually stores the pixel width, so the guess
|
|
|
|
works in the opposite direction.
|
2022-05-16 03:26:04 +00:00
|
|
|
|
|
|
|
Even though all of the information is made available, writers are expected to
|
|
|
|
follow the priority order:
|
|
|
|
|
|
|
|
1) use `width` field if available
|
|
|
|
2) use `wpx` pixel width if available
|
|
|
|
3) use `wch` character count if available
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
## Sheet Visibility
|
|
|
|
|
2022-05-23 03:37:51 +00:00
|
|
|
<details>
|
|
|
|
<summary><b>Format Support</b> (click to show)</summary>
|
|
|
|
|
|
|
|
**Hidden Sheets**: XLSX/M, XLSB, BIFF8/BIFF5 XLS, XLML
|
|
|
|
|
|
|
|
**Very Hidden Sheets**: XLSX/M, XLSB, BIFF8/BIFF5 XLS, XLML
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
2022-05-16 03:26:04 +00:00
|
|
|
Excel enables hiding sheets in the lower tab bar. The sheet data is stored in
|
|
|
|
the file but the UI does not readily make it available. Standard hidden sheets
|
|
|
|
are revealed in the "Unhide" menu. Excel also has "very hidden" sheets which
|
|
|
|
cannot be revealed in the menu. It is only accessible in the VB Editor!
|
|
|
|
|
|
|
|
The visibility setting is stored in the `Hidden` property of sheet props array.
|
|
|
|
|
2022-05-23 03:37:51 +00:00
|
|
|
| Value | Definition | VB Editor "Visible" Property |
|
|
|
|
|:-----:|:------------|:-----------------------------|
|
|
|
|
| 0 | Visible | `-1 - xlSheetVisible` |
|
|
|
|
| 1 | Hidden | ` 0 - xlSheetHidden` |
|
|
|
|
| 2 | Very Hidden | ` 2 - xlSheetVeryHidden` |
|
2022-05-16 03:26:04 +00:00
|
|
|
|
2022-05-23 03:37:51 +00:00
|
|
|
If the respective Sheet entry does not exist or if the `Hidden` property is not
|
|
|
|
set, the worksheet is visible.
|
2022-05-16 03:26:04 +00:00
|
|
|
|
2022-08-25 08:22:28 +00:00
|
|
|
**List all worksheets and their visibility settings**
|
2022-05-16 03:26:04 +00:00
|
|
|
|
|
|
|
```js
|
2022-05-23 03:37:51 +00:00
|
|
|
wb.Workbook.Sheets.map(function(x) { return [x.name, x.Hidden] })
|
|
|
|
// [ [ 'Visible', 0 ], [ 'Hidden', 1 ], [ 'VeryHidden', 2 ] ]
|
2022-05-16 03:26:04 +00:00
|
|
|
```
|
|
|
|
|
2022-05-23 03:37:51 +00:00
|
|
|
**Check if worksheet is visible**
|
|
|
|
|
2022-05-16 03:26:04 +00:00
|
|
|
Non-Excel formats do not support the Very Hidden state. The best way to test
|
|
|
|
if a sheet is visible is to check if the `Hidden` property is logical truth:
|
|
|
|
|
|
|
|
```js
|
2022-05-23 03:37:51 +00:00
|
|
|
wb.Workbook.Sheets.map(function(x) { return [x.name, !x.Hidden] })
|
|
|
|
// [ [ 'Visible', true ], [ 'Hidden', false ], [ 'VeryHidden', false ] ]
|
|
|
|
```
|
|
|
|
|
|
|
|
<details>
|
|
|
|
<summary><b>Live Example</b> (click to show)</summary>
|
|
|
|
|
|
|
|
|
|
|
|
[This test file](pathname:///files/sheet_visibility.xlsx) has three sheets:
|
|
|
|
|
|
|
|
- "Visible" is visible
|
|
|
|
- "Hidden" is hidden
|
|
|
|
- "VeryHidden" is very hidden
|
|
|
|
|
|
|
|
![Screenshot](pathname:///files/sheet_visibility.png)
|
|
|
|
|
|
|
|
**Live demo**
|
|
|
|
|
|
|
|
```jsx live
|
|
|
|
function Visibility(props) {
|
|
|
|
const [sheets, setSheets] = React.useState([]);
|
|
|
|
const names = [ "Visible", "Hidden", "Very Hidden" ];
|
|
|
|
|
|
|
|
React.useEffect(async() => {
|
|
|
|
const f = await fetch("/files/sheet_visibility.xlsx");
|
|
|
|
const ab = await f.arrayBuffer();
|
|
|
|
const wb = XLSX.read(ab);
|
|
|
|
|
|
|
|
/* State will be set to the `Sheets` property array */
|
|
|
|
setSheets(wb.Workbook.Sheets);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
return (<table>
|
|
|
|
<thead><tr><th>Name</th><th>Value</th><th>Hidden</th></tr></thead>
|
|
|
|
<tbody>{sheets.map((x,i) => (<tr key={i}>
|
|
|
|
|
|
|
|
<td>{x.name}</td>
|
|
|
|
|
|
|
|
<td>{x.Hidden} - {names[x.Hidden]}</td>
|
|
|
|
|
|
|
|
<td>{!x.Hidden ? "No" : "Yes"}</td>
|
|
|
|
|
|
|
|
</tr>))}</tbody></table>);
|
|
|
|
}
|
|
|
|
|
2022-05-16 03:26:04 +00:00
|
|
|
```
|
2022-05-23 03:37:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2022-05-16 03:26:04 +00:00
|
|
|
</details>
|
|
|
|
|