505 lines
22 KiB
HTML
505 lines
22 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=devi <div id="webdavInfo" style="background-color: #f8f9fa; padding: 15px; border-radius: 4px; margin: 10px 0;">
|
||
<strong>WebDAV-ähnliche URLs:</strong><br>
|
||
📁 Templates: <code>http://localhost:3000/webdav/templates/</code><br>
|
||
📄 Output: <code>http://localhost:3000/webdav/output/</code><br><br>
|
||
|
||
<strong>Microsoft Word Format:</strong><br>
|
||
📝 <code>ms-word:ofe|u|http://localhost:3000/webdav/output/dateiname.docx</code><br><br>
|
||
|
||
<strong>Zugriff:</strong><br>
|
||
🌐 Browser: Direkt über URLs<br>
|
||
📝 Word: ms-word:ofe|u| Links für direktes Öffnen<br>
|
||
💻 Office: URLs direkt in Office-Programmen verwenden
|
||
</div>bdavInfo" style="background-color: #f8f9fa; padding: 15px; border-radius: 4px; margin: 10px 0;">
|
||
<strong>WebDAV-ähnliche URLs:</strong><br>
|
||
📁 Templates: <code>http://localhost:3000/webdav/templates/</code><br>
|
||
📄 Output: <code>http://localhost:3000/webdav/output/</code><br><br>
|
||
|
||
<strong>Zugriff:</strong><br>
|
||
🌐 Browser: Direkt über URLs mit HTTP Basic Auth<br>
|
||
📱 HTTP-Client: Unterstützt PROPFIND für Dateilisten<br>
|
||
💻 Office: URLs direkt in Office-Programmen öffnen
|
||
</div>ial-scale=1.0">
|
||
<title>DOCX Template Server</title>
|
||
<style>
|
||
body {
|
||
font-family: Arial, sans-serif;
|
||
max-width: 800px;
|
||
margin: 0 auto;
|
||
padding: 20px;
|
||
background-color: #f5f5f5;
|
||
}
|
||
.container {
|
||
background: white;
|
||
padding: 30px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
}
|
||
h1 {
|
||
color: #333;
|
||
text-align: center;
|
||
}
|
||
.section {
|
||
margin: 30px 0;
|
||
padding: 20px;
|
||
border: 1px solid #ddd;
|
||
border-radius: 5px;
|
||
}
|
||
button {
|
||
background-color: #007bff;
|
||
color: white;
|
||
padding: 10px 20px;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
margin: 5px;
|
||
}
|
||
button:hover {
|
||
background-color: #0056b3;
|
||
}
|
||
input, select, textarea {
|
||
width: 100%;
|
||
padding: 8px;
|
||
margin: 5px 0;
|
||
border: 1px solid #ddd;
|
||
border-radius: 4px;
|
||
box-sizing: border-box;
|
||
}
|
||
.result {
|
||
margin-top: 20px;
|
||
padding: 15px;
|
||
background-color: #e8f5e8;
|
||
border-radius: 4px;
|
||
border-left: 4px solid #4CAF50;
|
||
}
|
||
.error {
|
||
background-color: #ffe8e8;
|
||
border-left: 4px solid #f44336;
|
||
}
|
||
pre {
|
||
background-color: #f8f9fa;
|
||
padding: 15px;
|
||
border-radius: 4px;
|
||
overflow-x: auto;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<h1>🗎 DOCX Template Server</h1>
|
||
|
||
<div class="section">
|
||
<h3>📋 Server Status</h3>
|
||
<button onclick="checkHealth()">Status prüfen</button>
|
||
<button onclick="listTemplates()">Templates auflisten</button>
|
||
<button onclick="getWebDAVInfo()">WebDAV Info</button>
|
||
<button onclick="listOutputFiles()">Output-Dateien</button>
|
||
<div id="healthResult"></div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h3>📁 Template-Management</h3>
|
||
<p>Verwalten Sie Ihre DOCX-Templates über WebDAV oder die Web-Oberfläche:</p>
|
||
<a href="/templates.html" target="_blank" style="display: inline-block; padding: 10px 20px; background-color: #007bff; color: white; text-decoration: none; border-radius: 4px; margin-right: 10px;">
|
||
🚀 Neue Template-Verwaltung
|
||
</a>
|
||
<button onclick="listTemplatesDetailed()">Templates mit Details anzeigen</button>
|
||
<button onclick="showTemplateUploadInfo()">Upload-Anleitung</button>
|
||
<div id="templatesResult"></div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h3>📄 Dokument aus Template erstellen</h3>
|
||
<input type="text" id="templateName" placeholder="Template-Name (z.B. template.docx)">
|
||
<textarea id="jsonData" rows="10" placeholder='JSON-Daten eingeben:
|
||
{
|
||
"name": "Max Mustermann",
|
||
"email": "max@beispiel.de",
|
||
"date": "30.09.2025",
|
||
"items": [
|
||
{"product": "Produkt A", "quantity": 2, "price": 29.99},
|
||
{"product": "Produkt B", "quantity": 1, "price": 49.99}
|
||
],
|
||
"total": 79.98
|
||
}'></textarea>
|
||
<button onclick="generateDocument()">Dokument erstellen</button>
|
||
<div id="generateResult"></div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h3>🌐 Dokument mit externen Daten</h3>
|
||
<input type="text" id="externalId" placeholder="ID für externe Daten">
|
||
<input type="text" id="externalTemplate" placeholder="Template-Name">
|
||
<button onclick="generateFromExternal()">Mit externen Daten erstellen</button>
|
||
<button onclick="getExternalData()">Externe Daten anzeigen</button>
|
||
<div id="externalResult"></div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h3>🌐 WebDAV Dateizugriff</h3>
|
||
<p>Bearbeiten Sie DOCX-Dateien direkt über WebDAV:</p>
|
||
<div id="webdavInfo" style="background-color: #f8f9fa; padding: 15px; border-radius: 4px; margin: 10px 0;">
|
||
<strong>WebDAV URLs:</strong><br>
|
||
<20> Templates: <code>http://localhost:8080/templates/</code><br>
|
||
📄 Output: <code>http://localhost:8080/output/</code><br><br>
|
||
|
||
<strong>Anmeldedaten:</strong><br>
|
||
👤 admin / password123<br>
|
||
👤 user / docx2024<br><br>
|
||
|
||
<strong>Verbindung aufbauen:</strong><br>
|
||
🪟 Windows: Als Netzlaufwerk verbinden<br>
|
||
🍎 macOS: Finder → Mit Server verbinden<br>
|
||
🐧 Linux: Dateimanager → Andere Orte → dav://localhost:8080/output
|
||
</div>
|
||
<button onclick="getWebDAVInfo()">WebDAV Details laden</button>
|
||
<div id="webdavResult"></div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h3>📁 Datei-Management</h3>
|
||
<button onclick="listOutputFiles()">Alle Output-Dateien anzeigen</button>
|
||
<div id="filesList"></div>
|
||
</div>
|
||
<p>Verwenden Sie diese Syntax in Ihren DOCX-Templates:</p>
|
||
<pre>
|
||
Einfache Werte:
|
||
{{name}} → wird durch den Namen ersetzt
|
||
{{email}} → wird durch die E-Mail ersetzt
|
||
{{date}} → wird durch das Datum ersetzt
|
||
|
||
Tabellen (in Word-Tabelle):
|
||
{{#items}}
|
||
{{product}} | {{quantity}} | {{price}}
|
||
{{/items}}
|
||
|
||
Bedingungen:
|
||
{{#name}}
|
||
Dieser Text wird nur angezeigt wenn 'name' existiert
|
||
{{/name}}
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
async function checkHealth() {
|
||
try {
|
||
const response = await fetch('/health');
|
||
const data = await response.json();
|
||
document.getElementById('healthResult').innerHTML =
|
||
`<div class="result">✅ ${data.message}<br>🌐 ${data.webdav}<br>Zeit: ${data.timestamp}</div>`;
|
||
} catch (error) {
|
||
document.getElementById('healthResult').innerHTML =
|
||
`<div class="result error">❌ Fehler: ${error.message}</div>`;
|
||
}
|
||
}
|
||
|
||
async function getWebDAVInfo() {
|
||
try {
|
||
const response = await fetch('/webdav-info');
|
||
const data = await response.json();
|
||
|
||
const webdavHtml = `
|
||
<div class="result">
|
||
<h4>🌐 WebDAV Verbindungsdetails</h4>
|
||
<p><strong>Base URL:</strong> ${data.webdav.baseUrl}</p>
|
||
<p><strong>Templates:</strong> <a href="${data.webdav.endpoints.templates}" target="_blank">${data.webdav.endpoints.templates}</a></p>
|
||
<p><strong>Output:</strong> <a href="${data.webdav.endpoints.output}" target="_blank">${data.webdav.endpoints.output}</a></p>
|
||
|
||
<h4><3E> Microsoft Word Format</h4>
|
||
<p><strong>Templates:</strong> <code>${data.webdav.msWordFormat.templates}</code></p>
|
||
<p><strong>Output:</strong> <code>${data.webdav.msWordFormat.output}</code></p>
|
||
|
||
<h4>💻 Verwendung</h4>
|
||
<p><strong>Direktzugriff:</strong> ${data.webdav.instructions.access}</p>
|
||
<p><strong>MS Word:</strong> ${data.webdav.instructions.msWord}</p>
|
||
<p><strong>Beispiel:</strong> <code>${data.webdav.instructions.example}</code></p>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('webdavResult').innerHTML = webdavHtml;
|
||
} catch (error) {
|
||
document.getElementById('webdavResult').innerHTML =
|
||
`<div class="result error">❌ WebDAV-Info Fehler: ${error.message}</div>`;
|
||
}
|
||
}
|
||
|
||
async function listOutputFiles() {
|
||
try {
|
||
const response = await fetch('/files/output');
|
||
const data = await response.json();
|
||
|
||
if (data.files.length === 0) {
|
||
document.getElementById('filesList').innerHTML =
|
||
`<div class="result">📁 Keine Dateien im Output-Ordner</div>`;
|
||
return;
|
||
}
|
||
|
||
const filesHtml = data.files.map(file => `
|
||
<div style="border: 1px solid #ddd; padding: 10px; margin: 5px 0; border-radius: 4px;">
|
||
<strong>📄 ${file.name}</strong><br>
|
||
<small>Größe: ${(file.size / 1024).toFixed(1)} KB |
|
||
Erstellt: ${new Date(file.created).toLocaleString('de-DE')}</small><br>
|
||
<a href="${file.downloadUrl}" target="_blank">📥 Download</a> |
|
||
<a href="${file.webdavUrl}" target="_blank">🌐 WebDAV</a> |
|
||
<a href="${file.msWordUrl}" title="In Microsoft Word öffnen">📝 Word</a> |
|
||
<button onclick="deleteFile('${file.name}')" style="background-color: #dc3545; font-size: 12px; padding: 2px 8px;">🗑️ Löschen</button>
|
||
</div>
|
||
`).join('');
|
||
|
||
document.getElementById('filesList').innerHTML =
|
||
`<div class="result">
|
||
<h4>📁 Output-Dateien (${data.count})</h4>
|
||
<p><strong>WebDAV-Zugriff:</strong> <a href="${data.webdavAccess}" target="_blank">${data.webdavAccess}</a></p>
|
||
${filesHtml}
|
||
</div>`;
|
||
} catch (error) {
|
||
document.getElementById('filesList').innerHTML =
|
||
`<div class="result error">❌ Fehler beim Laden der Dateien: ${error.message}</div>`;
|
||
}
|
||
}
|
||
|
||
async function deleteFile(filename) {
|
||
if (!confirm(`Datei "${filename}" wirklich löschen?`)) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(`/files/output/${filename}`, {
|
||
method: 'DELETE'
|
||
});
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
alert(result.message);
|
||
listOutputFiles(); // Liste aktualisieren
|
||
} else {
|
||
alert('Fehler beim Löschen: ' + result.error);
|
||
}
|
||
} catch (error) {
|
||
alert('Fehler beim Löschen: ' + error.message);
|
||
}
|
||
}
|
||
|
||
async function listTemplates() {
|
||
try {
|
||
const response = await fetch('/templates');
|
||
const data = await response.json();
|
||
const templateList = data.templates ? data.templates.map(t => t.name).join(', ') : 'Keine Templates gefunden';
|
||
document.getElementById('healthResult').innerHTML =
|
||
`<div class="result">📁 Verfügbare Templates: ${templateList}</div>`;
|
||
} catch (error) {
|
||
document.getElementById('healthResult').innerHTML =
|
||
`<div class="result error">❌ Fehler beim Laden der Templates: ${error.message}</div>`;
|
||
}
|
||
}
|
||
|
||
async function listTemplatesDetailed() {
|
||
try {
|
||
const response = await fetch('/templates');
|
||
const data = await response.json();
|
||
|
||
if (data.templates.length === 0) {
|
||
document.getElementById('templatesResult').innerHTML =
|
||
`<div class="result">📁 Keine Templates vorhanden<br>
|
||
<small>WebDAV Upload: ${data.webdavAccess}</small></div>`;
|
||
return;
|
||
}
|
||
|
||
const templatesHtml = data.templates.map(template => `
|
||
<div style="border: 1px solid #ddd; padding: 10px; margin: 5px 0; border-radius: 4px;">
|
||
<strong>📄 ${template.name}</strong><br>
|
||
<small>Größe: ${(template.size / 1024).toFixed(1)} KB |
|
||
Geändert: ${new Date(template.modified).toLocaleString('de-DE')}</small><br>
|
||
<a href="${template.webdavUrl}" target="_blank">🌐 WebDAV</a> |
|
||
<a href="${template.msWordUrl}" title="In Microsoft Word öffnen">📝 In Word bearbeiten</a> |
|
||
<button onclick="deleteTemplate('${template.name}')" style="background-color: #dc3545; font-size: 12px; padding: 2px 8px;">🗑️ Löschen</button>
|
||
</div>
|
||
`).join('');
|
||
|
||
document.getElementById('templatesResult').innerHTML =
|
||
`<div class="result">
|
||
<h4>📁 Templates (${data.count})</h4>
|
||
<p><strong>WebDAV-Zugriff:</strong> <a href="${data.webdavAccess}" target="_blank">${data.webdavAccess}</a></p>
|
||
${templatesHtml}
|
||
</div>`;
|
||
} catch (error) {
|
||
document.getElementById('templatesResult').innerHTML =
|
||
`<div class="result error">❌ Fehler beim Laden der Templates: ${error.message}</div>`;
|
||
}
|
||
}
|
||
|
||
async function showTemplateUploadInfo() {
|
||
try {
|
||
const response = await fetch('/templates');
|
||
const data = await response.json();
|
||
|
||
const uploadInfo = `
|
||
<div class="result">
|
||
<h4>📤 Template Upload-Anleitung</h4>
|
||
|
||
<h5>🌐 Via WebDAV (Empfohlen)</h5>
|
||
<p><strong>URL:</strong> <code>${data.webdavAccess}dateiname.docx</code></p>
|
||
<p><strong>Methode:</strong> PUT</p>
|
||
<p><strong>Content-Type:</strong> application/vnd.openxmlformats-officedocument.wordprocessingml.document</p>
|
||
|
||
<h5>📝 Mit Microsoft Word</h5>
|
||
<ol>
|
||
<li>Word öffnen</li>
|
||
<li>Datei → Speichern unter</li>
|
||
<li>URL eingeben: <code>http://localhost:3000/webdav/templates/</code></li>
|
||
<li>Dateiname eingeben (muss auf .docx enden)</li>
|
||
<li>Speichern</li>
|
||
</ol>
|
||
|
||
<h5>💻 Per HTTP PUT (cURL Beispiel)</h5>
|
||
<pre>curl -X PUT http://localhost:3000/webdav/templates/mein-template.docx \\
|
||
-H "Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document" \\
|
||
--data-binary @lokale-datei.docx</pre>
|
||
|
||
<h5>🔗 WebDAV-Laufwerk verbinden</h5>
|
||
<p>Verbinden Sie sich mit <code>http://localhost:3000/webdav/templates/</code> als Netzlaufwerk,
|
||
dann können Sie Dateien wie in einem normalen Ordner bearbeiten.</p>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('templatesResult').innerHTML = uploadInfo;
|
||
} catch (error) {
|
||
document.getElementById('templatesResult').innerHTML =
|
||
`<div class="result error">❌ Fehler beim Laden der Upload-Info: ${error.message}</div>`;
|
||
}
|
||
}
|
||
|
||
async function deleteTemplate(filename) {
|
||
if (!confirm(`Template "${filename}" wirklich löschen?`)) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(`/templates/${filename}`, {
|
||
method: 'DELETE'
|
||
});
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
alert(result.message);
|
||
listTemplatesDetailed(); // Liste aktualisieren
|
||
} else {
|
||
alert('Fehler beim Löschen: ' + result.error);
|
||
}
|
||
} catch (error) {
|
||
alert('Fehler beim Löschen: ' + error.message);
|
||
}
|
||
}
|
||
|
||
async function generateDocument() {
|
||
const templateName = document.getElementById('templateName').value;
|
||
const jsonData = document.getElementById('jsonData').value;
|
||
|
||
if (!templateName || !jsonData) {
|
||
alert('Bitte Template-Name und JSON-Daten eingeben');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const data = JSON.parse(jsonData);
|
||
const response = await fetch('/generate-document', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
templateName: templateName,
|
||
data: data
|
||
})
|
||
});
|
||
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
document.getElementById('generateResult').innerHTML =
|
||
`<div class="result">✅ ${result.message}<br>
|
||
<a href="${result.downloadUrl}" target="_blank">📥 Dokument herunterladen</a><br>
|
||
<a href="${result.msWordUrl}" title="In Microsoft Word öffnen">📝 In Word öffnen</a><br>
|
||
<small>WebDAV: <code>${result.webdavUrl}</code></small></div>`;
|
||
} else {
|
||
document.getElementById('generateResult').innerHTML =
|
||
`<div class="result error">❌ ${result.error}</div>`;
|
||
}
|
||
} catch (error) {
|
||
document.getElementById('generateResult').innerHTML =
|
||
`<div class="result error">❌ Fehler: ${error.message}</div>`;
|
||
}
|
||
}
|
||
|
||
async function getExternalData() {
|
||
const id = document.getElementById('externalId').value;
|
||
|
||
if (!id) {
|
||
alert('Bitte ID eingeben');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(`/external-data/${id}`);
|
||
const data = await response.json();
|
||
|
||
document.getElementById('externalResult').innerHTML =
|
||
`<div class="result">📊 Externe Daten für ID ${id}:<br>
|
||
<pre>${JSON.stringify(data, null, 2)}</pre></div>`;
|
||
} catch (error) {
|
||
document.getElementById('externalResult').innerHTML =
|
||
`<div class="result error">❌ Fehler: ${error.message}</div>`;
|
||
}
|
||
}
|
||
|
||
async function generateFromExternal() {
|
||
const id = document.getElementById('externalId').value;
|
||
const templateName = document.getElementById('externalTemplate').value;
|
||
|
||
if (!id || !templateName) {
|
||
alert('Bitte ID und Template-Name eingeben');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(`/generate-from-external/${id}`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
templateName: templateName
|
||
})
|
||
});
|
||
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
document.getElementById('externalResult').innerHTML =
|
||
`<div class="result">✅ ${result.message}<br>
|
||
<a href="${result.downloadUrl}" target="_blank">📥 Dokument herunterladen</a><br>
|
||
<a href="${result.msWordUrl}" title="In Microsoft Word öffnen">📝 In Word öffnen</a><br>
|
||
<details><summary>Verwendete Daten anzeigen</summary>
|
||
<pre>${JSON.stringify(result.data, null, 2)}</pre></details></div>`;
|
||
} else {
|
||
document.getElementById('externalResult').innerHTML =
|
||
`<div class="result error">❌ ${result.error}</div>`;
|
||
}
|
||
} catch (error) {
|
||
document.getElementById('externalResult').innerHTML =
|
||
`<div class="result error">❌ Fehler: ${error.message}</div>`;
|
||
}
|
||
}
|
||
|
||
// Beim Laden der Seite Status prüfen
|
||
window.onload = function() {
|
||
checkHealth();
|
||
}
|
||
</script>
|
||
</body>
|
||
</html> |