Improvements on excel rendering

This commit is contained in:
Joao Ramos
2024-08-18 21:25:18 +01:00
parent 1950d5f15d
commit bf1bdd935c

View File

@@ -46,6 +46,15 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "POST") return await post(req, res); if (req.method === "POST") return await post(req, res);
} }
function logWorksheetData(worksheet: any) {
worksheet.eachRow((row: any, rowNumber: number) => {
console.log(`Row ${rowNumber}:`);
row.eachCell((cell: any, colNumber: number) => {
console.log(` Cell ${colNumber}: ${cell.value}`);
});
});
}
async function post(req: NextApiRequest, res: NextApiResponse) { async function post(req: NextApiRequest, res: NextApiResponse) {
// verify if it's a logged user that is trying to export // verify if it's a logged user that is trying to export
if (req.session.user) { if (req.session.user) {
@@ -68,17 +77,17 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
return; return;
} }
if ( // if (
data.excel && // data.excel &&
data.excel.path && // data.excel.path &&
data.excel.version === process.env.EXCEL_VERSION // data.excel.version === process.env.EXCEL_VERSION
) { // ) {
// if it does, return the excel url // // if it does, return the excel url
const fileRef = ref(storage, data.excel.path); // const fileRef = ref(storage, data.excel.path);
const url = await getDownloadURL(fileRef); // const url = await getDownloadURL(fileRef);
res.status(200).end(url); // res.status(200).end(url);
return; // return;
} // }
const docsSnap = await getDocs( const docsSnap = await getDocs(
query(collection(db, "users"), where(documentId(), "in", data.assignees)) query(collection(db, "users"), where(documentId(), "in", data.assignees))
@@ -106,20 +115,29 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
const firstSectionData = [ const firstSectionData = [
{ {
label: "Corporate Name :", label: "Corporate Name :",
value: user.corporateInformation.companyInformation.name, value: user.corporateInformation?.companyInformation?.name || "",
}, },
{ {
label: "Report Download date :", label: "Report Download date :",
value: moment().format("DD/MM/YYYY"), value: moment().format("DD/MM/YYYY"),
}, },
{ label: "Test Information :", value: "TODO" }, { label: "Test Information :", value: "TODO" },
{ label: "Date of Test :", value: moment(data.startDate).format("DD/MM/YYYY") }, {
label: "Date of Test :",
value: moment(data.startDate).format("DD/MM/YYYY"),
},
{ label: "Number of Candidates :", value: data.assignees.length }, { label: "Number of Candidates :", value: data.assignees.length },
{ label: "Highest score :", value: highestScore }, { label: "Highest score :", value: highestScore },
{ label: "Lowest score :", value: lowestScore }, { label: "Lowest score :", value: lowestScore },
{ label: "", value: "" }, { label: "", value: "" },
{ label: "Date and time of First submission :", value: firstDate.format("DD/MM/YYYY") }, {
{ label: "Date and time of Last submission :", value: lastDate.format("DD/MM/YYYY") }, label: "Date and time of First submission :",
value: firstDate.format("DD/MM/YYYY"),
},
{
label: "Date and time of Last submission :",
value: lastDate.format("DD/MM/YYYY"),
},
]; ];
// Create a new workbook and add a worksheet // Create a new workbook and add a worksheet
@@ -132,19 +150,125 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
worksheet.getCell(`B${index + 1}`).value = value; // Second column (values) worksheet.getCell(`B${index + 1}`).value = value; // Second column (values)
}); });
// Set the response headers for downloading an Excel file logWorksheetData(worksheet);
res.setHeader(
"Content-Type", const testSectionsArray = [1, 2, 3, 4, 5];
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
); // Define the static part of the headers (before "Test Sections")
res.setHeader( const staticHeaders = [
"Content-Disposition", "Sr N",
"attachment; filename=ReportData.xlsx" "Candidate ID",
"First and Last Name",
"Passport/ID",
"Email ID",
"Gender",
];
// Define additional headers after "Test Sections"
const additionalHeaders = ["Time Spent", "Score", "Level"];
// Calculate the dynamic columns based on the testSectionsArray
const numberOfTestSections = testSectionsArray.length;
const testSectionHeaders = testSectionsArray.map(
(section, index) => `Part ${index + 1}`
); );
// Write the workbook to the response // Add the main header row, merging static columns and "Test Sections"
await workbook.xlsx.write(res); worksheet.addRow([
res.end(); ...staticHeaders,
...testSectionsArray.map((a) => "Test Sections"),
...additionalHeaders,
]);
// 1 headers rows
const startIndexTable = firstSectionData.length + 1;
logWorksheetData(worksheet);
// // Merge "Test Sections" over dynamic number of columns
// const tableColumns = staticHeaders.length + numberOfTestSections;
// worksheet.mergeCells(1, staticHeaders.length + 1, 1, tableColumns);
// logWorksheetData(worksheet);
// worksheet.mergeCells(`G1:G3`); // Time Spent
// worksheet.mergeCells(`H1:H3`); // Score
// worksheet.mergeCells(`I1:I3`); // Level
// Add the dynamic second and third header rows for test sections and sub-columns
worksheet.addRow([
...Array(staticHeaders.length).fill(""),
...testSectionHeaders,
"",
"",
"",
]);
worksheet.addRow([
...Array(staticHeaders.length).fill(""),
...testSectionsArray.map(() => "Grammar"),
"",
"",
"",
]);
// Merging static headers and "Test Sections" over dynamic columns
worksheet.mergeCells(`A${startIndexTable}:A${startIndexTable + 2}`); // "Sr N"
worksheet.mergeCells(`B${startIndexTable}:B${startIndexTable + 2}`); // "Candidate ID"
worksheet.mergeCells(`C${startIndexTable}:C${startIndexTable + 2}`); // "First and Last Name"
worksheet.mergeCells(`D${startIndexTable}:D${startIndexTable + 2}`); // "Passport/ID"
worksheet.mergeCells(`E${startIndexTable}:E${startIndexTable + 2}`); // "Email ID"
worksheet.mergeCells(`F${startIndexTable}:F${startIndexTable + 2}`); // "Gender"
// worksheet.addRow(users.map((a) => {
// }))
for (
let i = 0;
i < staticHeaders.length + additionalHeaders.length + 1;
i++
) {
worksheet.getColumn(i + 1).width = 30;
}
// Apply styles to the headers
[startIndexTable].forEach((rowNumber) => {
worksheet.getRow(rowNumber).eachCell((cell) => {
if (cell.value) {
cell.fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "FFBFBFBF" }, // Grey color for headers
};
cell.font = { bold: true };
cell.alignment = { vertical: "middle", horizontal: "center" };
}
});
});
worksheet.addRow(["Printed by: Confidential Information"]);
worksheet.addRow(["info@encoach.com"]);
// Convert workbook to Buffer (Node.js) or Blob (Browser)
const buffer = await workbook.xlsx.writeBuffer();
// generate the file ref for storage
const fileName = `${Date.now().toString()}.xlsx`;
const refName = `assignment_report/${fileName}`;
const fileRef = ref(storage, refName);
// upload the pdf to storage
const snapshot = await uploadBytes(fileRef, buffer, {
contentType:
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
});
// update the stats entries with the pdf url to prevent duplication
await updateDoc(docSnap.ref, {
excel: {
path: refName,
version: process.env.EXCEL_VERSION,
},
});
const url = await getDownloadURL(fileRef);
res.status(200).end(url);
return; return;
} }