feat: Add Markdown export service for DOCX and PDF formats
- Implemented MarkdownExportService to convert Markdown text into DOCX and PDF formats. - Supported Markdown elements include headings, bold, italic, blockquotes, tables, and specific emojis. - Added methods for generating DOCX and PDF documents with proper formatting and rendering. - Enhanced application properties to enable logging for production environment. - Introduced a test-run script to reset project state and trigger processing via API. Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -96,6 +96,41 @@ CREATE OR REPLACE PACKAGE DC_BACKEND_PKG AS
|
||||
p_interval_sec IN NUMBER DEFAULT 5
|
||||
);
|
||||
|
||||
-- -------------------------------------------------------------------------
|
||||
-- Konvertiert einen Markdown-CLOB zu DOCX oder PDF.
|
||||
-- POST /export/markdown → BLOB (application/pdf oder .docx)
|
||||
--
|
||||
-- p_markdown Markdown-Text (z.B. dc_projects.report_markdown)
|
||||
-- p_format 'PDF' (Standard) oder 'DOCX'
|
||||
-- Rückgabe BLOB mit dem fertigen Dokument
|
||||
-- -------------------------------------------------------------------------
|
||||
FUNCTION convert_markdown(
|
||||
p_markdown IN CLOB,
|
||||
p_format IN VARCHAR2 DEFAULT 'PDF'
|
||||
) RETURN BLOB;
|
||||
|
||||
-- -------------------------------------------------------------------------
|
||||
-- Convenience: liest report_markdown des Projekts und konvertiert zu PDF/DOCX.
|
||||
--
|
||||
-- Beispiel:
|
||||
-- v_blob := DC_BACKEND_PKG.project_report(1, 'PDF');
|
||||
-- -------------------------------------------------------------------------
|
||||
FUNCTION project_report(
|
||||
p_project_id IN NUMBER,
|
||||
p_format IN VARCHAR2 DEFAULT 'PDF'
|
||||
) RETURN BLOB;
|
||||
|
||||
-- -------------------------------------------------------------------------
|
||||
-- Generiert den Markdown-Prüfbericht für ein Projekt neu und speichert ihn
|
||||
-- in dc_projects.report_markdown. Ruft intern dc_generate_report auf.
|
||||
--
|
||||
-- Beispiel:
|
||||
-- DC_BACKEND_PKG.regenerate_report(1);
|
||||
-- -------------------------------------------------------------------------
|
||||
PROCEDURE regenerate_report(
|
||||
p_project_id IN NUMBER
|
||||
);
|
||||
|
||||
END DC_BACKEND_PKG;
|
||||
/
|
||||
|
||||
@@ -262,6 +297,93 @@ CREATE OR REPLACE PACKAGE BODY DC_BACKEND_PKG AS
|
||||
END wait_for_completion;
|
||||
|
||||
|
||||
-- -------------------------------------------------------------------------
|
||||
FUNCTION convert_markdown(
|
||||
p_markdown IN CLOB,
|
||||
p_format IN VARCHAR2 DEFAULT 'PDF'
|
||||
) RETURN BLOB IS
|
||||
l_url VARCHAR2(500);
|
||||
l_body CLOB;
|
||||
l_result BLOB;
|
||||
l_status NUMBER;
|
||||
BEGIN
|
||||
l_url := c_base_url || '/export/markdown';
|
||||
|
||||
-- JSON-Body mit CLOB-Inhalt: APEX_JSON unterstützt CLOBs beliebiger Größe
|
||||
APEX_JSON.INITIALIZE_CLOB_OUTPUT;
|
||||
APEX_JSON.OPEN_OBJECT;
|
||||
APEX_JSON.WRITE('content', p_markdown);
|
||||
APEX_JSON.WRITE('format', UPPER(p_format));
|
||||
APEX_JSON.CLOSE_OBJECT;
|
||||
l_body := APEX_JSON.GET_CLOB_OUTPUT;
|
||||
APEX_JSON.FREE_OUTPUT;
|
||||
|
||||
set_headers();
|
||||
|
||||
l_result := APEX_WEB_SERVICE.MAKE_REST_REQUEST_B(
|
||||
p_url => l_url,
|
||||
p_http_method => 'POST',
|
||||
p_body => l_body
|
||||
);
|
||||
|
||||
l_status := APEX_WEB_SERVICE.G_STATUS_CODE;
|
||||
|
||||
IF l_status NOT IN (200, 201) THEN
|
||||
RAISE_APPLICATION_ERROR(-20200,
|
||||
'Export-Service Fehler: HTTP ' || l_status ||
|
||||
' (format=' || p_format || ')');
|
||||
END IF;
|
||||
|
||||
RETURN l_result;
|
||||
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
IF SQLCODE = -20200 THEN RAISE; END IF;
|
||||
RAISE_APPLICATION_ERROR(-20201,
|
||||
'Verbindungsfehler beim Export: ' || SQLERRM);
|
||||
END convert_markdown;
|
||||
|
||||
|
||||
-- -------------------------------------------------------------------------
|
||||
FUNCTION project_report(
|
||||
p_project_id IN NUMBER,
|
||||
p_format IN VARCHAR2 DEFAULT 'PDF'
|
||||
) RETURN BLOB IS
|
||||
l_markdown CLOB;
|
||||
BEGIN
|
||||
SELECT report_markdown
|
||||
INTO l_markdown
|
||||
FROM dc_projects
|
||||
WHERE id = p_project_id;
|
||||
|
||||
IF l_markdown IS NULL OR DBMS_LOB.GETLENGTH(l_markdown) = 0 THEN
|
||||
RAISE_APPLICATION_ERROR(-20202,
|
||||
'Projekt ' || p_project_id || ' hat noch keinen Markdown-Bericht. '
|
||||
|| 'Bitte zuerst POST /api/dc/projects/' || p_project_id || '/report aufrufen.');
|
||||
END IF;
|
||||
|
||||
RETURN convert_markdown(l_markdown, p_format);
|
||||
|
||||
EXCEPTION
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
RAISE_APPLICATION_ERROR(-20110,
|
||||
'Projekt ' || p_project_id || ' nicht gefunden.');
|
||||
END project_report;
|
||||
|
||||
|
||||
-- -------------------------------------------------------------------------
|
||||
PROCEDURE regenerate_report(
|
||||
p_project_id IN NUMBER
|
||||
) IS
|
||||
BEGIN
|
||||
dc_generate_report(p_project_id => p_project_id);
|
||||
EXCEPTION
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
RAISE_APPLICATION_ERROR(-20110,
|
||||
'Projekt ' || p_project_id || ' nicht gefunden.');
|
||||
END regenerate_report;
|
||||
|
||||
|
||||
END DC_BACKEND_PKG;
|
||||
/
|
||||
|
||||
@@ -294,4 +416,24 @@ BEGIN
|
||||
DBMS_OUTPUT.PUT_LINE('Response: ' || l_response);
|
||||
END;
|
||||
/
|
||||
|
||||
-- Bericht als PDF exportieren
|
||||
DECLARE
|
||||
l_blob BLOB;
|
||||
BEGIN
|
||||
DC_BACKEND_PKG.g_api_key := 'mein-api-key';
|
||||
l_blob := DC_BACKEND_PKG.project_report(p_project_id => 1, p_format => 'PDF');
|
||||
DBMS_OUTPUT.PUT_LINE('PDF-Größe: ' || DBMS_LOB.GETLENGTH(l_blob) || ' Bytes');
|
||||
END;
|
||||
/
|
||||
|
||||
-- Bericht als DOCX exportieren
|
||||
DECLARE
|
||||
l_blob BLOB;
|
||||
BEGIN
|
||||
DC_BACKEND_PKG.g_api_key := 'mein-api-key';
|
||||
l_blob := DC_BACKEND_PKG.project_report(p_project_id => 1, p_format => 'DOCX');
|
||||
DBMS_OUTPUT.PUT_LINE('DOCX-Größe: ' || DBMS_LOB.GETLENGTH(l_blob) || ' Bytes');
|
||||
END;
|
||||
/
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user