Skip to content

Commit

Permalink
Merge pull request #89 from admisio/xlsx_export_svelte
Browse files Browse the repository at this point in the history
(backend) (frontend) SvelteKit RequestHandler file download
  • Loading branch information
starvy authored Mar 5, 2024
2 parents a46d48b + 62ffcc9 commit 87367d2
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 33 deletions.
24 changes: 24 additions & 0 deletions apps/web/src/routes/admin/(authenticated)/export/csv/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { RequestHandler } from './$types';

import { router } from '@testy/trpc/server/router';
import { createContext } from '@testy/trpc/server/createContext';

export const GET: RequestHandler = async (event) => {
try {
const trpc = router.createCaller(await createContext(event));

await trpc.auth.admin();

const xlsx = await trpc.users.csv();
const date = new Date().toISOString().split('.')[0];
return new Response(xlsx, {
status: 200,
headers: {
'Content-Type': 'text/csv',
'Content-Disposition': `attachment; filename="vysledky_${date}.csv"`
}
});
} catch {
return new Response('Čus 👀', { status: 403 });
}
};
24 changes: 24 additions & 0 deletions apps/web/src/routes/admin/(authenticated)/export/xlsx/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { RequestHandler } from './$types';

import { router } from '@testy/trpc/server/router';
import { createContext } from '@testy/trpc/server/createContext';

export const GET: RequestHandler = async (event) => {
try {
const trpc = router.createCaller(await createContext(event));

await trpc.auth.admin();

const xlsx = await trpc.users.xlsx();
return new Response(xlsx, {
status: 200,
headers: {
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
// TODO: Můžeme doplnit čas atd.
'Content-Disposition': `attachment; filename="vysledky.xlsx"`
}
});
} catch {
return new Response('Čus 👀', { status: 403 });
}
};
33 changes: 8 additions & 25 deletions apps/web/src/routes/admin/(authenticated)/users/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,38 +1,17 @@
<script lang="ts">
import { enhance } from '$app/forms';
import { goto } from '$app/navigation';
import Button from '$lib/components/buttons/Button.svelte';
import Submit from '$lib/components/buttons/Submit.svelte';
import TextInput from '$lib/components/inputs/TextInput.svelte';
import Modal from '$lib/components/Modal.svelte';
import UserListItem from '$lib/components/userlist/UserListItem.svelte';
import { trpc } from '$lib/trpc/client';
import type { ActionData, PageServerData } from './$types';
export let data: PageServerData;
// TODO: xlsx download
const downloadXlsx = async (e: Event) => {
const base64 = await trpc().users.xlsx.query();
const byteCharacters = atob(base64);
// Create a Uint8Array
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
// Create a Blob from the Uint8Array
const blob = new Blob([byteArray], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
// download the file
const anchor = window.document.createElement('a');
anchor.href = window.URL.createObjectURL(blob);
anchor.download = 'vysledky.xlsx';
anchor.click();
window.URL.revokeObjectURL(anchor.href);
const downloadXlsx = async () => {
window.open(`/admin/export/xlsx`, '_blank');
};
const openModal = async () => {
Expand Down Expand Up @@ -88,7 +67,11 @@
icon="material-symbols:add-circle-outline-rounded"
title="Přidat uživatele"
/>
<Button on:click={downloadXlsx} icon="material-symbols:download" title="Stáhnout výsledky" />
<Button
on:click={downloadXlsx}
icon="material-symbols:download"
title="Stáhnout výsledky"
/>
</div>
</div>
<div class="mx-auto mx-auto mb-6 flex max-w-screen-xl flex-col px-4 py-3 md:px-6 md:px-6">
Expand Down
2 changes: 1 addition & 1 deletion packages/trpc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"csv-stringify": "^6.3.0",
"date-fns": "^2.29.3",
"jsonwebtoken": "^9.0.0",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz",
"zod": "^3.21.4"
},
"devDependencies": {
Expand Down
4 changes: 4 additions & 0 deletions packages/trpc/server/routes/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export const users = t.router({
trpcInfo(ctx, `Created user ${input.username}`);
}),
csv: t.procedure.use(adminAuth).query(async () => exportCsv()),
/**
* @description Export users to xlsx, Only SSR
* @returns {Promise<ArrayBuffer>} ArrayBuffer, fallback array of 8-bit unsigned int
*/
xlsx: t.procedure.use(adminAuth).query(async () => exportXlsx()),
resetPassword: t.procedure
.use(adminAuth)
Expand Down
4 changes: 2 additions & 2 deletions packages/trpc/server/services/testService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class ResultCellMap extends Map<string, Record[]> {
}
}

export const exportXlsx = async (): Promise<string> => {
export const exportXlsx = async (): Promise<ArrayBuffer> => {
const workbook = XLXS.utils.book_new();
XLXS.set_fs(fs);

Expand Down Expand Up @@ -230,7 +230,7 @@ export const exportXlsx = async (): Promise<string> => {
const userSheet = getUserSheet(usersDb, resultCell);
XLXS.utils.book_append_sheet(workbook, userSheet, 'users');

return XLXS.write(workbook, { bookType: 'xlsx', type: 'base64' });
return XLXS.write(workbook, { bookType: 'xlsx', type: 'buffer' });
};

const getUserSheet = (users: User[], resultCell: ResultCellMap): XLXS.WorkSheet => {
Expand Down
14 changes: 9 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 87367d2

Please sign in to comment.