Jaspers Hub

rym / excel-export

pluginReviewed★ 0↓ 0

Excel Export: Builds .xlsx workbooks from supplied tables or grid panel data and writes/opens them in the plugin's exports folder.

1.4 KB
1import type { BackendContext } from '@jaspers-ai/sdk'
2import { buildXlsx } from './xlsx'
3import { cleanFilename, defaultFilename, rowArrays, sheetNames } from './sheets'
4
5export interface TableInput {
6 title: string
7 columns: string[]
8 rows: unknown[]
9}
10
11function base64(bytes: Uint8Array): string {
12 let s = ''
13 for (let i = 0; i < bytes.length; i += 0x8000) s += String.fromCharCode(...bytes.subarray(i, i + 0x8000))
14 return btoa(s)
15}
16
17/** Builds the workbook, writes it under exports/, opens it, and answers path, sheets, and row counts. */
18export async function writeWorkbook(ctx: BackendContext, tables: TableInput[], filename?: string) {
19 if (tables.length === 0) throw new Error('No tables to export.')
20 const names = sheetNames(tables.map((t) => t.title))
21 const sheets = tables.map((t, i) => ({ name: names[i]!, columns: t.columns, rows: rowArrays(t.columns, t.rows) }))
22 const file = filename ? cleanFilename(filename) : defaultFilename(tables[0]!.title, new Date())
23 const path = `exports/${file}`
24 await ctx.files.write(path, base64(buildXlsx(sheets)), { encoding: 'base64' })
25 let opened = true
26 try {
27 await ctx.files.open(path)
28 } catch {
29 opened = false
30 }
31 return {
32 path,
33 location: `~/Jaspers/excel-export/${path}`,
34 opened,
35 sheets: sheets.map((s) => s.name),
36 rows: sheets.map((s) => ({ sheet: s.name, title: tables[sheets.indexOf(s)]!.title, rows: s.rows.length, columns: s.columns.length })),
37 }
38}