OfficeServer/public/index.html
2025-10-01 21:14:31 +02:00

505 lines
22 KiB
HTML
Raw Permalink Blame History

<!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>