diff --git a/Makefile b/Makefile index da7d7f9..da556c3 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,6 @@ react: init ## Simple server for react and clones .PHONY: next next: init ## next.js demo - mkdir -p pages public - cat nexthdr.js sheetjs.js > pages/sheetjs.js - cp ../../shim.js public/shim.js next .PHONY: native diff --git a/README.md b/README.md index df18f2f..a393970 100644 --- a/README.md +++ b/README.md @@ -96,20 +96,84 @@ Components used in the demo: - [`react-native-file-access`](https://npm.im/react-native-file-access) React Native does not provide a native component for reading and writing files. -The sample script <`react-native.js`> uses `react-native-file-access` and has +The sample script `react-native.js` uses `react-native-file-access` and has notes for integrations with `react-native-fetch-blob` and `react-native-fs`. Note: for real app deployments, the `UIFileSharingEnabled` flag must be manually set in the iOS project `Info.plist` file. -#### Server-Rendered React Components with Next.js +## Server-Rendered React Components with Next.js -The demo uses the same component code as the in-browser version, but the build -step adds a small header that imports the library. The import is not needed in -deployments that use script tags to include the library. +The demo reads from `public/sheetjs.xlsx`. HTML output is generated using +`XLSX.utils.sheet_to_html` and inserted with `dangerouslySetInnerHTML`: -[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx) +```jsx +export default function Index({html, type}) { return ( + // ... +
+ // ... +); } +``` + +Next currently offers 3 general strategies for server-side data fetching: + +#### "Server-Side Rendering" using `getServerSideProps` + +`/getServerSideProps` reads the file on each request. The first worksheet is +converted to HTML: + +```js +export async function getServerSideProps() { + const wb = XLSX.readFile(path); + return { props: { + html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]) + }}; +} +``` + +#### "Static Site Generation" using `getStaticProps` + +`/getServerSideProps` reads the file at build time. The first worksheet is +converted to HTML: + +```js +export async function getStaticProps() { + const wb = XLSX.readFile(path); + return { props: { + html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]) + }}; +} +``` + +#### "Static Site Generation with Dynamic Routes" using `getStaticPaths` + +`/getStaticPaths` reads the file at build time and generates a list of sheets. + +`/sheets/[id]` uses `getStaticPaths` to generate a path per sheet index: + +```js +export async function getStaticPaths() { + const wb = XLSX.readFile(path); + return { + paths: wb.SheetNames.map((name, idx) => ({ params: { id: idx.toString() } })), + fallback: false + }; +} +``` + +It also uses `getStaticProps` for the actual HTML generation: + +```js +export async function getStaticProps(ctx) { + const wb = XLSX.readFile(path); + return { props: { + html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[ctx.params.id]]), + }}; +} +``` ## Additional Notes Some additional notes can be found in [`NOTES.md`](NOTES.md). + +[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx) diff --git a/nexthdr.js b/nexthdr.js index 9d56421..1ba3dc6 100644 --- a/nexthdr.js +++ b/nexthdr.js @@ -1,3 +1,3 @@ /* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -import XLSX from 'xlsx'; -import React from 'react'; \ No newline at end of file +import * as XLSX from 'xlsx'; +import React from 'react'; diff --git a/pages/.gitignore b/pages/.gitignore deleted file mode 100644 index 7902a8c..0000000 --- a/pages/.gitignore +++ /dev/null @@ -1 +0,0 @@ -sheetjs.js diff --git a/pages/getServerSideProps.js b/pages/getServerSideProps.js new file mode 100644 index 0000000..55cd11f --- /dev/null +++ b/pages/getServerSideProps.js @@ -0,0 +1,32 @@ +import Head from 'next/head'; +import { readFile, utils } from 'xlsx'; +import { join } from 'path'; +import { cwd } from 'process'; + +export default function Index({html, type}) { return ( +
+ + + SheetJS Next.JS {type} Demo + + + +
+

SheetJS Next.JS {type} Demo

+This demo reads from /public/sheetjs.xlsx and generates HTML from the first sheet. +
+
+
+); } + +export async function getServerSideProps() { + const wb = readFile(join(cwd(), "public", "sheetjs.xlsx")) + return { + props: { + type: "getStaticProps", + html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]), + }, + } +} \ No newline at end of file diff --git a/pages/getStaticPaths.js b/pages/getStaticPaths.js new file mode 100644 index 0000000..3852295 --- /dev/null +++ b/pages/getStaticPaths.js @@ -0,0 +1,38 @@ +import Head from 'next/head'; +import Link from "next/link"; +import { readFile, utils } from 'xlsx'; +import { join } from 'path'; +import { cwd } from 'process'; + +export default function Index({snames, type}) { return ( +
+ + + SheetJS Next.JS {type} Demo + + + +
+

SheetJS Next.JS {type} Demo

+This demo reads from /public/sheetjs.xlsx. Each worksheet maps to a path:

+{snames.map((sname, idx) => (<> + {`Sheet index=${idx} name="${sname}"`} +
+
+))} + +
+
+); } + +export async function getStaticProps() { + const wb = readFile(join(cwd(), "public", "sheetjs.xlsx")) + return { + props: { + type: "getStaticPaths", + snames: wb.SheetNames, + }, + } +} \ No newline at end of file diff --git a/pages/getStaticProps.js b/pages/getStaticProps.js new file mode 100644 index 0000000..ca2e304 --- /dev/null +++ b/pages/getStaticProps.js @@ -0,0 +1,32 @@ +import Head from 'next/head'; +import { readFile, utils } from 'xlsx'; +import { join } from 'path'; +import { cwd } from 'process'; + +export default function Index({html, type}) { return ( +
+ + + SheetJS Next.JS {type} Demo + + + +
+

SheetJS Next.JS {type} Demo

+This demo reads from /public/sheetjs.xlsx and generates HTML from the first sheet. +
+
+
+); } + +export async function getStaticProps() { + const wb = readFile(join(cwd(), "public", "sheetjs.xlsx")) + return { + props: { + type: "getStaticProps", + html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]), + }, + } +} \ No newline at end of file diff --git a/pages/index.js b/pages/index.js index ce781fd..c93bccd 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,23 +1,24 @@ -import Head from 'next/head' -import SheetJSApp from './sheetjs' -const Index = () => ( +import Head from 'next/head'; + +export default function Index() { return (
- - - SheetJS React Demo - - - - -
-

SheetJS React Demo

-
- Source Code Repo
- Issues? Something look weird? Click here and report an issue

-
- + + + SheetJS Next.JS Demo + + + +
+

SheetJS Next.JS Demos

+All demos read from /public/sheetjs.xlsx.
+
+- getStaticProps
+
+- getServerSideProps
+
+- getStaticPaths
+
-); -export default Index; \ No newline at end of file +); } \ No newline at end of file diff --git a/pages/sheets/[id].js b/pages/sheets/[id].js new file mode 100644 index 0000000..530b675 --- /dev/null +++ b/pages/sheets/[id].js @@ -0,0 +1,51 @@ +import Head from 'next/head'; +import { readFile, utils } from 'xlsx'; +import { join } from 'path'; +import { cwd } from 'process'; + +export default function Index({html, type, name}) { return ( +
+ + + SheetJS Next.JS {type} Demo + + + +
+

SheetJS Next.JS {type} Demo

+This demo reads from /public/sheetjs.xlsx.
+
+{name} +
+
+
+); } + +let cache = []; + +export async function getStaticProps(ctx) { + if(!cache || !cache.length) { + const wb = readFile(join(cwd(), "public", "sheetjs.xlsx")); + cache = wb.SheetNames.map((name) => ({ name, sheet: wb.Sheets[name] })); + } + const entry = cache[ctx.params.id]; + return { + props: { + type: "getStaticPaths", + name: entry.name, + id: ctx.params.id.toString(), + html: entry.sheet ? utils.sheet_to_html(entry.sheet) : "", + }, + } +} + +export async function getStaticPaths() { + const wb = readFile(join(cwd(), "public", "sheetjs.xlsx")); + cache = wb.SheetNames.map((name) => ({ name, sheet: wb.Sheets[name] })); + return { + paths: wb.SheetNames.map((name, idx) => ({ params: { id: idx.toString() } })), + fallback: false, + }; +} diff --git a/public/sheetjs.xlsx b/public/sheetjs.xlsx new file mode 100644 index 0000000..25496b9 Binary files /dev/null and b/public/sheetjs.xlsx differ diff --git a/react-native.js b/react-native.js index c29eae6..2c11a98 100644 --- a/react-native.js +++ b/react-native.js @@ -1,5 +1,5 @@ /* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -import XLSX from 'xlsx'; +import * as XLSX from 'xlsx'; import React, { Component } from 'react'; import { AppRegistry,