In this guide, you’ll learn how to build a practical Dify plugin that exports conversations into popular document formats. By the end, your plugin will:
Convert markdown text to Word documents (.docx)
Export conversations as PDF files
Handle file creation with proper formatting
Provide a clean user experience for document exports
Time required
15 minutes
Prerequisites
Basic Python knowledge and familiarity with document manipulation libraries
Create a word_export.yaml file to define the Word document export tool:
Copy
identity: author: your_username name: word_export label: en_US: Export to Word zh_Hans: 导出为Word文档description: human: en_US: Export conversation content to a Word document (.docx) zh_Hans: 将对话内容导出为Word文档(.docx) llm: > A tool that converts markdown text to a Word document (.docx) format. Use this tool when the user wants to save or export the conversation content as a Word document. The input text should be in markdown format.credential_schema: {} # No credentials neededtool_schema: markdown_content: type: string required: true label: en_US: Markdown Content zh_Hans: Markdown内容 human_description: en_US: The markdown content to convert to Word format zh_Hans: 要转换为Word格式的Markdown内容 document_name: type: string required: false label: en_US: Document Name zh_Hans: 文档名称 human_description: en_US: Name for the exported document (without extension) zh_Hans: 导出文档的名称(无需扩展名)
identity: author: your_username name: pdf_export label: en_US: Export to PDF zh_Hans: 导出为PDF文档description: human: en_US: Export conversation content to a PDF document zh_Hans: 将对话内容导出为PDF文档 llm: > A tool that converts markdown text to a PDF document. Use this tool when the user wants to save or export the conversation content as a PDF file. The input text should be in markdown format.credential_schema: {} # No credentials neededtool_schema: markdown_content: type: string required: true label: en_US: Markdown Content zh_Hans: Markdown内容 human_description: en_US: The markdown content to convert to PDF format zh_Hans: 要转换为PDF格式的Markdown内容 document_name: type: string required: false label: en_US: Document Name zh_Hans: 文档名称 human_description: en_US: Name for the exported document (without extension) zh_Hans: 导出文档的名称(无需扩展名)
import osimport tempfileimport uuidfrom docx import Documentfrom docx.shared import Ptfrom docx.enum.text import WD_PARAGRAPH_ALIGNMENTimport markdownfrom bs4 import BeautifulSoupdef convert_markdown_to_docx(markdown_text, document_name=None): """ Convert markdown text to a Word document and return the file path """ if not document_name: document_name = f"exported_document_{uuid.uuid4().hex[:8]}" # Convert markdown to HTML html = markdown.markdown(markdown_text) soup = BeautifulSoup(html, 'html.parser') # Create a new Word document doc = Document() # Process HTML elements and add to document for element in soup.find_all(['h1', 'h2', 'h3', 'h4', 'p', 'ul', 'ol']): if element.name == 'h1': heading = doc.add_heading(element.text.strip(), level=1) heading.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER elif element.name == 'h2': doc.add_heading(element.text.strip(), level=2) elif element.name == 'h3': doc.add_heading(element.text.strip(), level=3) elif element.name == 'h4': doc.add_heading(element.text.strip(), level=4) elif element.name == 'p': paragraph = doc.add_paragraph(element.text.strip()) elif element.name in ('ul', 'ol'): for li in element.find_all('li'): doc.add_paragraph(li.text.strip(), style='ListBullet') # Create temp directory if it doesn't exist temp_dir = tempfile.gettempdir() if not os.path.exists(temp_dir): os.makedirs(temp_dir) # Save the document file_path = os.path.join(temp_dir, f"{document_name}.docx") doc.save(file_path) return file_path
Here are some interesting ways to extend this plugin:
Custom templates: Add company branding or personalized styles
Multi-format support: Expand to export as HTML, Markdown, or other formats
Image handling: Process and include images from conversations
Table support: Implement proper formatting for data tables
Collaborative editing: Add integration with Google Docs or similar platforms
Technical insights
The core challenge in document conversion is maintaining formatting and structure. The approach used in this plugin first converts markdown to HTML (an intermediate format), then processes that HTML into the target format.This two-step process provides flexibility—you could extend it to support additional formats by simply adding new output modules that work with the HTML representation.For PDF generation, WeasyPrint was chosen because it offers high-quality PDF rendering with CSS support. For Word documents, python-docx provides granular control over document structure.
You’ve built a practical plugin that adds real value to the Dify platform by enabling users to export conversations in professional document formats. This functionality bridges the gap between AI conversations and traditional document workflows.
Documentation
Write your README.md in English (en_US) describing functionality, setup, and usage examples
Localization
Create additional README files like readme/README_zh_Hans.md for other languages