| 
									
										
										
										
											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. | 
					
						
							| 
									
										
										
										
											2023-06-20 01:21:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-16 03:26:04 +00:00
										 |  |  | </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> |