Skip to content

Commit 8cde3b1

Browse files
feat: add XML to Excel conversion tool and clean up debug statements in Excel to XML tool
1 parent ecd433a commit 8cde3b1

File tree

4 files changed

+172
-17
lines changed

4 files changed

+172
-17
lines changed

provider/excel-plugin.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ identity:
1313
tools:
1414
- tools/dify-plugin-markdown-to-excel.yaml
1515
- tools/dify-plugin-excel-to-xml.yaml
16+
- tools/dify-plugin-xml-to-excel.yaml
1617
extra:
1718
python:
1819
source: provider/excel-plugin.py

tools/dify-plugin-excel-to-xml.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -123,25 +123,9 @@ def get_url_from_file_data(file_data: Any) -> str:
123123

124124
class DifyPluginExcelToXMLTool(Tool):
125125
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage, None, None]:
126-
# フバッグ用にパラメータの内容を出力(ファイルオブジェクトを除外)
127-
try:
128-
print("Debug - tool_parameters keys:", tool_parameters.keys())
129-
except:
130-
print("Debug - tool_parameters: <not serializable>")
131126

132127
# ファイルオブジェクトを取得
133128
file_data = tool_parameters.get("file_url")
134-
try:
135-
if isinstance(file_data, dict):
136-
print("Debug - file_data keys:", file_data.keys())
137-
elif isinstance(file_data, list):
138-
print("Debug - file_data is list of length:", len(file_data))
139-
if len(file_data) > 0:
140-
print("Debug - first item keys:", file_data[0].keys())
141-
else:
142-
print("Debug - file_data type:", type(file_data))
143-
except:
144-
print("Debug - file_data: <not serializable>")
145129

146130
if not file_data:
147131
yield ToolInvokeMessage(
@@ -153,7 +137,6 @@ def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessag
153137
try:
154138
# ファイルのURLを取得
155139
file_url = get_url_from_file_data(file_data)
156-
print("Debug - file_url:", file_url) # 取得したURLを確認
157140

158141
if not file_url:
159142
yield ToolInvokeMessage(

tools/dify-plugin-xml-to-excel.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
from collections.abc import Generator
2+
from typing import Any
3+
import openpyxl
4+
from openpyxl.utils import get_column_letter
5+
from openpyxl.styles import Border, Side
6+
from io import BytesIO
7+
import xml.etree.ElementTree as ET
8+
import base64
9+
10+
from dify_plugin import Tool
11+
from dify_plugin.entities.tool import ToolInvokeMessage
12+
13+
def apply_cell_styles(cell, style_elements):
14+
"""セルにスタイルを適用"""
15+
for style_elem in style_elements:
16+
if style_elem.tag == 'borders':
17+
for border in style_elem.findall('border'):
18+
side = border.get('side')
19+
style = border.get('style')
20+
if side and style:
21+
border_style = Side(style=style)
22+
# 既存の罫線情報を保持しながら更新
23+
border_args = {
24+
'top': cell.border.top if cell.border else None,
25+
'bottom': cell.border.bottom if cell.border else None,
26+
'left': cell.border.left if cell.border else None,
27+
'right': cell.border.right if cell.border else None
28+
}
29+
border_args[side] = border_style
30+
cell.border = Border(**border_args)
31+
32+
elif style_elem.tag == 'merge':
33+
# mergeタグの中身を直接取得
34+
merge_info = style_elem.attrib
35+
if 'start' in merge_info and 'end' in merge_info:
36+
start = merge_info['start']
37+
end = merge_info['end']
38+
try:
39+
cell.parent.merge_cells(f'{start}:{end}')
40+
except ValueError:
41+
# 既に結合されているセルの場合はスキップ
42+
pass
43+
44+
elif style_elem.tag == 'background':
45+
from openpyxl.styles import PatternFill
46+
if style_elem.text: # テキストが存在する場合のみ適用
47+
cell.fill = PatternFill(start_color=style_elem.text,
48+
end_color=style_elem.text,
49+
fill_type='solid')
50+
51+
elif style_elem.tag == 'color':
52+
from openpyxl.styles import Font
53+
if style_elem.text: # テキストが存在する場合のみ適用
54+
current_font = cell.font or Font()
55+
cell.font = Font(color=style_elem.text,
56+
name=current_font.name,
57+
size=current_font.size,
58+
bold=current_font.bold,
59+
italic=current_font.italic)
60+
61+
def create_excel_from_xml(xml_text: str) -> BytesIO:
62+
"""XML形式のテキストからExcelファイルを生成"""
63+
# 新しいワークブックを作成
64+
wb = openpyxl.Workbook()
65+
ws = wb.active
66+
67+
try:
68+
# XMLをパース
69+
root = ET.fromstring(xml_text)
70+
worksheet = root.find('worksheet')
71+
if worksheet is None:
72+
raise ValueError("worksheetタグが見つかりません")
73+
74+
# 各行を処理
75+
for row_elem in worksheet.findall('row'):
76+
try:
77+
row_idx = int(row_elem.get('index'))
78+
except (ValueError, TypeError):
79+
continue
80+
81+
# 各セルを処理
82+
for cell_elem in row_elem.findall('cell'):
83+
ref = cell_elem.get('ref')
84+
if not ref:
85+
continue
86+
87+
try:
88+
# セルの値を設定
89+
value_elem = cell_elem.find('value')
90+
if value_elem is not None and value_elem.text is not None:
91+
ws[ref] = value_elem.text
92+
93+
# スタイルを適用
94+
apply_cell_styles(ws[ref], cell_elem)
95+
except Exception as e:
96+
print(f"セル {ref} の処理中にエラー: {str(e)}")
97+
continue
98+
99+
# メモリ上にExcelファイルを保存
100+
excel_io = BytesIO()
101+
wb.save(excel_io)
102+
excel_io.seek(0)
103+
return excel_io
104+
105+
except Exception as e:
106+
raise ValueError(f"XMLの処理中にエラー: {str(e)}")
107+
108+
class DifyPluginXMLToExcelTool(Tool):
109+
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage, None, None]:
110+
try:
111+
# XMLテキストを取得
112+
xml_text = tool_parameters.get("xml_text")
113+
if not xml_text:
114+
yield ToolInvokeMessage(
115+
type="text",
116+
message={"text": "XMLテキストが提供されていません。"}
117+
)
118+
return
119+
120+
# XMLからExcelファイルを生成
121+
excel_io = create_excel_from_xml(xml_text)
122+
excel_data = excel_io.getvalue()
123+
124+
# blobメッセージとしてファイルを返す
125+
yield self.create_blob_message(
126+
blob=excel_data,
127+
meta={
128+
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
129+
"filename": "converted.xlsx"
130+
}
131+
)
132+
133+
except Exception as e:
134+
yield ToolInvokeMessage(
135+
type="text",
136+
message={"text": f"エラーが発生しました: {str(e)}"}
137+
)
138+
return
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
identity:
2+
name: xml_to_excel
3+
author: Dify
4+
label:
5+
en_US: XML to Excel
6+
ja_JP: XMLからExcel
7+
zh_Hans: XML转Excel
8+
9+
description:
10+
human:
11+
en_US: Convert XML format text to Excel file
12+
ja_JP: XML形式のテキストをExcelファイルに変換します
13+
zh_Hans: 将XML格式文本转换为Excel文件
14+
llm: A tool for converting XML format text to Excel files
15+
16+
parameters:
17+
- name: xml_text
18+
type: string
19+
required: true
20+
label:
21+
en_US: XML Text
22+
ja_JP: XMLテキスト
23+
zh_Hans: XML文本
24+
human_description:
25+
en_US: The XML text to convert to Excel
26+
ja_JP: Excelに変換するXMLテキスト
27+
zh_Hans: 需要转换为Excel的XML文本
28+
llm_description: The XML text that needs to be converted to Excel format
29+
form: llm
30+
31+
extra:
32+
python:
33+
source: tools/dify-plugin-xml-to-excel.py

0 commit comments

Comments
 (0)