Hey everyone, I've been working on creating a dynamic timetable for a group without the need for pen and paper using JavaScript, HTML, and CSS. One challenge I'm facing is figuring out how to add a button that allows users to download the table in PDF format in landscape orientation. If anyone has any ideas or solutions, please feel free to share!
If you're interested, here's the link to the code on GitHub: https://github.com/zahiraaa/timetable
const timetable = document.getElementById("timetable");
const days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
const hours = ["7H", "13H", "20H"];
// Creating table headers for the days
const daysHeaderRow = document.createElement("tr");
daysHeaderCell.innerHTML = "Days";
daysHeaderRow.appendChild(daysHeaderCell);
days.forEach(day => {
const dayHeaderCell = document.createElement("th");
dayHeaderCell.innerHTML = day;
dayHeaderCell.colSpan = 3;
daysHeaderRow.appendChild(dayHeaderCell);
});
timetable.appendChild(daysHeaderRow);
// Create table headers for hours
const hoursHeaderRow = document.createElement("tr");
hoursHeaderCell.innerHTML = "Hours";
hoursHeaderRow.appendChild(hoursHeaderCell);
for (let i = 0; i < days.length; i++) {
for (let j = 0; j < 3; j++) {
const hourHeaderCell = document.createElement("th");
hourHeaderCell.innerHTML = hours[j];
hoursHeaderRow.appendChild(hourHeaderCell);
}
}
timetable.appendChild(hoursHeaderRow);
// Creating rows for individuals
const names = ["Khalfi","Redouani", "Daki", "Hamma", "Saadane", "Boughanem", "El Ansari","Badilou","Raoui", "Chouiba", "Dahmane", "Achdad", "Bouryal", "Ettouri", "Saadouni"];
for (let name of names) {
const row = document.createElement("tr");
const nameCell = document.createElement("td");
nameCell.innerHTML = name;
row.appendChild(nameCell);
for (let i = 0; i < days.length; i++) {
for (let j = 0; j < 3; j++) {
const cell = document.createElement("td");
const select = document.createElement("select");
select.classList.add("cell");
const options = [" ", "CP", "ME", "CL", "CE", "R"];
options.forEach(option => {
const optionElement = document.createElement("option");
optionElement.value = option;
optionElement.innerHTML = option;
select.appendChild(optionElement);
});
cell.appendChild(select);
row.appendChild(cell);
}
}
timetable.appendChild(row);
}
function exportCSV() {
var rows = document.querySelectorAll("#timetable tr");
var csvData = [];
for (var i = 0; i < rows.length; i++) {
var rowData = [];
var cells = rows[i].querySelectorAll("td, th");
for (var j = 0; j < cells.length; j++) {
const select = cells[j].querySelector("select");
if(select){
rowData.push(select.value);
}else{
rowData.push(cells[j].innerText);
}
}
csvData.push(rowData);
}
var csv = Papa.unparse(csvData);
var csvData = new Blob([csv], {type: 'text/csv;charset=utf-8;'});
var csvURL = null;
if (navigator.msSaveBlob) {
csvURL = navigator.msSaveBlob(csvData, 'timetable.csv');
} else {
csvURL = window.URL.createObjectURL(csvData);
}
var tempLink = document.createElement('a');
tempLink.href = csvURL;
tempLink.setAttribute('download', 'timetable.csv');
tempLink.click();
// Convert the CSV data to a PDF and download it
var pdf = new jsPDF('l','mm','a4');
pdf.addPage();
pdf.text(csv, 10, 10);
pdf.save('timetable.pdf');
}
#timetable th {
border: 1px solid #ddd;
padding: 8px;
text-align: center;
background-color: #006699; /* bleu foncé /
}
#timetable tr:nth-child(even) {
background-color: #E6E6FA; / lavande */
}
/* General layout */
body {
background-color: #f1f1f1;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
/* Navigation bar style */
nav {
background-color: #333;
color: #fff;
display: flex;
justify-content: space-between;
padding: 10px 20px;
}
nav a {
color: #fff;
text-decoration: none;
margin-right: 10px;
}
/* Main section style */
main {
padding: 20px;
}
/* Title style */
h1, h2, h3 {
color: #333;
text-align: center;
margin-bottom: 20px;
}
/* Paragraph style */
p {
line-height: 1.5;
margin-bottom: 20px;
}
/* Image style */
img {
max-width: 100%;
}
<table id="timetable">
<body>
<tr>
<td>
<link href="table.css" rel="stylesheet">
<script src="table.js"></script>
<form action="table.php" method="post">
</td>
<tr>
<button onclick="exportCSV()">Export CSV</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.min.js"></script>
<button onclick="exportPDF()">Export PDF</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.77/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.77/pdfmake.min.vfs.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.77/vfs_fonts.js"></script>
<button id="download-pdf-button">Télécharger en PDF</button>
<script>
var downloadButton = document.getElementById("download-pdf-button");
downloadButton.addEventListener("click", downloadPDFWithPDFMake);
</script>
</body>