dojo
This commit is contained in:
parent
10ed191020
commit
2c4c81603d
@ -17,7 +17,7 @@ Each standalone release script is available at <https://cdn.sheetjs.com/>.
|
||||
|
||||
<p><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>https://cdn.sheetjs.com/xlsx-{current}/package/dist/xlsx.full.min.js</a> is the URL for {current}</p>
|
||||
|
||||
:::note
|
||||
:::note pass
|
||||
|
||||
When referencing by file name, AMD loaders typically omit the file extension.
|
||||
|
||||
@ -63,7 +63,7 @@ sap.ui.define([
|
||||
})
|
||||
```
|
||||
|
||||
:::warning
|
||||
:::warning pass
|
||||
|
||||
**Copy and pasting code does not work** for SheetJS scripts as they contain
|
||||
Unicode characters that may be mangled. The standalone script should be
|
||||
@ -73,7 +73,7 @@ downloaded and manually uploaded to the project.
|
||||
|
||||
## RequireJS
|
||||
|
||||
:::caution
|
||||
:::caution pass
|
||||
|
||||
The standalone script must be aliased to the path `xlsx`.
|
||||
|
||||
@ -100,11 +100,11 @@ require(['xlsx'], function(XLSX) {
|
||||
## Dojo Toolkit
|
||||
|
||||
Dojo has changed module loading strategies over the years. These examples were
|
||||
tested with Dojo `1.10.4` and are not guaranteed to work with other versions.
|
||||
tested with Dojo `1.17.3`. They are not guaranteed to work with other versions.
|
||||
|
||||
Live demos are included in ["Dojo Toolkit"](/docs/demos/frontend/legacy#dojo-toolkit)
|
||||
|
||||
:::caution
|
||||
:::caution pass
|
||||
|
||||
The standalone scripts add `window.XLSX`, so it is recommended to use `_XLSX`
|
||||
in the function arguments and access the library with `XLSX` in the callback:
|
||||
@ -127,7 +127,7 @@ When `async` is set to `false` or `0`, the scripts can be directly referenced in
|
||||
`require` calls.
|
||||
|
||||
<CodeBlock language="html">{`\
|
||||
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:0"></script>
|
||||
<script src="dojo.js" data-dojo-config="isDebug:1, async:0"></script>
|
||||
<script>
|
||||
require([
|
||||
// highlight-next-line
|
||||
@ -163,7 +163,7 @@ dojoConfig = {
|
||||
]
|
||||
};
|
||||
</script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
|
||||
<script src="dojo.js" data-dojo-config="isDebug:1, async:1"></script>
|
||||
<script>
|
||||
require(["xlsx"], function(_XLSX) {
|
||||
// ... use XLSX here
|
||||
|
@ -25,7 +25,7 @@ These are designed to be referenced with `<script>` tags.
|
||||
|
||||
## Internet Explorer
|
||||
|
||||
:::warning
|
||||
:::warning pass
|
||||
|
||||
Internet Explorer is unmaintained and users should consider modern browsers.
|
||||
The SheetJS testing grid still includes IE and should work.
|
||||
@ -64,7 +64,7 @@ npx -y http-server .
|
||||
|
||||
<details><summary><b>Other Live Demos</b> (click to show)</summary>
|
||||
|
||||
:::caution
|
||||
:::caution pass
|
||||
|
||||
The hosted solutions may not work in older versions of Windows. For testing,
|
||||
demo pages should be downloaded and hosted using a simple HTTP server.
|
||||
@ -141,7 +141,7 @@ approach is embedded in `XLSX.writeFile` and no additional shims are necessary.
|
||||
|
||||
**Flash-based Download**
|
||||
|
||||
It is possible to write to the file system using a SWF file. `Downloadify`
|
||||
It is possible to write to the file system using a SWF file. `Downloadify`[^1]
|
||||
implements one solution. Since a genuine click is required, there is no way to
|
||||
force a download. The safest data type is Base64:
|
||||
|
||||
@ -171,7 +171,7 @@ scripting language can write to an arbitrary path on the filesystem. The shim
|
||||
includes a special `IE_SaveFile` function to write binary strings to file. It
|
||||
attempts to write to the Downloads folder or Documents folder or Desktop.
|
||||
|
||||
This approach can be triggered, but it requires the user to enable ActiveX. It
|
||||
This approach does not require user interaction, but ActiveX must be enabled. It
|
||||
is embedded as a strategy in `writeFile` and used only if the shim script is
|
||||
included in the page and the relevant features are enabled on the target system.
|
||||
|
||||
@ -185,6 +185,22 @@ _Live Demos_
|
||||
- [Download and display data](pathname:///dojo/read.html)
|
||||
- [Fetch JSON and generate a workbook](pathname:///dojo/write.html)
|
||||
|
||||
:::note pass
|
||||
|
||||
These demos have been tested with Dojo Toolkit `1.10.4` and `1.17.3`.
|
||||
|
||||
:::
|
||||
|
||||
:::warning pass
|
||||
|
||||
The official Google CDN is out of date. This is a known CDN bug.
|
||||
|
||||
The script <https://docs.sheetjs.com/dojo/dojo.js> was fetched from the official
|
||||
`1.17.3` uncompresssed release artifact[^2] on 2023-08-16.
|
||||
|
||||
:::
|
||||
|
||||
_Installation_
|
||||
|
||||
The ["AMD" instructions](/docs/getting-started/installation/amd#dojo-toolkit)
|
||||
includes details for use with `require`.
|
||||
@ -201,7 +217,7 @@ dojoConfig = {
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
|
||||
<script src="dojo.js" data-dojo-config="isDebug:1, async:1"></script>
|
||||
<script>
|
||||
require(["dojo/request/xhr", "xlsx"], function(xhr, _XLSX) {
|
||||
/* XLSX-related operations happen in the callback */
|
||||
@ -339,4 +355,7 @@ binding is possible using the `$parent` and `$index` binding context properties:
|
||||
</table>
|
||||
```
|
||||
|
||||
</details>
|
||||
</details>
|
||||
|
||||
[^1]: Project hosted at <https://github.com/dcneiner/Downloadify>
|
||||
[^2]: All Dojo Toolkit releases are available at <https://download.dojotoolkit.org/>. The mirrored `dojo.js` corresponds to the `1.17.3` uncompressed script <http://download.dojotoolkit.org/release-1.17.3/dojo.js.uncompressed.js>.
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Glide Datagrid
|
||||
title: Let Data Glide on Glide Data Grid
|
||||
sidebar_label: Glide Data Grid
|
||||
description: Display structured data with Glide Data Grid. Effortlessly import and export data using SheetJS. Modernize business processes while retaining legacy Excel structures.
|
||||
pagination_prev: demos/frontend/index
|
||||
pagination_next: demos/net/index
|
||||
---
|
||||
@ -7,24 +9,74 @@ pagination_next: demos/net/index
|
||||
import current from '/version.js';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
[Glide Data Grid](https://grid.glideapps.com/) is a high-performance data grid
|
||||
designed for the ReactJS web framework.
|
||||
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
|
||||
This demo uses Glide Data Grid and SheetJS to pull data from a spreadsheet and
|
||||
display the content in a data grid. We'll explore how to import data from files
|
||||
into the data grid and how to export modified data from the grid to workbooks.
|
||||
|
||||
The ["Demo"](#demo) section includes a complete example that displays data from
|
||||
user-supplied sheets and exports data to XLSX workbooks:
|
||||
|
||||
![Glide Data Grid example](pathname:///gdg/gdg.png)
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last tested on 2023 February 07 with the ViteJS+React+TypeScript
|
||||
starter (Vite `4.1.1`, React `18.2.0`) and `@glideapps/glide-data-grid@5.2.1`.
|
||||
This demo was last tested on 2023 August 17 with Glide Data Grid 5.2.1
|
||||
|
||||
:::
|
||||
|
||||
## Integration Details
|
||||
|
||||
[The "Frameworks" section](/docs/getting-started/installation/frameworks) covers
|
||||
installation with Yarn and other package managers.
|
||||
|
||||
Using the `npm` tool, this command installs SheetJS and Glide Data Grid:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @glideapps/glide-data-grid@5.2.1`}
|
||||
</CodeBlock>
|
||||
|
||||
Methods and components in both libraries can be loaded in pages using `import`:
|
||||
|
||||
```js
|
||||
import { read, utils, writeFile } from 'xlsx';
|
||||
import { DataEditor, GridCellKind, GridCell, Item } from '@glideapps/glide-data-grid';
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
Glide Data Grid is primarily event-based. It does not manage state directly.
|
||||
Instead, developers are expected to manage updates when users edit cells.
|
||||
|
||||
:::
|
||||
|
||||
#### Backing Store
|
||||
|
||||
Under the hood, the `DataEditor` component is designed to call methods and
|
||||
request data to display in the grid. It is typical to store data *outside* of
|
||||
component state. A `getCellContent` callback will pull data from the external
|
||||
backing store, while SheetJS operations will directly act on the store:
|
||||
backing store, while SheetJS operations will directly act on the store.
|
||||
|
||||
For this demo, there are two parts to the data store:
|
||||
|
||||
- `data` is an "Array of Objects" that will hold the raw data[^1].
|
||||
|
||||
- `header` is an array of the header names
|
||||
|
||||
:::info pass
|
||||
|
||||
Following the Glide Data Grid conventions[^2], both objects are defined at the top
|
||||
level of the component script. They are declared outside of the component!
|
||||
|
||||
:::
|
||||
|
||||
```js
|
||||
// !! THESE OBJECTS ARE DEFINED OUTSIDE OF THE COMPONENT FUNCTION !!
|
||||
// !! THESE ARRAYS ARE DEFINED OUTSIDE OF THE COMPONENT FUNCTION !!
|
||||
|
||||
// this will store the raw data objects
|
||||
let data: any[] = [];
|
||||
@ -34,9 +86,9 @@ let header: string[] = [];
|
||||
|
||||
#### Props
|
||||
|
||||
:::note
|
||||
:::note pass
|
||||
|
||||
This is a high-level overview. The official documentation should be consulted.
|
||||
This is a high-level overview. The official documentation should be consulted.[^3]
|
||||
|
||||
:::
|
||||
|
||||
@ -142,8 +194,16 @@ The demo uses the `onCellEdited` callback to write back to the data store.
|
||||
|
||||
_SheetJS to Data Store_
|
||||
|
||||
The raw data objects are readily generated with `sheet_to_json`. The headers
|
||||
can be pulled by extracting the first row of the worksheet:
|
||||
The SheetJS `read` method parses data from a number of sources[^4]. It returns a
|
||||
workbook object which holds worksheet objects and other data[^5].
|
||||
|
||||
Raw data objects can be generated with the SheetJS `sheet_to_json` function[^6].
|
||||
|
||||
The headers can be pulled from the first row of the sheet. The `sheet_to_json`
|
||||
method accepts a `range` option, and other SheetJS API functions can be used to
|
||||
calculate the correct range for the header names[^7].
|
||||
|
||||
This example generates row objects from the first sheet in the workbook:
|
||||
|
||||
```js
|
||||
import { utils, WorkBook } from 'xlsx';
|
||||
@ -220,12 +280,22 @@ export default App;
|
||||
|
||||
### Writing Data
|
||||
|
||||
`json_to_sheet` works directly on the `data` array:
|
||||
The SheetJS `json_to_sheet` method generates worksheet objects directly from
|
||||
the `data` array[^8]:
|
||||
|
||||
```js
|
||||
const ws = utils.json_to_sheet(data); // easy :)
|
||||
```
|
||||
|
||||
The worksheet can be exported to XLSX by creating a SheetJS workbook object[^9]
|
||||
and writing with `writeFile` or `writeFileXLSX`[^10]:
|
||||
|
||||
```js
|
||||
const wb = utils.book_new();
|
||||
utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
writeFileXLSX(wb, "sheetjs-gdg.xlsx");
|
||||
```
|
||||
|
||||
Since the editor can change the header titles, it is strongly recommended to
|
||||
pull column data from the state and rewrite the header row:
|
||||
|
||||
@ -262,7 +332,7 @@ export default App;
|
||||
|
||||
## Demo
|
||||
|
||||
1) Create a new project:
|
||||
1) Create a new project from the `react-ts` template:
|
||||
|
||||
```bash
|
||||
npm create vite@latest -- sheetjs-gdg --template react-ts
|
||||
@ -297,7 +367,7 @@ Refresh the browser window and a grid should be displayed:
|
||||
|
||||
3) To test the export functionality, make some changes to the grid data.
|
||||
|
||||
Suppose you believe that President Grover Cleveland should be counted once.
|
||||
Some statisticians believe President Grover Cleveland should be counted once.
|
||||
That would imply President Clinton should be index 41 and the indices of the
|
||||
other presidents should be decremented. By double-clicking on each cell in the
|
||||
Index column, a cell editor should appear. Decrement each index:
|
||||
@ -305,3 +375,14 @@ Index column, a cell editor should appear. Decrement each index:
|
||||
![glide-data-grid after edits](pathname:///gdg/post.png)
|
||||
|
||||
Click on the "Export" button to create a file! Open the file and verify.
|
||||
|
||||
[^1]: See ["Array of Objects" in the ReactJS demo](/docs/demos/frontend/react#array-of-objects)
|
||||
[^2]: The "Story" section of the ["Getting Started" page in the Glide Data Grid Storybook](https://quicktype.github.io/glide-data-grid/?path=/story/glide-data-grid-docs--getting-started) stores an Array of Objects outside of the component.
|
||||
[^3]: See [the "Data" section in `DataEditorProps`](https://grid.glideapps.com/docs/interfaces/DataEditorProps.html#columns:~:text=default-,Data,-Readonly) in the Glide Data Grid API documentation.
|
||||
[^4]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
[^5]: See ["SheetJS Data Model"](/docs/csf)
|
||||
[^6]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^7]: ["Addresses and Ranges"](/docs/csf/general) covers general concepts and utility functions including [`decode_range`](/docs/csf/general#cell-ranges-1).
|
||||
[^8]: See ["Array of Objects Input" in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
|
||||
[^9]: See ["Workbook Helpers" in "Utilities"](/docs/api/utilities/wb) for details on `book_new` and `book_append_sheet`.
|
||||
[^10]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Lume
|
||||
title: Illuminating Data with Lume
|
||||
sidebar_label: Lume
|
||||
description: Make static websites from spreadsheets using Lume. Seamlessly integrate data into your website using SheetJS. Illuminate data without leaving the comfort of Excel.
|
||||
pagination_prev: demos/net/index
|
||||
@ -8,8 +8,6 @@ sidebar_custom_props:
|
||||
type: native
|
||||
---
|
||||
|
||||
# Illuminating Data with Lume
|
||||
|
||||
[Lume](https://lume.land/) is a lightweight unopinionated static site generator.
|
||||
It has a rich ecosystem of JavaScript-powered plugins[^1]
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: NuxtJS
|
||||
title: Spreadsheets in VueJS Sites with NuxtJS
|
||||
sidebar_label: NuxtJS
|
||||
description: Make static websites from spreadsheets using NuxtJS. Seamlessly integrate data into the data layer using SheetJS. Create content without leaving the comfort of Excel.
|
||||
pagination_prev: demos/net/index
|
||||
pagination_next: demos/mobile/index
|
||||
---
|
||||
@ -7,11 +9,27 @@ pagination_next: demos/mobile/index
|
||||
import current from '/version.js';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
`@nuxt/content` is a file-based CMS for Nuxt, enabling static-site generation
|
||||
and on-demand server rendering powered by spreadsheets.
|
||||
[Nuxt Content](https://content.nuxtjs.org/) is a file-based CMS for NuxtJS,
|
||||
enabling static-site generation and on-demand server rendering from data files.
|
||||
|
||||
The [NodeJS module](/docs/getting-started/installation/nodejs) can be imported
|
||||
from Content v1 "parsers" and Content v2 "transformers".
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
|
||||
This demo uses NuxtJS and SheetJS to pull data from a spreadsheet and display
|
||||
the content in an HTML table.
|
||||
|
||||
:::info pass
|
||||
|
||||
There were breaking changes between VueJS 2.x and VueJS 3.x. Since many projects
|
||||
still use VueJS 2.x, this demo includes examples for both versions of VueJS.
|
||||
|
||||
:::
|
||||
|
||||
The ["Nuxt Content v1"](#nuxt-content-v1) section explores "parsers" for NuxtJS
|
||||
Content v1 (paired with VueJS 2.x and NuxtJS 2.x)
|
||||
|
||||
The ["Nuxt Content v2"](#nuxt-content-v2) section explores "transformers" for
|
||||
NuxtJS Content v2 (paired with VueJS 3.x and NuxtJS 3.x)
|
||||
|
||||
:::note
|
||||
|
||||
@ -19,8 +37,8 @@ The following deployments were tested:
|
||||
|
||||
| Nuxt Content | Nuxt | Date |
|
||||
|:-------------|:---------|:-----------|
|
||||
| `1.15.1` | `2.16.3` | 2023-06-01 |
|
||||
| `2.6.0` | `3.5.2` | 2023-06-01 |
|
||||
| `1.15.1` | `2.17.1` | 2023-08-16 |
|
||||
| `2.7.2` | `3.6.5` | 2023-08-16 |
|
||||
|
||||
:::
|
||||
|
||||
@ -57,7 +75,7 @@ telemetry.enabled=false
|
||||
|
||||
## Nuxt Content v1
|
||||
|
||||
Nuxt Content v1 is designed to work with Nuxt v2.
|
||||
Nuxt Content v1 is designed to work with NuxtJS v2 and VueJS v2.
|
||||
|
||||
The following diagram depicts the workbook waltz:
|
||||
|
||||
@ -74,22 +92,59 @@ flowchart LR
|
||||
aoo --> |index.vue\ntemplate| html
|
||||
```
|
||||
|
||||
### Configuration
|
||||
### Installation
|
||||
|
||||
Through an override in `nuxt.config.js`, Nuxt Content will use custom parsers.
|
||||
Differences from a stock `create-nuxt-app` config are shown below:
|
||||
The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be
|
||||
imported from `nuxt.config.js` for build-time processing.
|
||||
|
||||
```js title="nuxt.config.js"
|
||||
### Custom Parser
|
||||
|
||||
:::info pass
|
||||
|
||||
Custom parsers receive the file content interpreted as UTF-8 strings. For binary
|
||||
formats including XLSX and XLS, the data is corrupt and cannot be used.
|
||||
|
||||
The workaround involves safely re-reading the spreadsheets.
|
||||
|
||||
:::
|
||||
|
||||
The second argument passed to the parser is an object. The `path` property of
|
||||
the object is the path to the file.
|
||||
|
||||
The SheetJS `readFile`[^1] method can locate and parse the spreadsheet files.
|
||||
The `sheet_to_json`[^2] utility function can generate arrays of row objects for
|
||||
use in NuxtJS pages:
|
||||
|
||||
```js title="Custom Parser (in nuxt.config.js)"
|
||||
import { readFile, utils } from 'xlsx';
|
||||
|
||||
// This will be called when the files change
|
||||
/* This will be called when the files change */
|
||||
const parseSheet = (file, { path }) => {
|
||||
// `path` is a path that can be read with `XLSX.readFile`
|
||||
/* `path` is a path that can be read with `XLSX.readFile` */
|
||||
const wb = readFile(path);
|
||||
const o = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])}));
|
||||
|
||||
/* iterate through each worksheet name and generate row objects */
|
||||
const o = wb.SheetNames.map(name => ({
|
||||
name: name,
|
||||
data: utils.sheet_to_json(wb.Sheets[name])
|
||||
}));
|
||||
|
||||
/* The final result must be stored in the `data` key of an object */
|
||||
return { data: o };
|
||||
};
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
Using `content.extendParser`[^3], Nuxt Content will use custom parsers.
|
||||
|
||||
The property is expected to be an object whose keys are file extensions (with
|
||||
the `.` before the extension) and whose values are custom parser functions.
|
||||
|
||||
The relevant part of the config is shown below. In this snippet, the custom
|
||||
parser `parseSheet` will be associated with XLSX, XLS and NUMBERS files:
|
||||
|
||||
```js title="nuxt.config.js"
|
||||
export default {
|
||||
// ...
|
||||
|
||||
@ -114,7 +169,7 @@ When a spreadsheet is placed in the `content` folder, Nuxt will find it. The
|
||||
data can be referenced in a view with `asyncData`. The name should not include
|
||||
the extension, so `"sheetjs.numbers"` would be referenced as `"sheetjs"`:
|
||||
|
||||
```js
|
||||
```js title="Script section of .vue VueJS page"
|
||||
async asyncData ({$content}) {
|
||||
return {
|
||||
// $content('sheetjs') will match files with extensions in nuxt.config.js
|
||||
@ -125,9 +180,9 @@ the extension, so `"sheetjs.numbers"` would be referenced as `"sheetjs"`:
|
||||
|
||||
In the template, `data.data` is an array of objects. Each object has a `name`
|
||||
property for the worksheet name and a `data` array of row objects. This maps
|
||||
neatly with nested `v-for`:
|
||||
neatly with nested `v-for`[^4]:
|
||||
|
||||
```xml
|
||||
```xml title="Template section of .vue VueJS page"
|
||||
<!-- loop over the worksheets -->
|
||||
<div v-for="item in data.data" v-bind:key="item.name">
|
||||
<table>
|
||||
@ -143,10 +198,10 @@ neatly with nested `v-for`:
|
||||
|
||||
### Nuxt Content Demo
|
||||
|
||||
:::caution
|
||||
:::caution pass
|
||||
|
||||
When the demo was last tested, parts of the Nuxt dependency tree did not support
|
||||
NodeJS version 20. The creation step will show warnings like
|
||||
For some older versions, parts of the Nuxt dependency tree did not support
|
||||
NodeJS version 20. `EBADENGINE` warnings were displayed during app creation:
|
||||
|
||||
```
|
||||
npm WARN EBADENGINE Unsupported engine {
|
||||
@ -247,7 +302,7 @@ Replace the property with the following definition:
|
||||
|
||||
5) Replace `pages/index.vue` with the following:
|
||||
|
||||
```html
|
||||
```html title="pages/index.vue"
|
||||
<!-- sheetjs (C) 2013-present SheetJS -- https://sheetjs.com -->
|
||||
<template><div>
|
||||
<div v-for="item in data.data" v-bind:key="item.name">
|
||||
@ -310,7 +365,7 @@ will not change.
|
||||
|
||||
## Nuxt Content v2
|
||||
|
||||
Nuxt Content v2 is designed to work with Nuxt v3.
|
||||
Nuxt Content v2 is designed to work with NuxtJS v3 and VueJS v3.
|
||||
|
||||
The following diagram depicts the workbook waltz:
|
||||
|
||||
@ -327,14 +382,35 @@ flowchart LR
|
||||
aoo --> |index.vue\nContentRenderer| html
|
||||
```
|
||||
|
||||
### Overview
|
||||
### Installation
|
||||
|
||||
The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be
|
||||
safely imported from `nuxt.config.js` or transformer or module scripts. As long
|
||||
as the SheetJS modules are not imported in the various `.vue` pages, the library
|
||||
will not be added to the final page bundle!
|
||||
|
||||
### Custom Transformer
|
||||
|
||||
Nuxt Content `v2` supports custom transformers for controlling data. Although
|
||||
the library hard-codes UTF-8 interpretations, the `_id` field currently uses
|
||||
the pattern `content:` followed by the filename (if files are placed in the
|
||||
`content` folder directly). This enables a transformer to re-read the file:
|
||||
`content` folder directly). This enables a transformer to re-read the file.
|
||||
|
||||
```ts title="Transformer"
|
||||
<details><summary><b>Transformer Details</b> (click to show)</summary>
|
||||
|
||||
For example, if the file `pres.xlsx` is stored in the `content` folder, NuxtJS
|
||||
Content will use ID `"content:pres.xlsx"`. `"./content/" + _id.slice(8)` will
|
||||
be the original path `"./content/pres.xlsx"`.
|
||||
|
||||
The NodeJS `resolve`[^5] method will return a file path. `readFileSync`[^6] will
|
||||
read the file and return a NodeJS `Buffer`. That `Buffer` object can be parsed
|
||||
with the SheetJS `read`[^7] method. The `sheet_to_json`[^8] utility function can
|
||||
generate arrays of row objects for use in NuxtJS pages.
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
```ts title="sheetformer.ts (Transformer)"
|
||||
// @ts-ignore
|
||||
import { defineTransformer } from "@nuxt/content/transformers/utils";
|
||||
import { read, utils } from "xlsx";
|
||||
@ -343,6 +419,7 @@ import { resolve } from 'node:path';
|
||||
|
||||
export default defineTransformer({
|
||||
name: 'sheetformer',
|
||||
/* list of file extensions */
|
||||
extensions: ['.xlsx'],
|
||||
parse (_id: string, rawContent: string) {
|
||||
// highlight-start
|
||||
@ -352,47 +429,115 @@ export default defineTransformer({
|
||||
const wb = read(buf);
|
||||
// highlight-end
|
||||
/* generate JS objects for each worksheet */
|
||||
const body = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])}));
|
||||
const body = wb.SheetNames.map(name => ({
|
||||
name: name,
|
||||
data: utils.sheet_to_json(wb.Sheets[name])
|
||||
}));
|
||||
/* The final result must have the `_id` key and must store data in `body` */
|
||||
return { _id, body };
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Pages can pull data using `useAsyncData`:
|
||||
The data object returned by the transformer must have the original `_id` key.
|
||||
The data is stored in the `body` property of the final object.
|
||||
|
||||
```html title="Page"
|
||||
### Custom Modules
|
||||
|
||||
NuxtJS modules are the main mechanism for adding transformers to the pipeline.
|
||||
|
||||
<details><summary><b>Module Details</b> (click to show)</summary>
|
||||
|
||||
Due to the structure of the NuxtJS system, modules must be defined in separate
|
||||
script files. The module script is expected to export a module configured with
|
||||
`defineNuxtModule`. The setup method is expected to do the following:
|
||||
|
||||
- Register itself with the "Nitro" subsystem
|
||||
|
||||
- Add the transformer to Nuxt Content in the `content:context` hook
|
||||
|
||||
```js title="sheetmodule.ts (Module)"
|
||||
import { resolve } from 'path'
|
||||
import { defineNuxtModule } from '@nuxt/kit'
|
||||
|
||||
export default defineNuxtModule({
|
||||
/* module setup method */
|
||||
setup (_options, nuxt) {
|
||||
/* register with the nitro subsystem */
|
||||
nuxt.options.nitro.externals = nuxt.options.nitro.externals || {};
|
||||
nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || [];
|
||||
nuxt.options.nitro.externals.inline.push(resolve('./sheetmodule'));
|
||||
|
||||
/* add transformer in the content:context hook */
|
||||
// @ts-ignore
|
||||
nuxt.hook('content:context', (contentContext) => {
|
||||
contentContext.transformers.push(resolve('./sheetformer.ts'));
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The module must be loaded in `nuxt.config.ts` and added to the `modules` array:
|
||||
|
||||
```ts title="nuxt.config.ts"
|
||||
// highlight-next-line
|
||||
import SheetJSModule from './sheetmodule'
|
||||
|
||||
export default defineNuxtConfig({
|
||||
// @ts-ignore
|
||||
telemetry: false,
|
||||
modules: [
|
||||
// highlight-next-line
|
||||
SheetJSModule,
|
||||
/* it is recommended to load the custom modules before @nuxt/content */
|
||||
'@nuxt/content'
|
||||
],
|
||||
content: {}
|
||||
});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Rendering Data
|
||||
|
||||
Pages can pull data using `useAsyncData` in the page setup:
|
||||
|
||||
```html title="Script section of .vue VueJS page"
|
||||
<script setup>
|
||||
const key = "pres"; // matches pres.xlsx
|
||||
const {data} = await useAsyncData('x', ()=>queryContent(`/${key}`).findOne());
|
||||
// data.body is the output from the transformer and can be used in the template
|
||||
const { data } = await useAsyncData('x', ()=>queryContent(`/${key}`).findOne());
|
||||
</script>
|
||||
```
|
||||
|
||||
Pages should use `ContentRenderer` to reference the data:
|
||||
Pages should use `ContentRenderer` to reference the data. The `data` variable
|
||||
from the script setup will be shaped like the return value from the transformer.
|
||||
`data.body` is an array of objects that holds the worksheet name and data.
|
||||
|
||||
```html title="Page"
|
||||
<template><ContentRenderer :value="data">
|
||||
<!-- data.body is the array defined in the transformer -->
|
||||
<div v-for="item in data.body" v-bind:key="item.name">
|
||||
<!-- each item has a "name" string for worsheet name -->
|
||||
<h2>{{ item.name }}</h2>
|
||||
<!-- each item has a "body" array of data rows -->
|
||||
<table><thead><tr><th>Name</th><th>Index</th></tr></thead><tbody>
|
||||
<tr v-for="row in item.data" v-bind:key="row.Index">
|
||||
<!-- Assuming the sheet uses the columns "Name" and "Index" -->
|
||||
<td>{{ row.Name }}</td>
|
||||
<td>{{ row.Index }}</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</ContentRenderer></template>
|
||||
```html title="Template section of .vue VueJS page"
|
||||
<template>
|
||||
<ContentRenderer :value="data">
|
||||
<!-- data.body is the array defined in the transformer -->
|
||||
<div v-for="item in data.body" v-bind:key="item.name">
|
||||
<!-- each item has a "name" string for worksheet name -->
|
||||
<h2>{{ item.name }}</h2>
|
||||
<!-- each item has a "body" array of data rows -->
|
||||
<table><thead><tr><th>Name</th><th>Index</th></tr></thead><tbody>
|
||||
<tr v-for="row in item.data" v-bind:key="row.Index">
|
||||
<!-- Assuming the sheet uses the columns "Name" and "Index" -->
|
||||
<td>{{ row.Name }}</td>
|
||||
<td>{{ row.Index }}</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</ContentRenderer>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Nuxt Content 2 Demo
|
||||
|
||||
:::caution
|
||||
:::caution pass
|
||||
|
||||
When the demo was last tested, parts of the Nuxt dependency tree did not support
|
||||
For some older versions, parts of the Nuxt dependency tree did not support
|
||||
NodeJS version 20. If the `yarn install` step fails with a message like
|
||||
|
||||
```
|
||||
@ -434,47 +579,14 @@ The server is listening on that URL. Open the link in a web browser.
|
||||
curl -L -o content/pres.xlsx https://sheetjs.com/pres.xlsx
|
||||
```
|
||||
|
||||
4) Create the transformer.
|
||||
4) Create the transformer. Two files must be saved at the root of the project:
|
||||
|
||||
Two files must be written at the root of the project:
|
||||
- [`sheetformer.ts`](https://docs.sheetjs.com/nuxt/3/sheetformer.ts) (raw transformer module)
|
||||
- [`sheetmodule.ts`](https://docs.sheetjs.com/nuxt/3/sheetmodule.ts) (Nuxt configuration module)
|
||||
|
||||
- `sheetformer.ts` (the raw transformer module):
|
||||
|
||||
```ts title="sheetformer.ts"
|
||||
// @ts-ignore
|
||||
import { defineTransformer } from "@nuxt/content/transformers/utils";
|
||||
import { read, utils } from "xlsx";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
export default defineTransformer({
|
||||
name: 'sheetformer',
|
||||
extensions: ['.xlsx'],
|
||||
parse (_id: string, rawContent: string) {
|
||||
const wb = read(readFileSync(resolve("./content/" + _id.slice(8))));
|
||||
const body = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])}));
|
||||
return { _id, body };
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
- `sheetmodule.ts` (the Nuxt configuration module):
|
||||
|
||||
```ts title="sheetmodule.ts"
|
||||
import { resolve } from 'path'
|
||||
import { defineNuxtModule } from '@nuxt/kit'
|
||||
|
||||
export default defineNuxtModule({
|
||||
setup (_options, nuxt) {
|
||||
nuxt.options.nitro.externals = nuxt.options.nitro.externals || {}
|
||||
nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || []
|
||||
nuxt.options.nitro.externals.inline.push(resolve('./sheetmodule'))
|
||||
// @ts-ignore
|
||||
nuxt.hook('content:context', (contentContext) => {
|
||||
contentContext.transformers.push(resolve('./sheetformer.ts'))
|
||||
})
|
||||
}
|
||||
})
|
||||
```bash
|
||||
curl -O https://docs.sheetjs.com/nuxt/3/sheetformer.ts
|
||||
curl -O https://docs.sheetjs.com/nuxt/3/sheetmodule.ts
|
||||
```
|
||||
|
||||
After creating the source files, the module must be added to `nuxt.config.ts`:
|
||||
@ -490,7 +602,7 @@ export default defineNuxtConfig({
|
||||
'@nuxt/content'
|
||||
],
|
||||
content: {}
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
Restart the dev server by exiting the process (Control+C) and running:
|
||||
@ -520,25 +632,11 @@ Loading `http://localhost:3000/pres` should show some JSON data:
|
||||
},
|
||||
```
|
||||
|
||||
5) Create a page. Save the following content to `pages/pres.vue`:
|
||||
5) Download [`pres.vue`](pathname:///nuxt/3/pres.vue) and save to `pages`:
|
||||
|
||||
```html title="pages/pres.vue"
|
||||
<script setup>
|
||||
const {data} = await useAsyncData('s5s', () => queryContent('/pres').findOne());
|
||||
</script>
|
||||
<template><ContentRenderer :value="data">
|
||||
<div v-for="item in data.body" v-bind:key="item.name">
|
||||
<h2>{{ item.name }}</h2>
|
||||
<table><thead><tr><th>Name</th><th>Index</th></tr></thead><tbody>
|
||||
<tr v-for="row in item.data" v-bind:key="row.Index">
|
||||
<td>{{ row.Name }}</td>
|
||||
<td>{{ row.Index }}</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</ContentRenderer></template>
|
||||
```bash
|
||||
curl -o pages/pres.vue https://docs.sheetjs.com/nuxt/3/pres.vue
|
||||
```
|
||||
|
||||
Restart the dev server by exiting the process (Control+C) and running:
|
||||
|
||||
```bash
|
||||
@ -568,3 +666,12 @@ npx -y http-server .output/public
|
||||
Accessing `http://localhost:8080/pres` will show the page contents. Verifying
|
||||
the static nature is trivial: make another change in Excel and save. The page
|
||||
will not change.
|
||||
|
||||
[^1]: See [`readFile` in "Reading Files"](/docs/api/parse-options)
|
||||
[^2]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^3]: See [`extendParser`](https://content.nuxtjs.org/v1/getting-started/configuration#extendparser) in the NuxtJS documentation.
|
||||
[^4]: See ["Array of Objects" in the VueJS demo](/docs/demos/frontend/vue#array-of-objects)
|
||||
[^5]: See [`resolve`](https://nodejs.org/api/path.html#pathresolvepaths) in the NodeJS `node:path` documentation
|
||||
[^6]: See [`readFileSync`](https://nodejs.org/api/fs.html#fsreadfilesyncpath-options) in the NodeJS `node:fs` documentation
|
||||
[^7]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
[^8]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
|
@ -177,7 +177,7 @@ XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL_PAYLOAD, compression:
|
||||
After installing the package:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
bun i https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</CodeBlock>
|
||||
|
||||
The scripts will be available at `xlsx/dist/xlsx.zahl` (CommonJS) and
|
||||
@ -226,33 +226,33 @@ XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL_PAYLOAD, compression:
|
||||
For broad compatibility with third-party tools, this library supports many
|
||||
output formats. The specific file type is controlled with `bookType` option:
|
||||
|
||||
| `bookType` | file ext | container | sheets | Description |
|
||||
| :--------- | -------: | :-------: | :----- |:------------------------------- |
|
||||
| `xlsx` | `.xlsx` | ZIP | multi | Excel 2007+ XML Format |
|
||||
| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format |
|
||||
| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format |
|
||||
| `biff8` | `.xls` | CFB | multi | Excel 97-2004 Workbook Format |
|
||||
| `biff5` | `.xls` | CFB | multi | Excel 5.0/95 Workbook Format |
|
||||
| `biff4` | `.xls` | none | single | Excel 4.0 Worksheet Format |
|
||||
| `biff3` | `.xls` | none | single | Excel 3.0 Worksheet Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `numbers` |`.numbers`| ZIP | single | Numbers 3.0+ Spreadsheet |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet |
|
||||
| `wk3` | `.wk3` | none | multi | Lotus Workbook (WK3) |
|
||||
| `csv` | `.csv` | none | single | Comma Separated Values |
|
||||
| `txt` | `.txt` | none | single | UTF-16 Unicode Text (TXT) |
|
||||
| `sylk` | `.sylk` | none | single | Symbolic Link (SYLK) |
|
||||
| `html` | `.html` | none | single | HTML Document |
|
||||
| `dif` | `.dif` | none | single | Data Interchange Format (DIF) |
|
||||
| `dbf` | `.dbf` | none | single | dBASE II + VFP Extensions (DBF) |
|
||||
| `wk1` | `.wk1` | none | single | Lotus Worksheet (WK1) |
|
||||
| `rtf` | `.rtf` | none | single | Rich Text Format (RTF) |
|
||||
| `prn` | `.prn` | none | single | Lotus Formatted Text |
|
||||
| `eth` | `.eth` | none | single | Ethercalc Record Format (ETH) |
|
||||
| `bookType` | extension | sheets | Description |
|
||||
|:-----------|:-----------|:-------|:--------------------------------|
|
||||
| `xlsx` | `.xlsx` | multi | Excel 2007+ XML Format |
|
||||
| `xlsm` | `.xlsm` | multi | Excel 2007+ Macro XML Format |
|
||||
| `xlsb` | `.xlsb` | multi | Excel 2007+ Binary Format |
|
||||
| `biff8` | `.xls` | multi | Excel 97-2004 Workbook Format |
|
||||
| `biff5` | `.xls` | multi | Excel 5.0/95 Workbook Format |
|
||||
| `biff4` | `.xls` | single | Excel 4.0 Worksheet Format |
|
||||
| `biff3` | `.xls` | single | Excel 3.0 Worksheet Format |
|
||||
| `biff2` | `.xls` | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `numbers` | `.numbers` | multi | Numbers 3.0+ Spreadsheet |
|
||||
| `ods` | `.ods` | multi | OpenDocument Spreadsheet |
|
||||
| `fods` | `.fods` | multi | Flat OpenDocument Spreadsheet |
|
||||
| `wk3` | `.wk3` | multi | Lotus Workbook (WK3) |
|
||||
| `csv` | `.csv` | single | Comma Separated Values |
|
||||
| `txt` | `.txt` | single | UTF-16 Unicode Text (TXT) |
|
||||
| `sylk` | `.sylk` | single | Symbolic Link (SYLK) |
|
||||
| `html` | `.html` | single | HTML Document |
|
||||
| `dif` | `.dif` | single | Data Interchange Format (DIF) |
|
||||
| `dbf` | `.dbf` | single | dBASE II + VFP Extensions (DBF) |
|
||||
| `wk1` | `.wk1` | single | Lotus Worksheet (WK1) |
|
||||
| `rtf` | `.rtf` | single | Rich Text Format (RTF) |
|
||||
| `prn` | `.prn` | single | Lotus Formatted Text |
|
||||
| `eth` | `.eth` | single | Ethercalc Record Format (ETH) |
|
||||
|
||||
- `compression` only applies to formats with ZIP containers.
|
||||
- `compression` applies to ZIP-based formats (XLSX, XLSM, XLSB, NUMBERS, ODS)
|
||||
- Formats that only support a single sheet require a `sheet` option specifying
|
||||
the worksheet. If the string is empty, the first worksheet is used.
|
||||
- `writeFile` will automatically guess the output file format based on the file
|
||||
|
18979
docz/static/dojo/dojo.js
vendored
Normal file
18979
docz/static/dojo/dojo.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>SheetJS + Dojo Read Demo</title></head>
|
||||
<head>
|
||||
<meta name="robots" content="noindex">
|
||||
<title>SheetJS + Dojo Read Demo</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>SheetJS + Dojo Read Demo</h1>
|
||||
|
||||
@ -13,16 +16,14 @@ dojoConfig = { packages: [
|
||||
{ name: "xlsx", location: "https://cdn.sheetjs.com/xlsx-latest/package/dist", main: "xlsx.full.min" }
|
||||
] };
|
||||
</script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
|
||||
<script src="dojo.js" data-dojo-config="isDebug:1, async:1"></script>
|
||||
<script>
|
||||
require(["dojo/request/xhr", "xlsx"], function(xhr, _XLSX) {
|
||||
xhr("https://sheetjs.com/pres.numbers", {
|
||||
headers: { "X-Requested-With": null },
|
||||
// highlight-next-line
|
||||
handleAs: "arraybuffer"
|
||||
}).then(function(ab) {
|
||||
/* read ArrayBuffer */
|
||||
// highlight-next-line
|
||||
var wb = XLSX.read(ab);
|
||||
/* display first worksheet data */
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
|
@ -1,6 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>SheetJS + Dojo Write Demo</title></head>
|
||||
<head>
|
||||
<meta name="robots" content="noindex">
|
||||
<title>SheetJS + Dojo Write Demo</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>SheetJS + Dojo Write Demo</h1>
|
||||
|
||||
@ -11,7 +14,7 @@ dojoConfig = { packages: [
|
||||
{ name: "xlsx", location: "https://cdn.sheetjs.com/xlsx-latest/package/dist", main: "xlsx.full.min" }
|
||||
] };
|
||||
</script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
|
||||
<script src="dojo.js" data-dojo-config="isDebug:1, async:1"></script>
|
||||
<script>
|
||||
require(["dojo/request/xhr", "xlsx"], function(xhr, _XLSX) {
|
||||
xhr("https://sheetjs.com/data/executive.json", {
|
||||
|
BIN
docz/static/gdg/gdg.png
Normal file
BIN
docz/static/gdg/gdg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
11
docz/static/nuxt/3/nuxt.config.ts
Normal file
11
docz/static/nuxt/3/nuxt.config.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import SheetJSModule from './sheetmodule'
|
||||
|
||||
export default defineNuxtConfig({
|
||||
// @ts-ignore
|
||||
telemetry: false,
|
||||
modules: [
|
||||
SheetJSModule,
|
||||
'@nuxt/content'
|
||||
],
|
||||
content: {}
|
||||
});
|
14
docz/static/nuxt/3/pres.vue
Normal file
14
docz/static/nuxt/3/pres.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<script setup>
|
||||
const {data} = await useAsyncData('s5s', () => queryContent('/pres').findOne());
|
||||
</script>
|
||||
<template><ContentRenderer :value="data">
|
||||
<div v-for="item in data.body" v-bind:key="item.name">
|
||||
<h2>{{ item.name }}</h2>
|
||||
<table><thead><tr><th>Name</th><th>Index</th></tr></thead><tbody>
|
||||
<tr v-for="row in item.data" v-bind:key="row.Index">
|
||||
<td>{{ row.Name }}</td>
|
||||
<td>{{ row.Index }}</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</ContentRenderer></template>
|
15
docz/static/nuxt/3/sheetformer.ts
Normal file
15
docz/static/nuxt/3/sheetformer.ts
Normal file
@ -0,0 +1,15 @@
|
||||
// @ts-ignore
|
||||
import { defineTransformer } from "@nuxt/content/transformers/utils";
|
||||
import { read, utils } from "xlsx";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
export default defineTransformer({
|
||||
name: 'sheetformer',
|
||||
extensions: ['.xlsx'],
|
||||
parse (_id: string, rawContent: string) {
|
||||
const wb = read(readFileSync(resolve("./content/" + _id.slice(8))));
|
||||
const body = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])}));
|
||||
return { _id, body };
|
||||
}
|
||||
});
|
14
docz/static/nuxt/3/sheetmodule.ts
Normal file
14
docz/static/nuxt/3/sheetmodule.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { resolve } from 'path'
|
||||
import { defineNuxtModule } from '@nuxt/kit'
|
||||
|
||||
export default defineNuxtModule({
|
||||
setup (_options, nuxt) {
|
||||
nuxt.options.nitro.externals = nuxt.options.nitro.externals || {}
|
||||
nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || []
|
||||
nuxt.options.nitro.externals.inline.push(resolve('./sheetmodule'))
|
||||
// @ts-ignore
|
||||
nuxt.hook('content:context', (contentContext) => {
|
||||
contentContext.transformers.push(resolve('./sheetformer.ts'))
|
||||
})
|
||||
}
|
||||
});
|
Loading…
Reference in New Issue
Block a user