Improvements on excel rendering
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user