#!/usr/bin/env pwsh # https://docs.sheetjs.com/docs/demos/net/server#worker-threads $oldDir = Get-Location $tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-worker" if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } New-Item -ItemType Directory -Path $tempDir | Out-Null Set-Location -Path $tempDir '{ "type": "module" }' | Out-File -FilePath "package.json" -Encoding ASCII @' /* load the worker_threads module */ import { parentPort } from 'node:worker_threads'; /* load the SheetJS module and hook to FS */ import { set_fs, readFile, write } from 'xlsx'; import * as fs from 'fs'; set_fs(fs); /* the server will send a message with the `path` field */ parentPort.on('message', (task) => { // read file const wb = readFile(task.path, { dense: true }); // send back XLSX parentPort.postMessage(write(wb, { type: "buffer", bookType: "xlsx" })); // remove file fs.unlink(task.path, ()=>{}); }); '@ | Out-File -FilePath "worker.js" -Encoding ASCII Invoke-WebRequest -Uri "https://docs.sheetjs.com/server/worker_pool.js" -OutFile "worker_pool.js" Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" @' /* load dependencies */ import os from 'node:os'; import process from 'node:process' import express from 'express'; import formidable from 'formidable'; /* load worker pool */ import WorkerPool from './worker_pool.js'; const pool = new WorkerPool(os.cpus().length); process.on("beforeExit", () => { pool.close(); }) /* create server */ const app = express(); app.post('/', (req, res, next) => { // parse body const form = formidable({}); form.parse(req, (err, fields, files) => { // look for "upload" field if(err) return next(err); if(!files["upload"]) return next(new Error("missing `upload` file")); // send a message to the worker with the path to the uploaded file pool.runTask({ path: files["upload"].filepath }, (err, result) => { if(err) return next(err); // send the file back as an attachment res.attachment("SheetJSPool.xlsx"); res.status(200).end(result); }); }); }); // start server app.listen(7262, () => { console.log(`Example app listening on port 7262`); }); '@ | Out-File -FilePath "main.mjs" -Encoding ASCII npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz formidable@2.1.2 $expressVersions = @("4.21.2", "5.1.0") foreach ($express in $expressVersions) { npm i --save express@$express npm ls | Select-String "express" # Test with different node versions (if available) $nodeVersions = @(20, 22, 24) foreach ($n in $nodeVersions) { nvm use $n node --version $proc = Start-Process -NoNewWindow -FilePath "node" -ArgumentList "main.mjs" -PassThru Start-Sleep -Seconds 2 pwsh -NonInteractive -Command 'Invoke-WebRequest -Uri "http://localhost:7262/" -Method Post -Form @{ upload = Get-Item "pres.numbers" } -OutFile "SheetJSPool.xlsx"' npx -y xlsx-cli SheetJSPool.xlsx | Select-Object -First 10 Remove-Item -Path "SheetJSPool.xlsx" -Force $proc | Stop-Process } } Set-Location $oldDir Remove-Item -Path $tempDir -Recurse -Force