This commit is contained in:
Tomas Dvorak
2025-06-11 23:01:25 +02:00
parent f2cf831ad4
commit 2e78f34388
+50 -55
View File
@@ -4382,7 +4382,7 @@ function filterReservations() {
displayReservations(filtered); displayReservations(filtered);
} }
// Function to export reservations to Excel // Function to export reservations to CSV
function exportReservations() { function exportReservations() {
if (!window.allReservations || !window.allReservations.length) { if (!window.allReservations || !window.allReservations.length) {
showNotification('Žádné rezervace k exportu', 'warning'); showNotification('Žádné rezervace k exportu', 'warning');
@@ -4390,93 +4390,88 @@ function exportReservations() {
} }
// Get filtered reservations // Get filtered reservations
const vehicleFilter = document.getElementById('vehicleFilter').value; const vehicleFilter = document.getElementById('vehicleFilter')?.value || '';
const dateFilter = document.getElementById('dateFilter').value; const dateFilter = document.getElementById('dateFilter')?.value || '';
let dataToExport = [...window.allReservations]; let dataToExport = [...window.allReservations];
// Apply filters if set // Apply filters if set
if (vehicleFilter) { if (vehicleFilter) {
dataToExport = dataToExport.filter(res => res.vehicle === vehicleFilter); dataToExport = dataToExport.filter(res => res.vehicle && res.vehicle.trim() === vehicleFilter);
} }
if (dateFilter) { if (dateFilter) {
dataToExport = dataToExport.filter(res => { dataToExport = dataToExport.filter(res => {
const resDate = new Date(res.start).toISOString().split('T')[0]; if (!res.start) return false;
return resDate === dateFilter; const reservationDate = new Date(res.start);
const filterDate = new Date(dateFilter);
return reservationDate.getFullYear() === filterDate.getFullYear() &&
reservationDate.getMonth() === filterDate.getMonth() &&
reservationDate.getDate() === filterDate.getDate();
}); });
} }
if (!dataToExport.length) {
showNotification('Žádná data k exportu po aplikování filtrů', 'warning');
return;
}
// Sort by start date // Sort by start date
dataToExport.sort((a, b) => new Date(a.start) - new Date(b.start)); dataToExport.sort((a, b) => new Date(a.start) - new Date(b.start));
// Format date as DD.MM.YYYY // Format date and time as DD.MM.YYYY HH:MM
const formatDate = (dateString) => { const formatDateTime = (dateString) => {
const date = new Date(dateString); const date = new Date(dateString);
const day = String(date.getDate()).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0');
const month = String(date.getMonth() + 1).padStart(2, '0'); const month = String(date.getMonth() + 1).padStart(2, '0');
const year = date.getFullYear(); const year = date.getFullYear();
return `${day}.${month}.${year}`;
};
// Format time as HH:MM
const formatTime = (dateString) => {
const date = new Date(dateString);
const hours = String(date.getHours()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0');
return `${hours}:${minutes}`; return `${day}.${month}.${year} ${hours}:${minutes}`;
}; };
// Format date and time for Excel (YYYY-MM-DD HH:MM) // Escape CSV values (handles quotes and special characters)
const excelDateTime = (dateString) => { const escapeCsv = (value) => {
const date = new Date(dateString); if (value === null || value === undefined) return '';
const year = date.getFullYear(); const stringValue = String(value);
const month = String(date.getMonth() + 1).padStart(2, '0'); // Escape double quotes by doubling them
const day = String(date.getDate()).padStart(2, '0'); const escaped = stringValue.replace(/"/g, '""');
const hours = String(date.getHours()).padStart(2, '0'); // Wrap in quotes if contains comma, newline, or quote
const minutes = String(date.getMinutes()).padStart(2, '0'); if (escaped.includes(',') || escaped.includes('\n') || escaped.includes('"')) {
return `${year}-${month}-${day} ${hours}:${minutes}`; return `"${escaped}"`;
}
return escaped;
}; };
// Create CSV content with semicolon as delimiter for better Excel compatibility // Create CSV content
const headers = [ const headers = ['Řidič', 'Vozidlo', 'Od', 'Do', 'Účel'];
'Řidič',
'Vozidlo',
'Začátek rezervace',
'Konec rezervace',
'Doba trvání',
'Účel cesty'
];
const csvContent = [ const csvRows = [
headers.join(';'), headers.join(';'), // Header row
...dataToExport.map(res => { ...dataToExport.map(res => {
const start = new Date(res.start); const row = [
const end = new Date(res.end); escapeCsv(res.driverName || ''),
escapeCsv(res.vehicle || ''),
return [ escapeCsv(formatDateTime(res.start)),
`"${res.driverName || 'Neznámý řidič'}"`, escapeCsv(formatDateTime(res.end)),
`"${res.vehicle || 'Neznámé vozidlo'}"`, escapeCsv(res.purpose || '')
`"${excelDateTime(start)}"`, ];
`"${excelDateTime(end)}"`, return row.join(';');
`"${calculateDuration(res)}"`,
`"${res.purpose || 'Nespecifikováno'}"`
].join(';');
}) })
].join('\r\n'); ];
// Create and trigger download with proper encoding for Excel // Create CSV string with BOM for Excel
const blob = new Blob([ const csvString = '\uFEFF' + csvRows.join('\r\n');
'\ufeff', // UTF-8 BOM for Excel
csvContent
], {
type: 'text/csv;charset=utf-8;'
});
// Create and trigger download
const blob = new Blob([csvString], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a'); const link = document.createElement('a');
const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const timestamp = new Date().toISOString().split('T')[0];
link.href = URL.createObjectURL(blob); link.href = URL.createObjectURL(blob);
link.download = `rezervace_${timestamp}.csv`; link.download = `rezervace_${timestamp}.csv`;
link.style.display = 'none'; link.style.display = 'none';
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();