props
This commit is contained in:
parent
c761e870f7
commit
3553757e8d
@ -35,8 +35,9 @@ This demo was tested in the following configurations:
|
||||
|
||||
| Date | Platform |
|
||||
|:-----------|:--------------------------------------------------------------|
|
||||
| 2024-08-09 | NVIDIA RTX 4090 (24 GB VRAM) + i9-10910 (128 GB RAM) |
|
||||
| 2024-08-31 | NVIDIA RTX 4090 (24 GB VRAM) + i9-10910 (128 GB RAM) |
|
||||
| 2024-08-09 | NVIDIA RTX 4080 SUPER (16 GB VRAM) + i9-10910 (128 GB RAM) |
|
||||
| 2024-09-21 | AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) |
|
||||
| 2024-07-15 | Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) |
|
||||
|
||||
SheetJS users have verified this demo in other configurations:
|
||||
@ -56,6 +57,7 @@ SheetJS users have verified this demo in other configurations:
|
||||
| LangChainJS | NVIDIA RTX 2060 (6 GB VRAM) + Ryzen 5 3600 (32 GB RAM) |
|
||||
| LangChainJS | NVIDIA GTX 1080 (8 GB VRAM) + Ryzen 7 5800x (64 GB RAM) |
|
||||
| LangChainJS | NVIDIA GTX 1070 (8 GB VRAM) + Ryzen 7 7700x (32 GB RAM) |
|
||||
| LangChainJS | AMD RX 6800 XT (16 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) |
|
||||
|
||||
</details>
|
||||
|
||||
@ -65,6 +67,7 @@ Special thanks to:
|
||||
- [Triston Armstrong](https://tristonarmstrong.com/)
|
||||
- [Ben Halverson](https://benhalverson.dev/)
|
||||
- [Navid Nami](https://github.com/CaseoJKL)
|
||||
- [Benjamin Gregg](https://bgregg.dev/)
|
||||
- [`@Smor`](https://smor.dev/)
|
||||
- [`@timbr`](https://timbr.dev/)
|
||||
- [`@n3bs`](https://github.com/0xn3bs)
|
||||
|
@ -36,7 +36,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| Browser | Version | Date |
|
||||
|:-------------|:------------------|:-----------|
|
||||
| Chromiun 125 | `1.8.2` (latest) | 2024-06-09 |
|
||||
| Chromium 125 | `1.8.2` (latest) | 2024-06-09 |
|
||||
| Chromium 125 | `1.2.32` (legacy) | 2024-06-09 |
|
||||
|
||||
:::
|
||||
@ -86,9 +86,9 @@ app.controller('sheetjs', function($scope, $http) {
|
||||
method:'GET', url:'https://docs.sheetjs.com/pres.xlsx',
|
||||
/* ensure the result is an ArrayBuffer object */
|
||||
responseType:'arraybuffer'
|
||||
}).then(function(data) {
|
||||
}).then(function(response) {
|
||||
// highlight-next-line
|
||||
var wb = XLSX.read(data.data);
|
||||
var wb = XLSX.read(response.data);
|
||||
/* generate HTML from first worksheet*/
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
var html = XLSX.utils.sheet_to_html(ws);
|
||||
@ -200,8 +200,8 @@ app.controller('sheetjs', function($scope, $http) {
|
||||
$http({
|
||||
url:'https://docs.sheetjs.com/pres.xlsx',
|
||||
method:'GET', responseType:'arraybuffer'
|
||||
}).then(function(data) {
|
||||
var wb = XLSX.read(data.data);
|
||||
}).then(function(response) {
|
||||
var wb = XLSX.read(response.data);
|
||||
// highlight-next-line
|
||||
$scope.data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
|
||||
}, function(err) { console.log(err); });
|
||||
@ -277,8 +277,8 @@ app.controller('sheetjs', function($scope, $http) {
|
||||
$http({
|
||||
url:'https://docs.sheetjs.com/pres.xlsx',
|
||||
method:'GET', responseType:'arraybuffer'
|
||||
}).then(function(data) {
|
||||
var wb = XLSX.read(data.data);
|
||||
}).then(function(response) {
|
||||
var wb = XLSX.read(response.data);
|
||||
var data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
|
||||
$scope.data = data;
|
||||
}, function(err) { console.log(err); });
|
||||
@ -321,8 +321,8 @@ app.controller('sheetjs', function($scope, $http) {
|
||||
$http({
|
||||
url:'https://docs.sheetjs.com/pres.xlsx',
|
||||
method:'GET', responseType:'arraybuffer'
|
||||
}).then(function(data) {
|
||||
var wb = XLSX.read(data.data);
|
||||
}).then(function(response) {
|
||||
var wb = XLSX.read(response.data);
|
||||
// highlight-next-line
|
||||
$scope.data = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
}, function(err) { console.log(err); });
|
||||
@ -377,8 +377,8 @@ app.controller('sheetjs', function($scope, $http) {
|
||||
$http({
|
||||
url:'https://docs.sheetjs.com/pres.xlsx',
|
||||
method:'GET', responseType:'arraybuffer'
|
||||
}).then(function(data) {
|
||||
var wb = XLSX.read(data.data);
|
||||
}).then(function(response) {
|
||||
var wb = XLSX.read(response.data);
|
||||
$scope.data = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
}, function(err) { console.log(err); });
|
||||
});
|
||||
|
@ -30,7 +30,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| Browser | Version | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| Chromiun 125 | `5.3.2` | 2024-06-09 |
|
||||
| Chromium 125 | `5.3.2` | 2024-06-09 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -54,6 +54,7 @@ This demo was tested in the following environments:
|
||||
|:-----------|:--------------------|:---------|:-------------|:-----------|
|
||||
| Android 34 | Pixel 3a | `2.16.4` | `darwin-arm` | 2024-06-09 |
|
||||
| iOS 17.5 | iPhone SE (3rd gen) | `2.16.4` | `darwin-arm` | 2024-06-09 |
|
||||
| Android 35 | Pixel 3a | `2.16.9` | `win11-x64` | 2024-08-20 |
|
||||
|
||||
:::
|
||||
|
||||
@ -195,7 +196,7 @@ When prompted:
|
||||
- "Project folder": `SheetJSQuasar`
|
||||
- "Pick Quasar version": `Quasar v2 (Vue 3 | latest and greatest)`
|
||||
- "Pick script type": `Typescript`
|
||||
- "Pick Quasar App CLI variant": `Quasar App CLI with Vite`
|
||||
- "Pick Quasar App CLI variant": `Quasar App CLI with Vite 2 (stable | v1)`
|
||||
- "Package name": (press <kbd>Enter</kbd>, it will use the default `sheetjsquasar`)
|
||||
- "Project product name": `SheetJSQuasar`
|
||||
- "Project description": `SheetJS + Quasar`
|
||||
@ -218,7 +219,8 @@ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
3) Set up Cordova:
|
||||
|
||||
```bash
|
||||
quasar mode add cordova
|
||||
npx cordova telemetry off
|
||||
npx quasar mode add cordova
|
||||
```
|
||||
|
||||
When prompted, enter the app id `org.sheetjs.quasar`.
|
||||
@ -227,9 +229,9 @@ It will create a new `src-cordova` folder. Continue in that folder:
|
||||
|
||||
```bash
|
||||
cd src-cordova
|
||||
cordova platform add ios
|
||||
cordova plugin add cordova-plugin-wkwebview-engine
|
||||
cordova plugin add cordova-plugin-file
|
||||
npx cordova platform add ios
|
||||
npx cordova plugin add cordova-plugin-wkwebview-engine
|
||||
npx cordova plugin add cordova-plugin-file
|
||||
```
|
||||
|
||||
:::note pass
|
||||
@ -237,9 +239,9 @@ cordova plugin add cordova-plugin-file
|
||||
If there is an error `Could not load API for iOS project`, it needs to be reset:
|
||||
|
||||
```bash
|
||||
cordova platform rm ios
|
||||
cordova platform add ios
|
||||
cordova plugin add cordova-plugin-file
|
||||
npx cordova platform rm ios
|
||||
npx cordova platform add ios
|
||||
npx cordova plugin add cordova-plugin-file
|
||||
```
|
||||
|
||||
:::
|
||||
@ -271,7 +273,7 @@ The following lines must be added to `src-cordova/platforms/ios/SheetJSQuasar/Sh
|
||||
5) Start the development server:
|
||||
|
||||
```bash
|
||||
quasar dev -m ios
|
||||
npx quasar dev -m ios
|
||||
```
|
||||
|
||||
If prompted to select an external IP, press <kbd>Enter</kbd>.
|
||||
|
@ -13,57 +13,17 @@ For a given workbook object `wb`:
|
||||
`wb.Sheets` is an object whose keys are worksheet names (from `SheetNames`) and
|
||||
whose values are worksheet objects.
|
||||
|
||||
`wb.Props` is an object storing the standard properties. `wb.Custprops` stores
|
||||
custom properties. Since the XLS standard properties deviate from the XLSX
|
||||
standard, XLS parsing stores core properties in both places.
|
||||
|
||||
`wb.Workbook` stores [workbook-level attributes](#workbook-level-attributes).
|
||||
|
||||
When reading a file, `wb.bookType` is the determined book type.
|
||||
|
||||
## File Properties
|
||||
|
||||
The various file formats use different internal names for file properties. The
|
||||
workbook `Props` object normalizes the names:
|
||||
`wb.Props` is an object storing the standard properties.
|
||||
|
||||
<details open>
|
||||
<summary><b>File Properties</b> (click to hide)</summary>
|
||||
`wb.Custprops` stores custom properties.
|
||||
|
||||
| JS Name | Excel Description |
|
||||
|:--------------|:-------------------------------|
|
||||
| `Title` | Summary tab "Title" |
|
||||
| `Subject` | Summary tab "Subject" |
|
||||
| `Author` | Summary tab "Author" |
|
||||
| `Manager` | Summary tab "Manager" |
|
||||
| `Company` | Summary tab "Company" |
|
||||
| `Category` | Summary tab "Category" |
|
||||
| `Keywords` | Summary tab "Keywords" |
|
||||
| `Comments` | Summary tab "Comments" |
|
||||
| `LastAuthor` | Statistics tab "Last saved by" |
|
||||
| `CreatedDate` | Statistics tab "Created" |
|
||||
|
||||
</details>
|
||||
|
||||
For example, to set the workbook title property:
|
||||
|
||||
```js
|
||||
if(!wb.Props) wb.Props = {};
|
||||
wb.Props.Title = "Insert Title Here";
|
||||
```
|
||||
|
||||
Custom properties are added in the workbook `Custprops` object:
|
||||
|
||||
```js
|
||||
if(!wb.Custprops) wb.Custprops = {};
|
||||
wb.Custprops["Custom Property"] = "Custom Value";
|
||||
```
|
||||
|
||||
Writers will process the `Props` key of the options object:
|
||||
|
||||
```js
|
||||
/* force the Author to be "SheetJS" */
|
||||
XLSX.write(wb, { Props: { Author: "SheetJS" } });
|
||||
```
|
||||
["File Properties"](/docs/csf/features/props) covers the feature in more detail.
|
||||
|
||||
## Workbook-Level Attributes
|
||||
|
||||
|
@ -186,8 +186,7 @@ function SheetJSDOMMergedCells() {
|
||||
<div ref={ref} dangerouslySetInnerHTML={{__html}}/>
|
||||
<b>Merges:</b>
|
||||
<pre>{merges ? merges.map(m => XLSX.utils.encode_range(m)).join("\n") : ""}</pre>
|
||||
</>
|
||||
);
|
||||
</> );
|
||||
}
|
||||
```
|
||||
|
||||
|
164
docz/docs/07-csf/07-features/12-props.md
Normal file
164
docz/docs/07-csf/07-features/12-props.md
Normal file
@ -0,0 +1,164 @@
|
||||
---
|
||||
title: File Properties
|
||||
sidebar_position: 12
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary><b>File Format Support</b> (click to show)</summary>
|
||||
|
||||
Excel supports a number of standard properties. Most modern versions of Excel
|
||||
also support custom properties.
|
||||
|
||||
| Formats | Standard | Custom | Separate |
|
||||
|:----------|:--------:|:-------|----------|
|
||||
| XLSX/XLSM | ✔ | ✔ | ✔ |
|
||||
| XLSB | ✔ | ✔ | ✔ |
|
||||
| XLML | ✔ | ✔ | ✔ |
|
||||
| BIFF8 XLS | ✔ | ✔ | |
|
||||
| BIFF5 XLS | R | R | |
|
||||
|
||||
The letter R (R) marks features parsed but not written in the format.
|
||||
|
||||
The "Separate" column marks formats that store standard and custom properties
|
||||
in different locations. Legacy XLS files commingle properties.
|
||||
|
||||
</details>
|
||||
|
||||
Modern spreadsheet software support special file properties including titles and
|
||||
keywords. Third-party tools can understand the file properties without having to
|
||||
process or understand the spreadsheet structure.
|
||||
|
||||
In the SheetJS Data Model, the workbook object `Props` property holds standard
|
||||
properties and the `Custprops` property holds custom properties.
|
||||
|
||||
## Live Demo
|
||||
|
||||
The following demo generates `SheetJSProperties.xlsx` with two file properties:
|
||||
|
||||
- The standard `Title` property will be set to `SheetJS Properties Test`. This
|
||||
will be displayed in the "Summary" tab of the Excel file properties dialog:
|
||||
|
||||
!["Standard" tab showing "Title" property](pathname:///props/standard-title.png)
|
||||
|
||||
- The custom `Custom Quip` property will be set to `Get Sheet Done`. This will
|
||||
be displayed in the "Properties" table in the "Custom" tab of the dialog:
|
||||
|
||||
!["Custom" tab with "Custom Quip" property](pathname:///props/custom-quip.png)
|
||||
|
||||
|
||||
```jsx live
|
||||
function SheetJSPropertiesExport() { return (<button onClick={() => {
|
||||
/* create workbook */
|
||||
var ws = XLSX.utils.aoa_to_sheet([ ["Check Props"] ]);
|
||||
var wb = XLSX.utils.book_new(ws);
|
||||
|
||||
/* add Title */
|
||||
if(!wb.Props) wb.Props = {};
|
||||
wb.Props.Title = "SheetJS Properties Test";
|
||||
|
||||
/* add Custom Quip */
|
||||
if(!wb.Custprops) wb.Custprops = {};
|
||||
wb.Custprops["Custom Quip"] = "Get Sheet Done";
|
||||
|
||||
/* export to XLSX */
|
||||
XLSX.writeFile(wb, "SheetJSProperties.xlsx");
|
||||
}}><b>Click here to Export</b></button>); }
|
||||
```
|
||||
|
||||
## Spreadsheet Applications
|
||||
|
||||
Spreadsheet applications commonly display file properties in separate windows:
|
||||
|
||||
- Excel for Windows: select "File" above the ribbon bar, select "Info" in the
|
||||
left sidebar, and click Properties > Advanced Properties
|
||||
|
||||
- Excel for Mac: select "File" in the menu bar and select "Properties"
|
||||
|
||||
- WPS Office: select "Menu" > "Document Encryption" > "Properties"
|
||||
|
||||
:::note pass
|
||||
|
||||
When this demo was last tested, Apple Numbers (14.2, build 7041.0.109) did not
|
||||
support file properties in the XLSX import and export codecs.
|
||||
|
||||
:::
|
||||
|
||||
## Standard Properties
|
||||
|
||||
Some properties cannot be changed in spreadsheet applications. The underlying
|
||||
SheetJS output codecs can write arbitrary values.
|
||||
|
||||
The `Props` object understands the "standard" properties listed in the following
|
||||
table. "SheetJS Name" refers to the name of the property in the `Props` object.
|
||||
"Excel Property Setting" refers to the name in the Excel file properties dialog.
|
||||
|
||||
| SheetJS Name | Excel Property Setting |
|
||||
|:--------------|:-------------------------------|
|
||||
| `Title` | Summary tab "Title" |
|
||||
| `Subject` | Summary tab "Subject" |
|
||||
| `Author` | Summary tab "Author" |
|
||||
| `Manager` | Summary tab "Manager" |
|
||||
| `Company` | Summary tab "Company" |
|
||||
| `Category` | Summary tab "Category" |
|
||||
| `Keywords` | Summary tab "Keywords" |
|
||||
| `Comments` | Summary tab "Comments" |
|
||||
| `LastAuthor` | Statistics tab "Last saved by" |
|
||||
| `CreatedDate` | Statistics tab "Created" |
|
||||
|
||||
It is strongly recommended to test if the `Props` property exists:
|
||||
|
||||
```js title="Set the 'Title' file property"
|
||||
/* ensure `Props` exists */
|
||||
if(!wb.Props) wb.Props = {};
|
||||
|
||||
/* set `Title` property */
|
||||
wb.Props.Title = "SheetJS Properties Test";
|
||||
```
|
||||
|
||||
## Custom Properties
|
||||
|
||||
Custom properties are added in the workbook `Custprops` object. As with `Props`,
|
||||
scripts should test for the existence of the `Custprops` property:
|
||||
|
||||
```js title="Set the 'Custom Quip' custom file property"
|
||||
/* ensure `Custprops` exists */
|
||||
if(!wb.Custprops) wb.Custprops = {};
|
||||
|
||||
/* set `Custom Quip` property */
|
||||
wb.Custprops["Custom Quip"] = "Get Sheet Done";
|
||||
```
|
||||
|
||||
## Export Override
|
||||
|
||||
The SheetJS `write` and `writeFile` methods[^2] accept options. The `Props`
|
||||
option instructs the writer to override properties from the workbook object.
|
||||
|
||||
In the following example, the workbook object sets the "Title" and "Keywords"
|
||||
standard properties. `writeFile` will override the "Keywords" property and add
|
||||
the "Category" property. The generated file will have the following properties:
|
||||
|
||||
- "Title" will be set to "SheetJS Properties Test" (from the workbook object)
|
||||
- "Keywords" will be blank (overridden by `writeFile` option)
|
||||
- "Category" will be "Sheetpost" (assigned through `writeFile` option)
|
||||
|
||||
|
||||
```jsx live
|
||||
function SheetJSPropertiesOverride() { return (<button onClick={() => {
|
||||
/* create workbook */
|
||||
var ws = XLSX.utils.aoa_to_sheet([ ["Check Props"] ]);
|
||||
var wb = XLSX.utils.book_new(ws);
|
||||
|
||||
/* add Title and Keywords */
|
||||
if(!wb.Props) wb.Props = {};
|
||||
wb.Props.Title = "SheetJS Properties Test";
|
||||
wb.Props.Keywords = "Properties";
|
||||
|
||||
/* export to XLSX with property overrides */
|
||||
XLSX.writeFile(wb, "SheetJSPropertiesOverride.xlsx", { Props: {
|
||||
Keywords: "", /* Ensure `Keywords` is blank */
|
||||
Category: "Sheetpost", /* Add `Category` property */
|
||||
}});
|
||||
}}><b>Click here to Export</b></button>); }
|
||||
```
|
||||
|
||||
[^1]: See [`write` and `writeFile` in "Writing Files"](/docs/api/write-options)
|
@ -41,7 +41,7 @@ These instructions were tested on the following platforms:
|
||||
|
||||
| Platform | Architecture | Test Date |
|
||||
|:------------------------------|:-------------|:-----------|
|
||||
| Linux (Steam Deck Holo x64) | `linux-x64` | 2024-07-12 |
|
||||
| Linux (Steam Deck Holo x64) | `linux-x64` | 2024-09-20 |
|
||||
| Linux (Arch Linux AArch64) | `linux-arm` | 2024-05-10 |
|
||||
| MacOS 14.4 (x64) | `darwin-x64` | 2024-07-12 |
|
||||
| MacOS 14.5 (ARM64) | `darwin-arm` | 2024-05-23 |
|
||||
@ -302,6 +302,17 @@ sudo pacman-key --populate
|
||||
sudo pacman-key --refresh-keys
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
When this demo was last tested, keys were refreshed after 25 minutes.
|
||||
|
||||
**Do not switch to gaming mode or let the device sleep during the process!**
|
||||
|
||||
To ensure the device does not sleep, click the battery icon in the lower right
|
||||
corner of the screen and enable "Manually block sleep and screen locking".
|
||||
|
||||
:::
|
||||
|
||||
4) Install dependencies:
|
||||
|
||||
```bash
|
||||
@ -325,8 +336,6 @@ These packages are *not required* for building or testing the library.
|
||||
|
||||
B) Install NodeJS.
|
||||
|
||||
:::note pass
|
||||
|
||||
[The official NodeJS site](https://nodejs.org/en/download/) provides Linux
|
||||
binaries, but it is strongly recommended to use `nvm` to install NodeJS:
|
||||
|
||||
@ -334,15 +343,25 @@ binaries, but it is strongly recommended to use `nvm` to install NodeJS:
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
|
||||
```
|
||||
|
||||
After installing, start a new terminal session and install NodeJS "LTS":
|
||||
After installing `nvm`, start a new terminal session and install NodeJS "LTS":
|
||||
|
||||
```bash
|
||||
nvm install --lts
|
||||
node --version
|
||||
```
|
||||
|
||||
After installing, if running `node` in the terminal fails with a `glibc` error,
|
||||
an older version of NodeJS should be installed. For example, Ubuntu 18.04 does
|
||||
not support Node 18 but supports Node 16.20.0:
|
||||
:::note pass
|
||||
|
||||
If the `nvm` command cannot be found, close the current terminal session and
|
||||
start a new session.
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
|
||||
If the `node` command fails with a `glibc` error, an older version of NodeJS
|
||||
must be installed. For example, Ubuntu 18.04 does not support Node 18 but does
|
||||
support Node 16.20.0:
|
||||
|
||||
```bash
|
||||
nvm install 16
|
||||
|
BIN
docz/static/props/custom-quip.png
Normal file
BIN
docz/static/props/custom-quip.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
docz/static/props/standard-title.png
Normal file
BIN
docz/static/props/standard-title.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
Loading…
Reference in New Issue
Block a user