OfficeServer/server-old.js
2025-10-01 19:55:38 +02:00

363 lines
11 KiB
JavaScript

const express = require('express');
const fs = require('fs');
const path = require('path');
const { createReport } = require('docx-templates');
const cors = require('cors');
const auth = require('basic-auth');
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware
app.use(cors());
app.use(express.json());
app.use(express.static('public'));
// Template-Ordner erstellen falls nicht vorhanden
const templatesDir = path.join(__dirname, 'templates');
const outputDir = path.join(__dirname, 'output');
if (!fs.existsSync(templatesDir)) {
fs.mkdirSync(templatesDir, { recursive: true });
}
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// WebDAV-ähnliche Routen für Dateizugriff (ohne Authentifizierung)
app.use('/webdav/output', express.static(outputDir));
app.use('/webdav/templates', express.static(templatesDir));
// Output-Dateien über WebDAV-ähnliche URL bereitstellen
app.use('/webdav/output', express.static(outputDir, {
setHeaders: (res, path) => {
res.set('DAV', '1, 2');
res.set('MS-Author-Via', 'DAV');
}
}));
// Templates über WebDAV-ähnliche URL bereitstellen
app.use('/webdav/templates', express.static(templatesDir, {
setHeaders: (res, path) => {
res.set('DAV', '1, 2');
res.set('MS-Author-Via', 'DAV');
}
}));
// WebDAV PROPFIND Support (vereinfacht)
app.propfind('/webdav/*', (req, res) => {
const requestPath = req.path.replace('/webdav/', '');
const isOutput = requestPath.startsWith('output');
const dirPath = isOutput ? outputDir : templatesDir;
try {
const files = fs.readdirSync(dirPath);
const xml = `<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:">
${files.map(file => {
const filePath = path.join(dirPath, file);
const stats = fs.statSync(filePath);
return `
<D:response>
<D:href>/webdav/${requestPath}/${file}</D:href>
<D:propstat>
<D:prop>
<D:displayname>${file}</D:displayname>
<D:getcontentlength>${stats.size}</D:getcontentlength>
<D:getlastmodified>${stats.mtime.toUTCString()}</D:getlastmodified>
<D:resourcetype>${stats.isDirectory() ? '<D:collection/>' : ''}</D:resourcetype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>`;
}).join('')}
</D:multistatus>`;
res.set('Content-Type', 'application/xml; charset=utf-8');
res.send(xml);
} catch (error) {
res.status(404).send('Not found');
}
});
// Route: Template hochladen
app.post('/upload-template', (req, res) => {
// Hier würde normalerweise multer für File-Upload verwendet
res.json({ message: 'Template-Upload-Endpoint bereit' });
});
// Route: DOCX mit Daten befüllen
app.post('/generate-document', async (req, res) => {
try {
const { templateName, data } = req.body;
if (!templateName || !data) {
return res.status(400).json({
error: 'Template-Name und Daten sind erforderlich'
});
}
const templatePath = path.join(templatesDir, templateName);
if (!fs.existsSync(templatePath)) {
return res.status(404).json({
error: 'Template nicht gefunden'
});
}
// Template laden
const template = fs.readFileSync(templatePath);
// Dokument mit Daten befüllen
const buffer = await createReport({
template,
data: data,
cmdDelimiter: ['{{', '}}'], // Template-Syntax
});
// Eindeutigen Dateinamen erstellen
const timestamp = Date.now();
const outputFileName = `document_${timestamp}.docx`;
const outputPath = path.join(outputDir, outputFileName);
// Befülltes Dokument speichern
fs.writeFileSync(outputPath, buffer);
// Download-Link zurückgeben
res.json({
success: true,
downloadUrl: `/download/${outputFileName}`,
message: 'Dokument erfolgreich erstellt'
});
} catch (error) {
console.error('Fehler beim Erstellen des Dokuments:', error);
res.status(500).json({
error: 'Fehler beim Erstellen des Dokuments',
details: error.message
});
}
});
// Route: Dokument herunterladen
app.get('/download/:filename', (req, res) => {
const filename = req.params.filename;
const filePath = path.join(outputDir, filename);
if (!fs.existsSync(filePath)) {
return res.status(404).json({ error: 'Datei nicht gefunden' });
}
res.download(filePath, filename, (err) => {
if (err) {
console.error('Download-Fehler:', err);
res.status(500).json({ error: 'Download-Fehler' });
}
});
});
// Route: Verfügbare Templates auflisten
app.get('/templates', (req, res) => {
try {
const templates = fs.readdirSync(templatesDir)
.filter(file => file.endsWith('.docx'))
.map(file => ({
name: file,
path: `/templates/${file}`
}));
res.json(templates);
} catch (error) {
res.status(500).json({
error: 'Fehler beim Auflisten der Templates'
});
}
});
// Beispiel-Route: Daten von externem Service abrufen
app.get('/external-data/:id', async (req, res) => {
try {
const id = req.params.id;
// Hier würden Sie normalerweise Daten von einem externen API abrufen
// Beispiel mit fetch oder axios
// Beispiel-Daten für Demonstration
const exampleData = {
id: id,
name: 'Max Mustermann',
email: 'max@beispiel.de',
date: new Date().toLocaleDateString('de-DE'),
items: [
{ product: 'Produkt A', quantity: 2, price: 29.99 },
{ product: 'Produkt B', quantity: 1, price: 49.99 },
{ product: 'Produkt C', quantity: 3, price: 19.99 }
],
total: 129.95
};
res.json(exampleData);
} catch (error) {
res.status(500).json({
error: 'Fehler beim Abrufen der externen Daten'
});
}
});
// Kombinierte Route: Externe Daten abrufen und Dokument erstellen
app.post('/generate-from-external/:id', async (req, res) => {
try {
const id = req.params.id;
const { templateName } = req.body;
// Externe Daten abrufen (simulation)
const externalData = {
id: id,
name: 'Max Mustermann',
email: 'max@beispiel.de',
date: new Date().toLocaleDateString('de-DE'),
items: [
{ product: 'Produkt A', quantity: 2, price: 29.99 },
{ product: 'Produkt B', quantity: 1, price: 49.99 },
{ product: 'Produkt C', quantity: 3, price: 19.99 }
],
total: 129.95
};
// Template-Pfad
const templatePath = path.join(templatesDir, templateName);
if (!fs.existsSync(templatePath)) {
return res.status(404).json({
error: 'Template nicht gefunden'
});
}
// Template laden und befüllen
const template = fs.readFileSync(templatePath);
const buffer = await createReport({
template,
data: externalData,
cmdDelimiter: ['{{', '}}'],
});
// Datei speichern
const timestamp = Date.now();
const outputFileName = `document_${id}_${timestamp}.docx`;
const outputPath = path.join(outputDir, outputFileName);
fs.writeFileSync(outputPath, buffer);
res.json({
success: true,
downloadUrl: `/download/${outputFileName}`,
data: externalData,
message: 'Dokument mit externen Daten erstellt'
});
} catch (error) {
console.error('Fehler:', error);
res.status(500).json({
error: 'Fehler beim Erstellen des Dokuments mit externen Daten'
});
}
});
// Health Check
app.get('/health', (req, res) => {
res.json({
status: 'OK',
message: 'DOCX Template Server läuft',
webdav: 'WebDAV-ähnliche Endpoints auf Port 3000',
timestamp: new Date().toISOString()
});
});
// WebDAV Info Endpoint
app.get('/webdav-info', (req, res) => {
res.json({
webdav: {
url: 'http://localhost:3000',
endpoints: {
templates: 'http://localhost:3000/webdav/templates/',
output: 'http://localhost:3000/webdav/output/'
},
credentials: {
admin: 'password123',
user: 'docx2024'
},
instructions: {
windows: 'Als Netzlaufwerk: http://localhost:3000/webdav/output/',
macos: 'Finder > Mit Server verbinden: http://localhost:3000/webdav/output/',
linux: 'dav://localhost:3000/webdav/output/ oder direkt über Browser'
},
note: 'Vereinfachte WebDAV-Implementation - verwenden Sie Browser oder HTTP-Clients'
}
});
});
// Datei-Management Endpoints
app.get('/files/output', (req, res) => {
try {
const files = fs.readdirSync(outputDir)
.filter(file => file.endsWith('.docx'))
.map(file => {
const filePath = path.join(outputDir, file);
const stats = fs.statSync(filePath);
return {
name: file,
size: stats.size,
created: stats.birthtime,
modified: stats.mtime,
webdavUrl: `http://localhost:3000/webdav/output/${file}`,
downloadUrl: `/download/${file}`
};
})
.sort((a, b) => b.modified - a.modified);
res.json({
files,
count: files.length,
webdavAccess: 'http://localhost:3000/webdav/output/'
});
} catch (error) {
res.status(500).json({
error: 'Fehler beim Auflisten der Dateien'
});
}
});
app.delete('/files/output/:filename', (req, res) => {
try {
const filename = req.params.filename;
const filePath = path.join(outputDir, filename);
if (!fs.existsSync(filePath)) {
return res.status(404).json({ error: 'Datei nicht gefunden' });
}
fs.unlinkSync(filePath);
res.json({
success: true,
message: `Datei ${filename} gelöscht`
});
} catch (error) {
res.status(500).json({
error: 'Fehler beim Löschen der Datei'
});
}
});
// Server starten
app.listen(PORT, () => {
console.log(`🚀 DOCX Template Server läuft auf Port ${PORT}`);
console.log(`📁 Templates-Ordner: ${templatesDir}`);
console.log(`📄 Output-Ordner: ${outputDir}`);
console.log(`🌐 Health Check: http://localhost:${PORT}/health`);
console.log(`🗂️ WebDAV-ähnliche Endpoints:`);
console.log(` Templates: http://localhost:${PORT}/webdav/templates/`);
console.log(` Output: http://localhost:${PORT}/webdav/output/`);
console.log(`👤 Login: admin/password123 oder user/docx2024`);
});
module.exports = app;