Enhance Excel export functionality in backend and frontend; implement Excel file generation and update download logic for correct file extension
This commit is contained in:
@@ -16,23 +16,23 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"cors": "^2.8.5",
|
||||
"helmet": "^7.1.0",
|
||||
"morgan": "^1.10.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"mysql2": "^3.6.5",
|
||||
"sequelize": "^6.35.2",
|
||||
"bcrypt": "^5.1.1",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"nodemailer": "^6.9.7",
|
||||
"cors": "^2.8.5",
|
||||
"crypto": "^1.0.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"exceljs": "^4.4.0",
|
||||
"express": "^4.18.2",
|
||||
"express-session": "^1.18.0",
|
||||
"helmet": "^7.1.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"morgan": "^1.10.0",
|
||||
"mysql2": "^3.6.5",
|
||||
"nodemailer": "^6.9.7",
|
||||
"passport": "^0.7.0",
|
||||
"passport-google-oauth20": "^2.0.0",
|
||||
"express-session": "^1.18.0"
|
||||
"sequelize": "^6.35.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^3.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class ExportController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Exportiert Daten als Excel
|
||||
* Exportiert Daten als Excel (.xlsx)
|
||||
*/
|
||||
async exportExcel(req, res) {
|
||||
try {
|
||||
@@ -47,11 +47,11 @@ class ExportController {
|
||||
});
|
||||
}
|
||||
|
||||
const excel = await ExportService.exportExcel(userId, startDate, endDate);
|
||||
const buffer = await ExportService.exportExcel(userId, startDate, endDate);
|
||||
|
||||
res.setHeader('Content-Type', 'text/csv; charset=utf-8');
|
||||
res.setHeader('Content-Disposition', `attachment; filename="zeiterfassung_${startDate}_${endDate}.csv"`);
|
||||
res.send(excel);
|
||||
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
res.setHeader('Content-Disposition', `attachment; filename="zeiterfassung_${startDate}_${endDate}.xlsx"`);
|
||||
res.send(buffer);
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Excel-Export:', error);
|
||||
res.status(500).json({
|
||||
|
||||
@@ -29,17 +29,49 @@ class ExportService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Exportiert Daten als Excel (CSV mit Excel-kompatiblem Encoding)
|
||||
* Exportiert Daten als echte Excel-Datei (.xlsx)
|
||||
* @param {number} userId - User-ID
|
||||
* @param {string} startDate - Startdatum
|
||||
* @param {string} endDate - Enddatum
|
||||
* @returns {Promise<string>} Excel-kompatibles CSV mit BOM
|
||||
* @returns {Promise<Buffer>} Excel-Datei als Buffer
|
||||
*/
|
||||
async exportExcel(userId, startDate, endDate) {
|
||||
const csv = await this.exportCSV(userId, startDate, endDate);
|
||||
const ExcelJS = require('exceljs');
|
||||
const data = await this._getExportData(userId, startDate, endDate);
|
||||
|
||||
// UTF-8 BOM für Excel
|
||||
return '\ufeff' + csv;
|
||||
// Erstelle Workbook
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const worksheet = workbook.addWorksheet('Zeiterfassung');
|
||||
|
||||
// Definiere Spalten
|
||||
worksheet.columns = [
|
||||
{ header: 'Datum', key: 'date', width: 12 },
|
||||
{ header: 'Uhrzeit', key: 'time', width: 10 },
|
||||
{ header: 'Aktivität', key: 'activity', width: 20 },
|
||||
{ header: 'Gesamt-Netto-Arbeitszeit', key: 'netWorkTime', width: 25 }
|
||||
];
|
||||
|
||||
// Style für Header
|
||||
worksheet.getRow(1).font = { bold: true };
|
||||
worksheet.getRow(1).fill = {
|
||||
type: 'pattern',
|
||||
pattern: 'solid',
|
||||
fgColor: { argb: 'FFE0E0E0' }
|
||||
};
|
||||
|
||||
// Füge Daten hinzu
|
||||
data.forEach(row => {
|
||||
worksheet.addRow({
|
||||
date: row.date,
|
||||
time: row.time,
|
||||
activity: row.activity,
|
||||
netWorkTime: row.netWorkTime
|
||||
});
|
||||
});
|
||||
|
||||
// Generiere Buffer
|
||||
const buffer = await workbook.xlsx.writeBuffer();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user