diff --git a/b2b-marketing-assistant/services/export.ts b/b2b-marketing-assistant/services/export.ts
new file mode 100644
index 00000000..456131ea
--- /dev/null
+++ b/b2b-marketing-assistant/services/export.ts
@@ -0,0 +1,68 @@
+import type { AnalysisData, AnalysisStep } from './types';
+
+const sanitizeCellForMarkdown = (cell: string) => cell.replace(/\|/g, '\\|').replace(/\n/g, '
');
+
+export const tableToMarkdown = (step: AnalysisStep): string => {
+ if (!step.rows || step.rows.length === 0) return '';
+
+ const headers = `| ${step.headers.map(sanitizeCellForMarkdown).join(' | ')} |`;
+ const separator = `| ${step.headers.map(() => '---').join(' | ')} |`;
+ const rows = step.rows
+ .map(row => `| ${row.map(sanitizeCellForMarkdown).join(' | ')} |`)
+ .join('\n');
+
+ return `${headers}\n${separator}\n${rows}`;
+};
+
+export const generateMarkdown = (data: AnalysisData, titles: Record, summaryTitle: string): string => {
+ let markdownContent = '# B2B Marketing Analysis Report\n\n';
+
+ const stepOrder: (keyof AnalysisData)[] = ['offer', 'targetGroups', 'personas', 'painPoints', 'gains', 'messages'];
+
+ for (const key of stepOrder) {
+ const step = data[key];
+ const title = titles[key];
+ if (!step) continue;
+
+ markdownContent += `## ${title}\n\n`;
+
+ if (step.summary && step.summary.length > 0) {
+ markdownContent += `**${summaryTitle}**\n`;
+ markdownContent += step.summary.map(item => `- ${item}`).join('\n');
+ markdownContent += `\n\n`;
+ }
+
+ markdownContent += tableToMarkdown(step);
+ markdownContent += `\n\n---\n\n`;
+ }
+
+ return markdownContent;
+};
+
+export const downloadFile = (content: string, filename: string, mimeType: string) => {
+ const blob = new Blob([content], { type: mimeType });
+ const link = document.createElement('a');
+ link.href = URL.createObjectURL(blob);
+ link.download = filename;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ URL.revokeObjectURL(link.href);
+};
+
+export const convertArrayToTsv = (headers: string[], rows: string[][]): string => {
+ const sanitizeCell = (cell: string) => {
+ let cleanCell = cell.replace(/\r?\n|\r/g, ' ').replace(/\t/g, ' ');
+ if (cleanCell.includes('"')) {
+ cleanCell = `"${cleanCell.replace(/"/g, '""')}"`;
+ }
+ return cleanCell;
+ };
+
+ const headerRow = headers.map(sanitizeCell).join('\t');
+ const dataRows = rows.map(row =>
+ row.map(sanitizeCell).join('\t')
+ ).join('\n');
+
+ return `${headerRow}\n${dataRows}`;
+};
\ No newline at end of file