marco.pms.web/src/utils/tableExportUtils.jsx

123 lines
3.8 KiB
JavaScript

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", columns = null) => {
if (!data || data.length === 0) return;
const pdfDoc = await PDFDocument.create();
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
// Landscape dimensions
const pageWidth = 1000; // wider for more space
const pageHeight = 600;
let page = pdfDoc.addPage([pageWidth, pageHeight]);
const margin = 30;
let y = pageHeight - margin;
const headers = columns || Object.keys(data[0]);
const rowHeight = 25; // slightly taller rows for readability
const columnSpacing = 150; // increase space between columns
// Draw headers
headers.forEach((header, i) => {
page.drawText(header, { x: margin + i * columnSpacing, y, font, size: 12 });
});
y -= rowHeight;
// Draw rows
data.forEach(row => {
headers.forEach((header, i) => {
const text = row[header] ? row[header].toString() : '';
page.drawText(text, { x: margin + i * columnSpacing, y, font, size: 10 });
});
y -= rowHeight;
if (y < margin) {
page = pdfDoc.addPage([pageWidth, pageHeight]); // landscape for new page
y = pageHeight - margin;
}
});
const pdfBytes = await pdfDoc.save();
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 clone = table.cloneNode(true);
// Remove last column (Actions) from all rows
clone.querySelectorAll("tr").forEach((row) => {
row.removeChild(row.lastElementChild);
});
const newWindow = window.open("", "", "width=600,height=600");
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(clone.outerHTML);
newWindow.document.write("</body></html>");
newWindow.document.close();
newWindow.onload = () => {
newWindow.print();
};
}
};