> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dify.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Markdownエクスポーター

> 会話をさまざまなドキュメント形式にエクスポートするプラグインの作成方法を学ぶ

> このドキュメントは AI によって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/develop-md-exporter) を参照してください。

## 構築するもの

会話を一般的なドキュメント形式にエクスポートする実用的な Dify プラグインを構築します。最終的に、プラグインは以下の機能を持ちます：

* MarkdownテキストをWord文書（.docx）に変換
* 会話をPDFファイルとしてエクスポート
* 適切なフォーマットでファイル作成を処理
* ドキュメントエクスポートのためのクリーンなユーザー体験を提供

<CardGroup cols={2}>
  <Card title="所要時間" icon="clock">
    15分
  </Card>

  <Card title="前提条件" icon="list-check">
    基本的なPython知識とドキュメント操作ライブラリへの習熟
  </Card>
</CardGroup>

## ステップ1：環境のセットアップ

<Steps>
  <Step title="Dify CLIのインストール">
    <Tabs>
      <Tab title="Mac">
        ```bash theme={null}
        brew tap langgenius/dify
        brew install dify
        ```
      </Tab>

      <Tab title="Linux">
        [Dify GitHub リリースページ](https://github.com/langgenius/dify-plugin-daemon/releases) から最新の Dify CLI を取得します。

        ```bash theme={null}
        # Download appropriate version
        chmod +x dify-plugin-linux-amd64
        mv dify-plugin-linux-amd64 dify
        sudo mv dify /usr/local/bin/
        ```
      </Tab>
    </Tabs>

    インストールの確認：

    ```bash theme={null}
    dify version
    ```
  </Step>

  <Step title="プラグインプロジェクトの作成">
    新しいプラグインプロジェクトを初期化します：

    ```bash theme={null}
    dify plugin init
    ```

    プロンプトに従って入力してください：

    * **Name**: `md_exporter`
    * **Type**: `tool`
    * その他の詳細は指示に従って完了してください
  </Step>
</Steps>

## ステップ2：プラグインマニフェストの定義

`manifest.yaml`ファイルを作成してプラグインのメタデータを定義します：

```yaml theme={null}
version: 0.0.4
type: plugin
author: your_username
label:
  en_US: Markdown Exporter
  zh_Hans: Markdown导出工具
created_at: "2025-09-30T00:00:00Z"
icon: icon.png

resource:
  memory: 134217728  # 128MB
  permission:
    storage:
      enabled: true  # We need storage for temp files

plugins:
  tools:
    - word_export.yaml
    - pdf_export.yaml
  
meta:
  version: 0.0.1
  arch:
    - amd64
    - arm64
  runner:
    language: python
    version: 3.12
    entrypoint: main
```

## ステップ3：Wordエクスポートツールの定義

`word_export.yaml`ファイルを作成してWord文書エクスポートツールを定義します：

```yaml theme={null}
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 needed
tool_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: 导出文档的名称（无需扩展名）
```

## ステップ4：PDFエクスポートツールの定義

PDFエクスポート用の`pdf_export.yaml`ファイルを作成します：

```yaml theme={null}
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 needed
tool_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: 导出文档的名称（无需扩展名）
```

## ステップ5：必要な依存関係のインストール

必要なライブラリを含む`requirements.txt`を作成または更新します：

```text theme={null}
python-docx>=0.8.11
markdown>=3.4.1
weasyprint>=59.0
beautifulsoup4>=4.12.2
```

## ステップ6：Wordエクスポート機能の実装

`utils/docx_utils.py`にユーティリティモジュールを作成します：

<CodeGroup>
  ```python utils/docx_utils.py theme={null}
  import os
  import tempfile
  import uuid
  from docx import Document
  from docx.shared import Pt
  from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
  import markdown
  from bs4 import BeautifulSoup

  def 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
  ```
</CodeGroup>

## ステップ7：PDFエクスポート機能の実装

`utils/pdf_utils.py`にユーティリティモジュールを作成します：

<CodeGroup>
  ```python utils/pdf_utils.py theme={null}
  import os
  import tempfile
  import uuid
  import markdown
  from weasyprint import HTML, CSS
  from weasyprint.text.fonts import FontConfiguration

  def convert_markdown_to_pdf(markdown_text, document_name=None):
      """
      Convert markdown text to a PDF document and return the file path
      """
      if not document_name:
          document_name = f"exported_document_{uuid.uuid4().hex[:8]}"
      
      # Convert markdown to HTML
      html_content = markdown.markdown(markdown_text)
      
      # Add basic styling
      styled_html = f"""
      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="UTF-8">
          <title>{document_name}</title>
          <style>
              body {{ font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }}
              h1 {{ text-align: center; color: #333; }}
              h2, h3, h4 {{ color: #444; margin-top: 20px; }}
              p {{ margin-bottom: 15px; }}
              ul, ol {{ margin-left: 20px; }}
          </style>
      </head>
      <body>
          {html_content}
      </body>
      </html>
      """
      
      # Create temp directory if it doesn't exist
      temp_dir = tempfile.gettempdir()
      if not os.path.exists(temp_dir):
          os.makedirs(temp_dir)
      
      # Output file path
      file_path = os.path.join(temp_dir, f"{document_name}.pdf")
      
      # Configure fonts
      font_config = FontConfiguration()
      
      # Render PDF
      HTML(string=styled_html).write_pdf(
          file_path,
          stylesheets=[],
          font_config=font_config
      )
      
      return file_path
  ```
</CodeGroup>

## ステップ8：ツール実装の作成

まず、`tools/word_export.py`にWordエクスポートツールを作成します：

<CodeGroup>
  ```python tools/word_export.py theme={null}
  import os
  import base64
  from collections.abc import Generator
  from typing import Any
  from dify_plugin import Tool
  from dify_plugin.entities.tool import ToolInvokeMessage
  from utils.docx_utils import convert_markdown_to_docx

  class WordExportTool(Tool):
      def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
          # Extract parameters
          markdown_content = tool_parameters.get("markdown_content", "")
          document_name = tool_parameters.get("document_name", "exported_document")
          
          if not markdown_content:
              yield self.create_text_message("Error: No content provided for export.")
              return
          
          try:
              # Convert markdown to Word
              file_path = convert_markdown_to_docx(markdown_content, document_name)
              
              # Read the file as binary
              with open(file_path, 'rb') as file:
                  file_content = file.read()
              
              # Encode as base64
              file_base64 = base64.b64encode(file_content).decode('utf-8')
              
              # Return success message and file
              yield self.create_text_message(
                  f"Document exported successfully as Word (.docx) format."
              )
              
              yield self.create_file_message(
                  file_name=f"{document_name}.docx", 
                  file_content=file_base64,
                  mime_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
              )
              
          except Exception as e:
              yield self.create_text_message(f"Error exporting to Word: {str(e)}")
              return
  ```
</CodeGroup>

次に、`tools/pdf_export.py`にPDFエクスポートツールを作成します：

<CodeGroup>
  ```python tools/pdf_export.py theme={null}
  import os
  import base64
  from collections.abc import Generator
  from typing import Any
  from dify_plugin import Tool
  from dify_plugin.entities.tool import ToolInvokeMessage
  from utils.pdf_utils import convert_markdown_to_pdf

  class PDFExportTool(Tool):
      def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
          # Extract parameters
          markdown_content = tool_parameters.get("markdown_content", "")
          document_name = tool_parameters.get("document_name", "exported_document")
          
          if not markdown_content:
              yield self.create_text_message("Error: No content provided for export.")
              return
          
          try:
              # Convert markdown to PDF
              file_path = convert_markdown_to_pdf(markdown_content, document_name)
              
              # Read the file as binary
              with open(file_path, 'rb') as file:
                  file_content = file.read()
              
              # Encode as base64
              file_base64 = base64.b64encode(file_content).decode('utf-8')
              
              # Return success message and file
              yield self.create_text_message(
                  f"Document exported successfully as PDF format."
              )
              
              yield self.create_file_message(
                  file_name=f"{document_name}.pdf", 
                  file_content=file_base64,
                  mime_type="application/pdf"
              )
              
          except Exception as e:
              yield self.create_text_message(f"Error exporting to PDF: {str(e)}")
              return
  ```
</CodeGroup>

## ステップ9：エントリーポイントの作成

プロジェクトのルートに`main.py`ファイルを作成します：

<CodeGroup>
  ```python main.py theme={null}
  from dify_plugin import PluginRunner
  from tools.word_export import WordExportTool
  from tools.pdf_export import PDFExportTool

  plugin = PluginRunner(
      tools=[
          WordExportTool(),
          PDFExportTool(),
      ],
      providers=[]  # No credential providers needed
  )
  ```
</CodeGroup>

## ステップ10：プラグインのテスト

<Steps>
  <Step title="デバッグ環境のセットアップ">
    まず、テンプレートから `.env` ファイルを作成します：

    ```bash theme={null}
    cp .env.example .env
    ```

    Dify 環境の詳細を設定します：

    ```dotenv theme={null}
    INSTALL_METHOD=remote
    REMOTE_INSTALL_URL=debug-plugin.dify.dev:5003
    REMOTE_INSTALL_KEY=your_debug_key
    ```
  </Step>

  <Step title="依存関係のインストール">
    ```bash theme={null}
    pip install -r requirements.txt
    ```
  </Step>

  <Step title="デバッグモードでプラグインを起動">
    ```bash theme={null}
    python -m main
    ```
  </Step>
</Steps>

## ステップ11：配布用にパッケージ化

プラグインを共有する準備ができたら：

```bash theme={null}
dify plugin package ./
```

これにより、配布用の`plugin.difypkg`ファイルが作成されます。

## クリエイティブな活用例

<CardGroup cols={2}>
  <Card title="レポート生成" icon="file-lines">
    このプラグインを使用して、分析サマリーをクライアント向けのプロフェッショナルなレポートに変換
  </Card>

  <Card title="セッションドキュメント化" icon="book">
    コーチングやコンサルティングセッションのノートをフォーマットされたドキュメントとしてエクスポート
  </Card>
</CardGroup>

## 基本を超えて

このプラグインを拡張するための興味深い方法をいくつか紹介します：

* **カスタムテンプレート**：企業ブランディングやパーソナライズされたスタイルを追加
* **マルチフォーマットサポート**：HTML、Markdown、その他のフォーマットへのエクスポートを拡張
* **画像処理**：会話からの画像を処理して含める
* **テーブルサポート**：データテーブルの適切なフォーマットを実装
* **コラボレーティブ編集**：Google Docsや類似のプラットフォームとの統合を追加

<Accordion title="技術的な洞察">
  ドキュメント変換の核心的な課題は、フォーマットと構造を維持することです。このプラグインはまず Markdown を中間形式の HTML に変換し、その後その HTML をターゲット形式に処理します。

  この 2 段階のプロセスは柔軟性をもたらします。HTML 表現で動作する新しい出力モジュールを追加するだけで、より多くのフォーマットをサポートできます。

  PDF 生成では、CSS をサポートする高品質な PDF レンダリングを提供する WeasyPrint を使用します。Word 文書では、python-docx がドキュメント構造に対する詳細な制御を提供します。
</Accordion>

## まとめ

会話をプロフェッショナルなドキュメント形式でエクスポートできる実用的なプラグインを構築し、AI 会話と従来のドキュメントワークフローの間のギャップを埋めました。

<CardGroup cols={2}>
  <Card title="ドキュメント" icon="book">
    機能、セットアップ、使用例を説明するREADME.mdを英語（en\_US）で作成してください
  </Card>

  <Card title="ローカライゼーション" icon="language">
    他の言語用に`readme/README_zh_Hans.md`などの追加READMEファイルを作成してください
  </Card>
</CardGroup>

<CheckList>
  <CheckListItem id="privacy">
    プラグインを公開する場合はプライバシーポリシー（PRIVACY.md）を追加してください
  </CheckListItem>

  <CheckListItem id="documentation">
    ドキュメントに包括的な例を含めてください
  </CheckListItem>

  <CheckListItem id="testing">
    さまざまなドキュメントサイズとフォーマットで徹底的にテストしてください
  </CheckListItem>
</CheckList>
