lume
This commit is contained in:
parent
de18b667b9
commit
fa5ff21a8e
@ -12,6 +12,7 @@ api
|
||||
csf
|
||||
|
||||
# Excel-related terms
|
||||
A1
|
||||
A1-Style
|
||||
AutoFilter
|
||||
BIFF12
|
||||
|
@ -10,6 +10,15 @@ import current from '/version.js';
|
||||
|
||||
# Deno
|
||||
|
||||
[Deno](https://deno.land/) is a JavaScript runtime powered by V8.
|
||||
|
||||
:::caution Deno support is considered experimental.
|
||||
|
||||
Great open source software grows with user tests and reports. Any issues should
|
||||
be reported to the Deno project for further diagnosis.
|
||||
|
||||
:::
|
||||
|
||||
Each standalone release script is available at <https://cdn.sheetjs.com/>.
|
||||
|
||||
Using the URL imports, `deno run` will automatically download scripts and types:
|
||||
|
@ -6,6 +6,88 @@ With the advent of server-side frameworks and content management systems, it is
|
||||
possible to build sites whose source of truth is a spreadsheet! This demo
|
||||
explores a number of approaches.
|
||||
|
||||
## Lume
|
||||
|
||||
[Lume](https://lume.land) is a static site generator for the Deno platform.
|
||||
|
||||
The official [Sheets plugin](https://lume.land/plugins/sheets/) uses SheetJS
|
||||
to load data from spreadsheets.
|
||||
|
||||
### Lume Demo
|
||||
|
||||
:::note
|
||||
|
||||
This was tested against `lume v1.12.0` on 2022 October 4.
|
||||
|
||||
:::
|
||||
|
||||
<details><summary><b>Complete Example</b> (click to show)</summary>
|
||||
|
||||
1) Create a stock site:
|
||||
|
||||
```bash
|
||||
mkdir sheetjs-lume
|
||||
cd sheetjs-lume
|
||||
deno run -A https://deno.land/x/lume/init.ts
|
||||
```
|
||||
|
||||
When prompted, enter the following options:
|
||||
|
||||
- `Use TypeScript for the configuration file`: press Enter (use default `N`)
|
||||
- `Do you want to use plugins`: type `sheets` and press Enter
|
||||
|
||||
The project will be configured and modules will be installed.
|
||||
|
||||
2) Download <https://sheetjs.com/pres.numbers> and place in a `_data` folder:
|
||||
|
||||
```bash
|
||||
mkdir _data
|
||||
curl -LO https://sheetjs.com/pres.numbers
|
||||
mv pres.numbers _data
|
||||
```
|
||||
|
||||
3) Create a `index.njk` file that references the file. Since the file is
|
||||
`pres.numbers`, the parameter name is `pres`:
|
||||
|
||||
```liquid title="index.njk"
|
||||
<h2>Presidents</h2>
|
||||
<table><thead><th>Name</th><th>Index</th></thead>
|
||||
<tbody>
|
||||
{% for row in pres %}{% if (loop.index >= 1) %}
|
||||
<tr>
|
||||
<td>{{ row.Name }}</td>
|
||||
<td>{{ row.Index }}</td>
|
||||
</tr>
|
||||
{% endif %}{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
4) Run the development server:
|
||||
|
||||
```bash
|
||||
deno task lume --serve
|
||||
```
|
||||
|
||||
To verify it works, access http://localhost:3000 from your web browser.
|
||||
Adding a new row and saving `pres.numbers` should refresh the data
|
||||
|
||||
5) Stop the server (press `CTRL+C` in the terminal window) and run
|
||||
|
||||
```bash
|
||||
deno task lume
|
||||
```
|
||||
|
||||
This will create a static site in the `_site` folder, which can be served with:
|
||||
|
||||
```bash
|
||||
npx http-server _site
|
||||
```
|
||||
|
||||
Accessing the page http://localhost:8080 will show the page contents.
|
||||
|
||||
</details>
|
||||
|
||||
## GatsbyJS
|
||||
|
||||
[`gatsby-transformer-excel`](https://www.gatsbyjs.com/plugins/gatsby-transformer-excel/)
|
||||
@ -513,160 +595,3 @@ the static nature is trivial: make another change in Excel and save. The page
|
||||
will not change.
|
||||
|
||||
</details>
|
||||
|
||||
## Lume
|
||||
|
||||
Lume is a static site generator for the Deno platform.
|
||||
|
||||
`lume#loadData` can add custom loaders for data. The loader method receives a
|
||||
path to the file, which can be read with `XLSX.readFile`. This should be added
|
||||
to `_config.js`, like in the example below:
|
||||
|
||||
```js title="_config.js"
|
||||
import lume from "lume/mod.ts";
|
||||
import { readFile, utils } from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs';
|
||||
|
||||
function wbLoader(path) {
|
||||
const wb = readFile(path);
|
||||
const res = wb.SheetNames.map(n => ({
|
||||
name: n,
|
||||
data: utils.sheet_to_json(wb.Sheets[n])
|
||||
}));
|
||||
return { content: res };
|
||||
}
|
||||
|
||||
const site = lume();
|
||||
const exts = [".xlsx", ".numbers", /* ... other supported extensions */];
|
||||
// highlight-next-line
|
||||
site.loadData(exts, wbLoader);
|
||||
|
||||
export default site;
|
||||
```
|
||||
|
||||
The actual spreadsheets should be placed in the `_data` subfolder.
|
||||
|
||||
The variable name is the stem of the filename (`sheetjs` if `sheetjs.xlsx` or
|
||||
`sheetjs.numbers` exists). A Nunjucks or JSX template can loop through the
|
||||
worksheets and the data rows. The example assumes each worksheet has a `name` and `index` column:
|
||||
|
||||
```jsx title="index.jsx"
|
||||
export default ({sheetjs}) => {
|
||||
return (<>{(sheetjs).map(sheet => (<>
|
||||
<h2>{sheet.name}</h2>
|
||||
<table><thead><th>Name</th><th>Index</th></thead>
|
||||
<tbody>{sheet.data.map(row => (<tr>
|
||||
<td>{row.name}</td>
|
||||
<td>{row.index}</td>
|
||||
</tr>))}</tbody>
|
||||
</table>
|
||||
</>))}</>);
|
||||
};
|
||||
```
|
||||
|
||||
### Lume Demo
|
||||
|
||||
<details><summary><b>Complete Example</b> (click to show)</summary>
|
||||
|
||||
:::note
|
||||
|
||||
This was tested against `lume v1.10.4` on 2022 August 25.
|
||||
|
||||
:::
|
||||
|
||||
1) Create a stock site:
|
||||
|
||||
```bash
|
||||
mkdir sheetjs-lume
|
||||
cd sheetjs-lume
|
||||
deno run -A https://deno.land/x/lume/init.ts
|
||||
```
|
||||
|
||||
When prompted, enter the following options:
|
||||
|
||||
- `Use TypeScript for the configuration file`: press Enter (use default `N`)
|
||||
- `Do you want to use plugins`: type `jsx` and press Enter
|
||||
|
||||
The project will be configured and modules will be installed.
|
||||
|
||||
2) Make the following highlighted changes to `_config.js`:
|
||||
|
||||
```js title="_config.js"
|
||||
import lume from "lume/mod.ts";
|
||||
import jsx from "lume/plugins/jsx.ts";
|
||||
|
||||
// highlight-start
|
||||
import { readFile, utils } from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs';
|
||||
|
||||
function wbLoader(path) {
|
||||
const wb = readFile(path);
|
||||
const res = wb.SheetNames.map(n => ({
|
||||
name: n,
|
||||
data: utils.sheet_to_json(wb.Sheets[n])
|
||||
}));
|
||||
return { content: res };
|
||||
}
|
||||
// highlight-end
|
||||
|
||||
const site = lume();
|
||||
|
||||
site.use(jsx());
|
||||
|
||||
// highlight-start
|
||||
const exts = [".xlsx", ".numbers", /* ... other supported extensions */];
|
||||
site.loadData(exts, wbLoader);
|
||||
// highlight-end
|
||||
|
||||
export default site;
|
||||
```
|
||||
|
||||
This instructs Lume to watch for and load `.xlsx` and `.numbers` spreadsheets
|
||||
|
||||
3) Download <https://sheetjs.com/pres.numbers> and place in a `_data` folder:
|
||||
|
||||
```bash
|
||||
mkdir _data
|
||||
curl -LO https://sheetjs.com/pres.numbers
|
||||
mv pres.numbers _data
|
||||
```
|
||||
|
||||
4) Create a `index.jsx` file that references the file. Since the file is
|
||||
`pres.numbers`, the parameter name is `pres`:
|
||||
|
||||
```jsx title="index.jsx"
|
||||
export default ({pres}) => {
|
||||
return (<>{(pres).map(sheet => (<>
|
||||
<h2>{sheet.name}</h2>
|
||||
<table><thead><th>Name</th><th>Index</th></thead>
|
||||
<tbody>{sheet.data.map(row => (<tr>
|
||||
<td>{row.Name}</td>
|
||||
<td>{row.Index}</td>
|
||||
</tr>))}</tbody>
|
||||
</table>
|
||||
</>))}</>);
|
||||
};
|
||||
```
|
||||
|
||||
5) Run the development server:
|
||||
|
||||
```bash
|
||||
deno task lume --serve
|
||||
```
|
||||
|
||||
To verify it works, access http://localhost:3000 from your web browser.
|
||||
Adding a new row and saving `pres.numbers` should refresh the data
|
||||
|
||||
6) Stop the server (press `CTRL+C` in the terminal window) and run
|
||||
|
||||
```bash
|
||||
deno task lume
|
||||
```
|
||||
|
||||
This will create a static site in the `_site` folder, which can be served with:
|
||||
|
||||
```bash
|
||||
npx http-server _serve
|
||||
```
|
||||
|
||||
Accessing the page http://localhost:8080 will show the page contents.
|
||||
|
||||
</details>
|
@ -219,7 +219,7 @@ includes an example of constructing a simple array.
|
||||
function export_pouchdb_to_xlsx(db) {
|
||||
/* fetch all rows, including the underlying data */
|
||||
db.allDocs({include_docs: true}, function(err, doc) {
|
||||
|
||||
|
||||
/* pull the individual data rows */
|
||||
const aoo = doc.rows.map(r => {
|
||||
/* `rest` will include every field from `r` except for _id and _rev */
|
||||
|
@ -890,4 +890,4 @@ rd.resume();
|
||||
</Tabs>
|
||||
|
||||
|
||||
<https://github.com/sheetjs/sheetaki> pipes write streams to nodejs response.
|
||||
<https://sheetaki.now.sh/> pipes write streams to nodejs response.
|
||||
|
@ -113,6 +113,7 @@ In addition to the aforementioned sheet keys, worksheets also add:
|
||||
| `pivotTables` | Use PivotTable reports | disabled |
|
||||
| `objects` | Edit objects | enabled |
|
||||
| `scenarios` | Edit scenarios | enabled |
|
||||
|
||||
</details>
|
||||
|
||||
- `ws['!autofilter']`: AutoFilter object following the schema:
|
||||
|
@ -16,14 +16,17 @@ while the writer will translate from A1-Style strings to the file format.
|
||||
|:------------------|:-----:|:-----:|:-----:|:-------:|:-----------------------|
|
||||
| XLSX / XLSM | ✔ | ✔ | ✔ | ✔ | A1-Style strings |
|
||||
| XLSB | ✔ | | ✔ | ✔ | BIFF parsed tokens |
|
||||
| XLS | ✔ | | ✔ | | BIFF parsed tokens |
|
||||
| XLML | ✔ | ✔ | ✔ | | RC-style strings |
|
||||
| SYLK | ✔ | ✔ | | | `A1`/RC-style strings |
|
||||
| CSV / TXT | ✔ | ✔ | | | A1-Style strings |
|
||||
| ODS / FODS / UOS | ✔ | ✔ | | | OpenFormula strings |
|
||||
| WK\* | ✔ | | | | Lotus parsed tokens |
|
||||
| WQ\* / WB\* / QPW | | | | | Quattro Pro tokens |
|
||||
| NUMBERS | | | | | Numbers parsed tokens |
|
||||
| XLS | ✔ | | ✔ | * | BIFF parsed tokens |
|
||||
| XLML | ✔ | ✔ | ✔ | * | RC-style strings |
|
||||
| SYLK | ✔ | ✔ | | * | A1/RC-style strings |
|
||||
| CSV / TXT | ✔ | ✔ | * | * | A1-Style strings |
|
||||
| ODS / FODS / UOS | ✔ | ✔ | | * | OpenFormula strings |
|
||||
| WK\* | ✔ | | | * | Lotus parsed tokens |
|
||||
| WQ\* / WB\* / QPW | | | | * | Quattro Pro tokens |
|
||||
| NUMBERS | | | | * | Numbers parsed tokens |
|
||||
|
||||
Asterisks (*) mark features that are not supported by the file formats. There is
|
||||
no way to mark a dynamic array formula in the XLS file format.
|
||||
|
||||
</details>
|
||||
|
||||
|
@ -24,34 +24,32 @@ For example, the following snippet creates a link from cell `A3` to
|
||||
ws["A1"].l = { Target: "https://sheetjs.com", Tooltip: "Find us @ SheetJS.com!" };
|
||||
```
|
||||
|
||||
Note that Excel does not automatically style hyperlinks. They will be displayed
|
||||
using default style. <a href="https://sheetjs.com/pro">SheetJS Pro Basic</a>
|
||||
:::note
|
||||
|
||||
Excel does not automatically style hyperlinks. They will be displayed using
|
||||
the default cell style. <a href="https://sheetjs.com/pro">SheetJS Pro Basic</a>
|
||||
extends this export with support for hyperlink styling.
|
||||
|
||||
<details><summary><b>Live Example</b> (click to show)</summary>
|
||||
:::
|
||||
|
||||
<details open><summary><b>Live Example</b> (click to hide)</summary>
|
||||
|
||||
```jsx live
|
||||
/* The live editor requires this function wrapper */
|
||||
function ExportSimpleLink(props) {
|
||||
function ExportSimpleLink(props) { return ( <button onClick={() => {
|
||||
/* Create worksheet */
|
||||
var ws = XLSX.utils.aoa_to_sheet([ [ "Link", "No Link" ] ]);
|
||||
/* Add link */
|
||||
ws["A1"].l = {
|
||||
Target: "https://sheetjs.com",
|
||||
Tooltip: "Find us @ SheetJS.com!"
|
||||
};
|
||||
|
||||
/* Callback invoked when the button is clicked */
|
||||
const xport = React.useCallback(() => {
|
||||
/* Create worksheet */
|
||||
var ws = XLSX.utils.aoa_to_sheet([ [ "Link", "No Link" ] ]);
|
||||
/* Add link */
|
||||
ws["A1"].l = {
|
||||
Target: "https://sheetjs.com",
|
||||
Tooltip: "Find us @ SheetJS.com!"
|
||||
};
|
||||
|
||||
/* Export to file (start a download) */
|
||||
var wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "SheetJSSimpleLink.xlsx");
|
||||
});
|
||||
|
||||
return (<button onClick={xport}><b>Export XLSX!</b></button>);
|
||||
}
|
||||
/* Export to file (start a download) */
|
||||
var wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "SheetJSSimpleLink.xlsx");
|
||||
}}><b>Export XLSX!</b></button> ); }
|
||||
```
|
||||
|
||||
</details>
|
||||
@ -72,6 +70,40 @@ ws["A4"].l = { Target: "mailto:ignored@dev.null" };
|
||||
ws["A5"].l = { Target: "mailto:ignored@dev.null?subject=Test Subject" };
|
||||
```
|
||||
|
||||
<details><summary><b>Live Example</b> (click to show)</summary>
|
||||
|
||||
**This demo creates a XLSX spreadsheet with a `mailto` email link. The email
|
||||
address input in the form never leaves your machine.**
|
||||
|
||||
```jsx live
|
||||
/* The live editor requires this function wrapper */
|
||||
function ExportRemoteLink(props) {
|
||||
const [email, setEmail] = React.useState("ignored@dev.null");
|
||||
const set_email = React.useCallback((evt) => setEmail(evt.target.value));
|
||||
|
||||
/* Callback invoked when the button is clicked */
|
||||
const xport = React.useCallback(() => {
|
||||
/* Create worksheet */
|
||||
var ws = XLSX.utils.aoa_to_sheet([ [ "HTTPS", "mailto" ] ]);
|
||||
/* Add links */
|
||||
ws["A1"].l = { Target: "https://sheetjs.com" };
|
||||
ws["B1"].l = { Target: `mailto:${email}` };
|
||||
|
||||
/* Export to file (start a download) */
|
||||
var wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "SheetJSRemoteLink.xlsx");
|
||||
});
|
||||
|
||||
return (<>
|
||||
<b>Email: </b><input type="text" value={email} onChange={set_email} size="50"/>
|
||||
<br/><button onClick={xport}><b>Export XLSX!</b></button>
|
||||
</>);
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Local Links
|
||||
|
||||
Links to absolute paths should use the `file://` URI scheme:
|
||||
@ -103,13 +135,55 @@ Links where the target is a cell or range or defined name in the same workbook
|
||||
```js
|
||||
ws["C1"].l = { Target: "#E2" }; /* Link to cell E2 */
|
||||
ws["C2"].l = { Target: "#Sheet2!E2" }; /* Link to cell E2 in sheet Sheet2 */
|
||||
ws["C3"].l = { Target: "#SomeDefinedName" }; /* Link to Defined Name */
|
||||
ws["C3"].l = { Target: "#SheetJSDName" }; /* Link to Defined Name */
|
||||
```
|
||||
|
||||
<details><summary><b>Live Example</b> (click to show)</summary>
|
||||
|
||||
```jsx live
|
||||
/* The live editor requires this function wrapper */
|
||||
function ExportInternalLink(props) { return ( <button onClick={() => {
|
||||
/* Create empty workbook */
|
||||
var wb = XLSX.utils.book_new();
|
||||
|
||||
/* Create worksheet */
|
||||
var ws = XLSX.utils.aoa_to_sheet([ [ "Same", "Cross", "Name" ] ]);
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
|
||||
/* Create links */
|
||||
ws["A1"].l = { Target: "#B2:D4", Tooltip: "Same-Sheet" };
|
||||
ws["B1"].l = { Target: "#Sheet2!B2:D4", Tooltip: "Cross-Sheet" };
|
||||
ws["C1"].l = { Target: "#SheetJSDN", Tooltip: "Defined Name" };
|
||||
|
||||
/* Create stub Sheet2 */
|
||||
var ws2 = XLSX.utils.aoa_to_sheet([["This is Sheet2"]]);
|
||||
XLSX.utils.book_append_sheet(wb, ws2, "Sheet2");
|
||||
|
||||
/* Create defined name */
|
||||
wb.Workbook = {
|
||||
Names: [{Name: "SheetJSDN", Ref:"Sheet2!A1:B2"}]
|
||||
}
|
||||
|
||||
/* Export to file (start a download) */
|
||||
XLSX.writeFile(wb, "SheetJSInternalLink.xlsx");
|
||||
}}><b>Export XLSX!</b></button> ); }
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
:::caution
|
||||
|
||||
Some third-party tools like Google Sheets do not correctly parse hyperlinks in
|
||||
XLSX documents. A workaround was added in library version 0.18.12.
|
||||
|
||||
:::
|
||||
|
||||
## HTML
|
||||
|
||||
The HTML DOM parser will process `<a>` links in the table:
|
||||
|
||||
<details open><summary><b>Live Example</b> (click to hide)</summary>
|
||||
|
||||
```jsx live
|
||||
/* The live editor requires this function wrapper */
|
||||
function ExportHyperlink(props) {
|
||||
@ -134,3 +208,5 @@ function ExportHyperlink(props) {
|
||||
</>);
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
@ -11,12 +11,11 @@ are expected to serialize SheetJS workbooks in the underlying file format.
|
||||
The following topics are covered in sub-pages:
|
||||
|
||||
<ul>{useCurrentSidebarCategory().items.map((item, index) => {
|
||||
const listyle = (item.customProps?.icon) ? {
|
||||
listStyleImage: `url("${item.customProps.icon}")`
|
||||
} : {};
|
||||
return (<li style={listyle} {...(item.customProps?.class ? {className: item.customProps.class}: {})}>
|
||||
<a href={item.href}>{item.label}</a>{item.customProps?.summary && (" - " + item.customProps.summary)}
|
||||
</li>);
|
||||
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> );
|
||||
})}</ul>
|
||||
|
||||
## Row and Column Properties
|
||||
@ -340,9 +339,9 @@ var vbablob = wb.vbaraw;
|
||||
|
||||
#### Code Names
|
||||
|
||||
By default, Excel will use `ThisWorkbook` or a translation `DieseArbeitsmappe`
|
||||
for the workbook. Each worksheet will be identified using the default `Sheet#`
|
||||
naming pattern even if the worksheet names have changed.
|
||||
Excel will use `ThisWorkbook` (or a translation like `DieseArbeitsmappe`) as the
|
||||
default Code Name for the workbook. Each worksheet will be identified using the
|
||||
default `Sheet#` naming pattern even if the worksheet names have changed.
|
||||
|
||||
A custom workbook code name will be stored in `wb.Workbook.WBProps.CodeName`.
|
||||
For exports, assigning the property will override the default value.
|
||||
@ -374,4 +373,3 @@ function wb_has_macro(wb/*:workbook*/)/*:boolean*/ {
|
||||
return sheets.some((ws) => !!ws && ws['!type']=='macro');
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -5,8 +5,8 @@ hide_table_of_contents: true
|
||||
---
|
||||
|
||||
Here are some common errors and their resolutions. This is not comprehensive.
|
||||
The [issue tracker](https://github.com/SheetJS/sheetjs/issues) has a wealth of
|
||||
information and user-contributed examples.
|
||||
The [issue tracker](https://git.sheetjs.com/SheetJS/sheetjs/issues) has a
|
||||
wealth of information and user-contributed examples.
|
||||
|
||||
If issues are not covered in the docs or the issue tracker, or if a solution is
|
||||
not discussed in the documentation, we would appreciate a bug report.
|
||||
|
12
docz/docs/09-miscellany/03-source.md
Normal file
12
docz/docs/09-miscellany/03-source.md
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
title: Source Code
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
||||
The official source code repository is <https://git.sheetjs.com/sheetjs/sheetjs>
|
||||
|
||||
Mirrors:
|
||||
|
||||
- [GitHub](https://github.com/sheetjs/sheetjs)
|
||||
- [GitLab](https://gitlab.com/sheetjs/sheetjs)
|
@ -8,7 +8,30 @@ hide_table_of_contents: true
|
||||
SheetJS Community Edition is licensed under the "Apache 2.0 License". All rights
|
||||
not explicitly granted by the Apache 2.0 License are reserved by SheetJS LLC.
|
||||
|
||||
<details><summary><b>License</b> (click to show)</summary>
|
||||
#### Required Attribution
|
||||
|
||||
When integrating SheetJS CE in a project or service, the following text must be
|
||||
added to open source disclosures:
|
||||
|
||||
```
|
||||
SheetJS Community Edition -- https://sheetjs.com/
|
||||
|
||||
Copyright (C) 2012-present SheetJS LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
```
|
||||
|
||||
<details><summary><b>Complete License Text</b> (click to show)</summary>
|
||||
|
||||
```
|
||||
Apache License
|
||||
|
@ -80,7 +80,7 @@ const config = {
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/sheetjs/sheetjs',
|
||||
href: 'https://docs.sheetjs.com/docs/miscellany/source/',
|
||||
label: 'Source',
|
||||
position: 'right',
|
||||
},
|
||||
@ -132,7 +132,7 @@ const config = {
|
||||
},
|
||||
{
|
||||
label: 'Source',
|
||||
href: 'https://github.com/sheetjs/sheetjs',
|
||||
href: 'https://docs.sheetjs.com/docs/miscellany/source/',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user