forked from sheetjs/docs.sheetjs.com
		
	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: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| :::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: | ||||
|  | ||||
| 
 | ||||
| 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