Merge pull request 'Vaibhav_Task-#90' (#24) from Vaibhav_Task-#90 into Feature_Task_Management
Reviewed-on: #24
This commit is contained in:
commit
7324a7a6bc
147
package-lock.json
generated
147
package-lock.json
generated
@ -21,6 +21,7 @@
|
||||
"localforage": "^1.10.0",
|
||||
"match-sorter": "^6.3.1",
|
||||
"moment": "^2.30.1",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"perfect-scrollbar": "^1.5.5",
|
||||
"react": "^18.2.0",
|
||||
"react-apexcharts": "^1.7.0",
|
||||
@ -30,6 +31,7 @@
|
||||
"react-router-dom": "^6.20.1",
|
||||
"react-toastify": "^11.0.2",
|
||||
"sort-by": "^1.2.0",
|
||||
"xlsx": "^0.18.5",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -859,6 +861,24 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@pdf-lib/standard-fonts": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz",
|
||||
"integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pako": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@pdf-lib/upng": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz",
|
||||
"integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pako": "^1.0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@reduxjs/toolkit": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.5.0.tgz",
|
||||
@ -1740,6 +1760,15 @@
|
||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/adler-32": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
|
||||
"integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
@ -2142,6 +2171,19 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/cfb": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
|
||||
"integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"adler-32": "~1.3.0",
|
||||
"crc-32": "~1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
@ -2176,6 +2218,15 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/codepage": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
|
||||
"integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@ -2223,6 +2274,18 @@
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
|
||||
},
|
||||
"node_modules/crc-32": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"crc32": "bin/crc32.njs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
@ -3028,6 +3091,15 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/frac": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
|
||||
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
@ -4234,6 +4306,12 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/pako": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
||||
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
|
||||
"license": "(MIT AND Zlib)"
|
||||
},
|
||||
"node_modules/parent-module": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
@ -4279,6 +4357,18 @@
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/pdf-lib": {
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz",
|
||||
"integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@pdf-lib/standard-fonts": "^1.0.0",
|
||||
"@pdf-lib/upng": "^1.0.1",
|
||||
"pako": "^1.0.11",
|
||||
"tslib": "^1.11.1"
|
||||
}
|
||||
},
|
||||
"node_modules/perfect-scrollbar": {
|
||||
"version": "1.5.6",
|
||||
"resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.6.tgz",
|
||||
@ -5014,6 +5104,18 @@
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ssf": {
|
||||
"version": "0.11.2",
|
||||
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
|
||||
"integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"frac": "~1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/string.prototype.matchall": {
|
||||
"version": "4.0.11",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz",
|
||||
@ -5217,6 +5319,12 @@
|
||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
@ -5640,6 +5748,24 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/wmf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
|
||||
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/word": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
|
||||
"integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/word-wrap": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
|
||||
@ -5655,6 +5781,27 @@
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/xlsx": {
|
||||
"version": "0.18.5",
|
||||
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
|
||||
"integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"adler-32": "~1.3.0",
|
||||
"cfb": "~1.2.1",
|
||||
"codepage": "~1.15.0",
|
||||
"crc-32": "~1.2.1",
|
||||
"ssf": "~0.11.2",
|
||||
"wmf": "~1.0.1",
|
||||
"word": "~0.3.0"
|
||||
},
|
||||
"bin": {
|
||||
"xlsx": "bin/xlsx.njs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
|
@ -24,6 +24,7 @@
|
||||
"localforage": "^1.10.0",
|
||||
"match-sorter": "^6.3.1",
|
||||
"moment": "^2.30.1",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"perfect-scrollbar": "^1.5.5",
|
||||
"react": "^18.2.0",
|
||||
"react-apexcharts": "^1.7.0",
|
||||
@ -33,6 +34,7 @@
|
||||
"react-router-dom": "^6.20.1",
|
||||
"react-toastify": "^11.0.2",
|
||||
"sort-by": "^1.2.0",
|
||||
"xlsx": "^0.18.5",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect,useRef } from "react";
|
||||
import moment from "moment";
|
||||
import { Link, NavLink, useNavigate } from "react-router-dom";
|
||||
import Avatar from "../../components/common/Avatar";
|
||||
@ -11,6 +11,7 @@ import { hasUserPermission } from "../../utils/authUtils";
|
||||
import { MANAGE_EMPLOYEES } from "../../utils/constants";
|
||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||
import SuspendEmp from "../../components/Employee/SuspendEmp";
|
||||
import {exportToCSV,exportToExcel,printTable,exportToPDF} from "../../utils/tableExportUtils";
|
||||
|
||||
const EmployeeList = () => {
|
||||
const { profile: loginUser } = useProfile();
|
||||
@ -101,7 +102,29 @@ const EmployeeList = () => {
|
||||
openModal();
|
||||
}
|
||||
}, [modelConfig, isCreateModalOpen]);
|
||||
|
||||
const tableRef = useRef(null);
|
||||
const handleExport = (type) => {
|
||||
if (!currentItems || currentItems.length === 0) return;
|
||||
|
||||
switch (type) {
|
||||
case "csv":
|
||||
exportToCSV(currentItems, "employees");
|
||||
break;
|
||||
case "excel":
|
||||
exportToExcel(currentItems, "employees");
|
||||
break;
|
||||
case "pdf":
|
||||
exportToPDF(currentItems, "employees"); // Pass the employeeList directly
|
||||
break;
|
||||
case "print":
|
||||
printTable(tableRef.current);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{isCreateModalOpen && (
|
||||
@ -198,13 +221,23 @@ const EmployeeList = () => {
|
||||
</button>
|
||||
<ul className="dropdown-menu">
|
||||
<li>
|
||||
<a
|
||||
aria-label="dropdown item action"
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
>
|
||||
{/* <i className="bx bx-printer me-1"></i> */}
|
||||
Coming Soon
|
||||
<a className="dropdown-item" href="#" onClick={() => handleExport("print")}>
|
||||
<i className="bx bx-printer me-1"></i> Print
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a className="dropdown-item" href="#" onClick={() => handleExport("csv")}>
|
||||
<i className="bx bx-file me-1"></i> CSV
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a className="dropdown-item" href="#" onClick={() => handleExport("excel")}>
|
||||
<i className="bx bxs-file-export me-1"></i> Excel
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a className="dropdown-item" href="#" onClick={() => handleExport("pdf")}>
|
||||
<i className="bx bxs-file-pdf me-1"></i> PDF
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@ -237,6 +270,7 @@ const EmployeeList = () => {
|
||||
id="DataTables_Table_0"
|
||||
aria-describedby="DataTables_Table_0_info"
|
||||
style={{ width: "100%" }}
|
||||
ref={tableRef}
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
|
186
src/utils/tableExportUtils.jsx
Normal file
186
src/utils/tableExportUtils.jsx
Normal file
@ -0,0 +1,186 @@
|
||||
import * as XLSX from "xlsx";
|
||||
import { PDFDocument, rgb, StandardFonts } from 'pdf-lib';
|
||||
|
||||
/**
|
||||
* Export JSON data to CSV
|
||||
* @param {Array} data - Array of objects to export
|
||||
* @param {string} fileName - File name without extension
|
||||
*/
|
||||
export const exportToCSV = (data, fileName = "data") => {
|
||||
const headers = Object.keys(data[0] || {});
|
||||
const csvContent = [
|
||||
headers.join(","), // header row
|
||||
...data.map(row => headers.map(field => `"${row[field] ?? ""}"`).join(",")),
|
||||
].join("\n");
|
||||
|
||||
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.setAttribute("download", `${fileName}.csv`);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
};
|
||||
|
||||
/**
|
||||
* Export JSON data to Excel
|
||||
* @param {Array} data - Array of objects to export
|
||||
* @param {string} fileName - File name without extension
|
||||
*/
|
||||
export const exportToExcel = (data, fileName = "data") => {
|
||||
const ws = XLSX.utils.json_to_sheet(data);
|
||||
const wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, `${fileName}.xlsx`);
|
||||
};
|
||||
|
||||
/**
|
||||
* Export JSON data to PDF using pdf-lib
|
||||
* @param {Array} data - Array of objects to export
|
||||
* @param {string} fileName - File name for the PDF (optional)
|
||||
*/
|
||||
export const exportToPDF = async (data, fileName = "data") => {
|
||||
if (!data || data.length === 0) return;
|
||||
|
||||
// Create a new PDF document
|
||||
const pdfDoc = await PDFDocument.create();
|
||||
|
||||
// Set up the font
|
||||
const font = await pdfDoc.embedFont(StandardFonts.Helvetica); // Use Helvetica font
|
||||
|
||||
// Calculate column widths dynamically based on data content
|
||||
const headers = Object.keys(data[0]);
|
||||
const rows = data.map(item => headers.map(header => item[header] || ''));
|
||||
|
||||
const getMaxColumnWidth = (columnIndex) => {
|
||||
let maxWidth = font.widthOfTextAtSize(headers[columnIndex], 12);
|
||||
rows.forEach(row => {
|
||||
const cellText = row[columnIndex].toString();
|
||||
maxWidth = Math.max(maxWidth, font.widthOfTextAtSize(cellText, 10));
|
||||
});
|
||||
return maxWidth + 10; // Padding for better spacing
|
||||
};
|
||||
|
||||
const columnWidths = headers.map((_, index) => getMaxColumnWidth(index));
|
||||
const tableX = 30; // X-coordinate for the table start
|
||||
const rowHeight = 20; // Height of each row (can be adjusted)
|
||||
const maxPageHeight = 750; // Max available height for content (before a new page is added)
|
||||
const pageMargin = 30; // Margin from the top of the page
|
||||
|
||||
let tableY = maxPageHeight; // Start Y position for the table
|
||||
const maxPageWidth = 600; // Max available width for content (before a new page is added)
|
||||
|
||||
// Add the headers and rows to the page
|
||||
const addHeadersToPage = (page, scaleFactor) => {
|
||||
let xPosition = tableX;
|
||||
headers.forEach((header, index) => {
|
||||
page.drawText(header, {
|
||||
x: xPosition,
|
||||
y: tableY,
|
||||
font,
|
||||
size: 12 * scaleFactor, // Scale the header font size
|
||||
color: rgb(0, 0, 0),
|
||||
});
|
||||
xPosition += columnWidths[index] * scaleFactor; // Adjust X position based on scaling
|
||||
});
|
||||
tableY -= rowHeight; // Move down after adding headers
|
||||
};
|
||||
|
||||
// Add a new page and reset the table position
|
||||
const addNewPage = (scaleFactor) => {
|
||||
const page = pdfDoc.addPage([600, 800]);
|
||||
tableY = maxPageHeight; // Reset Y position for the new page
|
||||
addHeadersToPage(page, scaleFactor); // Re-add headers to the new page
|
||||
return page;
|
||||
};
|
||||
|
||||
// Create the first page and add headers
|
||||
let page = pdfDoc.addPage([600, 800]);
|
||||
|
||||
// Check if the content fits within the page width, scale if necessary
|
||||
const checkPageWidth = (row) => {
|
||||
let totalWidth = columnWidths.reduce((acc, width) => acc + width, 0);
|
||||
let scaleFactor = 1;
|
||||
if (totalWidth > maxPageWidth) {
|
||||
scaleFactor = maxPageWidth / totalWidth; // Scale down if necessary
|
||||
}
|
||||
|
||||
return scaleFactor;
|
||||
};
|
||||
|
||||
// Function to check for page breaks when adding a new row
|
||||
const checkPageBreak = () => {
|
||||
if (tableY - rowHeight < pageMargin) {
|
||||
page = addNewPage(scaleFactor); // Add a new page if there is no space for the next row
|
||||
}
|
||||
};
|
||||
|
||||
// Add rows to the PDF with pagination and horizontal scaling
|
||||
rows.forEach(row => {
|
||||
checkPageBreak(); // Check for page break before adding each row
|
||||
|
||||
const scaleFactor = checkPageWidth(row); // Get the scaling factor for the row
|
||||
|
||||
// Add headers to the first page and each new page with the same scale factor
|
||||
if (tableY === maxPageHeight) {
|
||||
addHeadersToPage(page, scaleFactor); // Add headers only on the first page
|
||||
}
|
||||
|
||||
let xPosition = tableX;
|
||||
row.forEach((value, index) => {
|
||||
page.drawText(value.toString(), {
|
||||
x: xPosition,
|
||||
y: tableY,
|
||||
font,
|
||||
size: 10 * scaleFactor, // Scale the font size
|
||||
color: rgb(0, 0, 0),
|
||||
});
|
||||
xPosition += columnWidths[index] * scaleFactor; // Adjust X position based on scaling
|
||||
});
|
||||
|
||||
tableY -= rowHeight; // Move down to the next row position
|
||||
});
|
||||
|
||||
// Serialize the document to bytes
|
||||
const pdfBytes = await pdfDoc.save();
|
||||
|
||||
// Trigger a download of the PDF
|
||||
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = `${fileName}.pdf`;
|
||||
link.click();
|
||||
};
|
||||
|
||||
/**
|
||||
* Print the HTML table by accepting the table element or a reference.
|
||||
* @param {HTMLElement} table - The table element (or ref) to print
|
||||
*/
|
||||
export const printTable = (table) => {
|
||||
if (table) {
|
||||
const newWindow = window.open("", "", "width=600,height=600"); // Open a new window
|
||||
|
||||
// Inject styles for the table and body
|
||||
newWindow.document.write("<html><head><title>Print Table</title>");
|
||||
const style = document.createElement('style');
|
||||
style.innerHTML = `
|
||||
body { font-family: Arial, sans-serif; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
||||
th { background-color: #f2f2f2; }
|
||||
`;
|
||||
newWindow.document.head.appendChild(style);
|
||||
|
||||
newWindow.document.write("</head><body>");
|
||||
newWindow.document.write(table.outerHTML); // Write the table HTML to the new window
|
||||
newWindow.document.write("</body></html>");
|
||||
|
||||
newWindow.document.close(); // Close the document stream
|
||||
|
||||
// Wait for the document to load before triggering print
|
||||
newWindow.onload = () => {
|
||||
newWindow.print(); // Trigger the print dialog after the content is loaded
|
||||
};
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user