fix excel exports on publishers

This commit is contained in:
Dobromir Popov
2024-12-28 18:27:23 +02:00
parent c290b1a37b
commit 9e5cce3644
4 changed files with 19736 additions and 18 deletions

19697
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@ import fs from 'fs';
import path from 'path'; import path from 'path';
import { all } from "axios"; import { all } from "axios";
import { logger } from "src/helpers/common"; import { logger } from "src/helpers/common";
import { ExportPublishersToExcel } from "src/helpers/excel"; import { generatePublishersExcel } from "src/helpers/excel";
/** /**
* *
@ -435,9 +435,16 @@ export default async function handler(req, res) {
res.status(200).json(await dataHelper.getAllPublishersWithStatisticsMonth(day, noEndDate)); res.status(200).json(await dataHelper.getAllPublishersWithStatisticsMonth(day, noEndDate));
case "exportPublishersExcel": case "exportPublishersExcel":
try { try {
await ExportPublishersToExcel(req, res); const today = new Date();
const dateStr = today.toISOString().split('T')[0]; // Gets YYYY-MM-DD format
const excelBuffer = await generatePublishersExcel();
res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
res.setHeader("Content-Disposition", "attachment; filename=" + encodeURI(`Publishers_${dateStr}.xlsx`));
res.send(excelBuffer);
} catch (error) { } catch (error) {
console.error(JSON.stringify(error)); console.error(JSON.stringify(error));
res.status(500).json({ error: "Failed to generate Excel file" });
} }
break; break;
default: default:

View File

@ -197,20 +197,34 @@ function PublishersPage({ publishers = [] }: IProps) {
const exportPublishers = async () => { const exportPublishers = async () => {
try { try {
const response = await axiosInstance.get('/api/?action=exportPublishersExcel'); const response = await axiosInstance.get('/api/?action=exportPublishersExcel', { responseType: 'arraybuffer' });
const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
// Get filename from Content-Disposition header
const contentDisposition = response.headers['content-disposition'];
let filename = 'publishers.xlsx'; // default fallback
if (contentDisposition) {
const filenameMatch = contentDisposition.match(/filename=(.*?)(;|$)/);
if (filenameMatch) {
filename = decodeURI(filenameMatch[1]);
}
}
const blob = new Blob([response.data], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
const a = document.createElement('a'); const a = document.createElement('a');
a.href = url; a.href = url;
a.download = 'publishers.xlsx'; a.download = filename;
document.body.appendChild(a);
a.click(); a.click();
a.remove();
window.URL.revokeObjectURL(url); // Clean up
} catch (error) { } catch (error) {
console.error(JSON.stringify(error)); // Log the error console.error(JSON.stringify(error));
toast.error("Грешка при експорт на данни"); toast.error("Грешка при експорт на данни");
} }
} }
return ( return (
<Layout> <Layout>
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER]}> <ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER]}>
@ -245,7 +259,7 @@ function PublishersPage({ publishers = [] }: IProps) {
</div> </div>
{/* export by calling excel helper .ExportPublishersToExcel() */} {/* export by calling excel helper .ExportPublishersToExcel() */}
<div className="flex justify-center m-4"> <div className="flex justify-center m-4">
<button className="btn" onClick={exportPublishers}>Export to Excel</button> <button className="button m-2 btn btn-primary" onClick={exportPublishers}>Export to Excel</button>
</div> </div>
</div> </div>

View File

@ -616,7 +616,7 @@ exports.ReadDocxFileForMonth = async function (filePath, buffer, month, year, pr
}; };
exports.ExportPublishersToExcel = async function (req, res) { exports.generatePublishersExcel = async function () {
const prisma = common.getPrismaClient(); const prisma = common.getPrismaClient();
const publishers = await prisma.publisher.findMany({ const publishers = await prisma.publisher.findMany({
// where: { isActive: true, }, // where: { isActive: true, },
@ -624,9 +624,9 @@ exports.ExportPublishersToExcel = async function (req, res) {
// availabilities: { where: { isActive: true, }, }, // availabilities: { where: { isActive: true, }, },
// assignments: { include: { shift: true, }, }, // assignments: { include: { shift: true, }, },
congregation: true, congregation: true,
}, },
}); });
const ExcelJS = require("exceljs"); const ExcelJS = require("exceljs");
const xjswb = new ExcelJS.Workbook(); const xjswb = new ExcelJS.Workbook();
const sheet = xjswb.addWorksheet("Publishers"); const sheet = xjswb.addWorksheet("Publishers");
@ -639,10 +639,11 @@ exports.ExportPublishersToExcel = async function (req, res) {
{ header: "Congregation", key: "congregationName", width: 32 }, { header: "Congregation", key: "congregationName", width: 32 },
{ header: "Last Login", key: "lastLogin", width: 32 }, { header: "Last Login", key: "lastLogin", width: 32 },
{ header: "Type", key: "PublisherTypeText", width: 32 }, { header: "Type", key: "PublisherTypeText", width: 32 },
{ header: "Active", key: "isActive", width: 10 }, // { header: "Active", key: "isActive", width: 10 },
{ header: "Created At", key: "createdAt", width: 32 }, { header: "Created At", key: "createdAt", width: 32 },
{ header: "Updated At", key: "updatedAt", width: 32 }, { header: "Updated At", key: "updatedAt", width: 32 },
]; ];
publishers.forEach((publisher) => { publishers.forEach((publisher) => {
sheet.addRow({ sheet.addRow({
name: publisher.firstName + " " + publisher.lastName, name: publisher.firstName + " " + publisher.lastName,
@ -650,18 +651,17 @@ exports.ExportPublishersToExcel = async function (req, res) {
email: publisher.email, email: publisher.email,
phone: publisher.phone, phone: publisher.phone,
role: publisher.role, role: publisher.role,
congregationName: publisher.congregation.name, congregationName: publisher.congregation?.name || 'не е зададен', // Add null check here
lastLogin: publisher.lastLogin, lastLogin: publisher.lastLogin,
PublisherTypeText: publisher.PublisherTypeText, PublisherTypeText: publisher.PublisherTypeText,
isActive: publisher.isActive, // isActive: publisher.isActive,
createdAt: publisher.createdAt, createdAt: publisher.createdAt,
updatedAt: publisher.updatedAt, updatedAt: publisher.updatedAt,
}); });
}); });
res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
res.setHeader("Content-Disposition", "attachment; filename=" + encodeURI("Publishers.xlsx")); // Return a buffer with the Excel data
xjswb.xlsx.write(res); return await xjswb.xlsx.writeBuffer();
} }
const weekNames = [ const weekNames = [