name: word-studio description: Professional Word document generator. Use when user needs to create reports, papers, contracts, resumes, or any professional document. Supports docx/doc formats, charts, images, tables, TOC, and multi-language. Generates publication-ready documents. Word文件生成、專業報告、論文模板、合同製作。 version: 1.0.3 license: MIT-0 metadata: {"openclaw": {"emoji": "📄", "requires": {"bins": ["python3"]}}} dependencies: "pip install python-docx pillow"
Professional Word document generator that creates publication-ready documents in docx/doc formats.
請提供以下資訊:
文件型別:(報告/論文/簡歷/合同/其他)
文件標題:
主要內容:
格式要求:(docx/doc)
語言:(中文/英文)
特殊要求:(圖表/目錄/頁首頁尾等)
更多技能請訪問小蔥技能站7w4.net。
python3 << 'PYEOF'
from docx import Document
from docx.shared import Inches, Pt, Cm, RGBColor, Emu
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.enum.section import WD_ORIENT
import os
def create_cover_page(doc, config):
"""Create professional cover page with vertical centering"""
section = doc.sections[0]
page_height = section.page_height
page_width = section.page_width
# 建立單列表格用於垂直居中
table = doc.add_table(rows=1, cols=1)
table.alignment = WD_TABLE_ALIGNMENT.CENTER
# 設定表格高度為頁面高度(減去邊距)
table_row = table.rows[0]
table_row.height = page_height - section.top_margin - section.bottom_margin
# 獲取單元格
cell = table.cell(0, 0)
# 新增標題
title_para = cell.paragraphs[0]
title_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
title_run = title_para.add_run(config['title'])
title_run.font.size = Pt(26)
title_run.font.bold = True
title_run.font.name = '黑體'
# 新增空行
cell.add_paragraph()
# 新增副標題
if 'subtitle' in config:
subtitle_para = cell.add_paragraph()
subtitle_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
subtitle_run = subtitle_para.add_run(config['subtitle'])
subtitle_run.font.size = Pt(16)
subtitle_run.font.color.rgb = RGBColor(100, 100, 100)
subtitle_run.font.name = '宋體'
# 新增空行
cell.add_paragraph()
cell.add_paragraph()
# 新增作者資訊
if 'author' in config:
author_para = cell.add_paragraph()
author_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
author_run = author_para.add_run(config['author'])
author_run.font.size = Pt(14)
author_run.font.name = '宋體'
# 新增空行
cell.add_paragraph()
# 新增日期
from datetime import datetime
date_para = cell.add_paragraph()
date_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
date_run = date_para.add_run(datetime.now().strftime("%Y年%m月%d日"))
date_run.font.size = Pt(14)
date_run.font.name = '宋體'
# 隱藏表格邊框
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
tbl = table._tbl
tblPr = tbl.tblPr if tbl.tblPr is not None else OxmlElement('w:tblPr')
borders = OxmlElement('w:tblBorders')
for border_name in ['top', 'left', 'bottom', 'right', 'insideH', 'insideV']:
border = OxmlElement(f'w:{border_name}')
border.set(qn('w:val'), 'none')
border.set(qn('w:sz'), '0')
border.set(qn('w:space'), '0')
border.set(qn('w:color'), 'auto')
borders.append(border)
tblPr.append(borders)
return doc
# 新增目錄佔位符
if config.get('toc', False):
toc_heading = doc.add_heading('目錄', level=1)
toc_para = doc.add_paragraph('(請在Word中右鍵此處,選擇"更新域"生成目錄)')
doc.add_page_break()
# 新增正文內容
for section_data in config.get('sections', []):
# 新增章節標題
doc.add_heading(section_data['title'], level=1)
# 新增段落內容
for para in section_data.get('paragraphs', []):
p = doc.add_paragraph(para)
p.paragraph_format.first_line_indent = Cm(0.74) # 首行縮排2字元
p.paragraph_format.line_spacing = 1.5 # 1.5倍行距
# 新增表格(如有)
if 'table' in section_data:
table_data = section_data['table']
table = doc.add_table(rows=len(table_data), cols=len(table_data[0]))
table.style = 'Table Grid'
table.alignment = WD_TABLE_ALIGNMENT.CENTER
for i, row_data in enumerate(table_data):
for j, cell_text in enumerate(row_data):
table.cell(i, j).text = str(cell_text)
# 新增圖片(如有)
if 'image' in section_data:
img_path = section_data['image']
if os.path.exists(img_path):
doc.add_picture(img_path, width=Inches(5))
last_paragraph = doc.paragraphs[-1]
last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 新增圖表(如有)
if 'chart' in section_data:
chart_info = section_data['chart']
doc.add_paragraph(f"【圖表:{chart_info['title']}】")
# 新增頁首頁尾
if config.get('header', False):
header = section.header
header_para = header.paragraphs[0]
header_para.text = config.get('header_text', '')
header_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
if config.get('footer', False):
footer = section.footer
footer_para = footer.paragraphs[0]
footer_para.text = config.get('footer_text', '')
footer_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
return doc
def save_document(doc, output_path, format='docx'):
"""Save document in specified format"""
if format == 'doc':
# docx轉doc需要LibreOffice
docx_path = output_path.replace('.doc', '.docx')
doc.save(docx_path)
# 嘗試使用LibreOffice轉換
import subprocess
try:
subprocess.run([
'soffice', '--headless', '--convert-to', 'doc',
'--outdir', os.path.dirname(output_path),
docx_path
], check=True, timeout=30)
os.remove(docx_path) # 刪除臨時docx
return output_path
except:
# 如果LibreOffice不可用,返回docx
final_path = output_path.replace('.doc', '.docx')
os.rename(docx_path, final_path)
return final_path
else:
doc.save(output_path)
return output_path
# 示例配置
config = {
'title': '示例文件標題',
'subtitle': '副標題',
'author': '作者姓名',
'toc': True,
'header': True,
'header_text': '公司名稱',
'footer': True,
'footer_text': '第 {PAGE} 頁',
'sections': [
{
'title': '第一章 引言',
'paragraphs': [
'這是第一段內容,需要首行縮排兩個字元。',
'這是第二段內容,繼續闡述相關內容。'
]
},
{
'title': '第二章 資料分析',
'paragraphs': ['本章展示相關資料。'],
'table': [
['專案', 'Q1', 'Q2', 'Q3', 'Q4'],
['銷售額', '100', '150', '200', '250'],
['增長率', '10%', '50%', '33%', '25%']
]
}
]
}
# 生成文件
output_dir = os.environ.get('OPENCLAW_WORKSPACE', os.getcwd())
output_path = os.path.join(output_dir, 'document.docx')
doc = create_document(config)
final_path = save_document(doc, output_path, 'docx')
print(f"✅ 文件已生成:{final_path}")
PYEOF
WORK_REPORT = {
'title': '2026年度工作總結報告',
'toc': True,
'header': True,
'header_text': 'XX公司',
'sections': [
{'title': '一、工作概述', 'paragraphs': [...]},
{'title': '二、主要工作內容', 'paragraphs': [...]},
{'title': '三、工作成果', 'paragraphs': [...]},
{'title': '四、存在問題', 'paragraphs': [...]},
{'title': '五、下一步計劃', 'paragraphs': [...]},
]
}
ACADEMIC_PAPER = {
'title': '論文標題',
'author': '作者姓名',
'toc': True,
'sections': [
{'title': '摘要', 'paragraphs': [...]},
{'title': '關鍵詞', 'paragraphs': [...]},
{'title': '1 引言', 'paragraphs': [...]},
{'title': '2 文獻綜述', 'paragraphs': [...]},
{'title': '3 研究方法', 'paragraphs': [...]},
{'title': '4 結果與分析', 'paragraphs': [...]},
{'title': '5 結論', 'paragraphs': [...]},
{'title': '參考文獻', 'paragraphs': [...]},
]
}
CONTRACT = {
'title': '商務合同',
'sections': [
{'title': '第一條 合同雙方', 'paragraphs': [...]},
{'title': '第二條 合同標的', 'paragraphs': [...]},
{'title': '第三條 價格與支付', 'paragraphs': [...]},
{'title': '第四條 交付與驗收', 'paragraphs': [...]},
{'title': '第五條 違約責任', 'paragraphs': [...]},
{'title': '第六條 爭議解決', 'paragraphs': [...]},
]
}
RESUME = {
'title': '個人簡歷',
'sections': [
{'title': '基本資訊', 'paragraphs': [...]},
{'title': '教育背景', 'paragraphs': [...]},
{'title': '工作經歷', 'paragraphs': [...]},
{'title': '專案經驗', 'paragraphs': [...]},
{'title': '技能證書', 'paragraphs': [...]},
{'title': '自我評價', 'paragraphs': [...]},
]
}
優先使用開源免費字型,確保跨平臺一致性:
| 字型名稱 | 型別 | 語言 | 許可證 |
|---|---|---|---|
| Noto Sans | 無襯線 | 全語言 | OFL (免費) |
| Noto Serif | 襯線 | 全語言 | OFL (免費) |
| Noto Sans SC | 無襯線 | 簡體中文 | OFL (免費) |
| Noto Serif SC | 襯線 | 簡體中文 | OFL (免費) |
| Source Han Sans | 無襯線 | 中日韓 | OFL (免費) |
| Source Han Serif | 襯線 | 中日韓 | OFL (免費) |
| Liberation Sans | 無襯線 | 拉丁 | OFL (免費) |
| Liberation Serif | 襯線 | 拉丁 | OFL (免費) |
def get_platform_fonts(platform, language):
"""Get fonts based on platform and language"""
# 開源字型(首選,跨平臺一致)
OPEN_SOURCE_FONTS = {
'body': {
'zh': 'Noto Serif SC',
'en': 'Liberation Serif',
'ja': 'Noto Serif JP',
'ko': 'Noto Serif KR',
'default': 'Noto Serif'
},
'heading': {
'zh': 'Noto Sans SC',
'en': 'Liberation Sans',
'ja': 'Noto Sans JP',
'ko': 'Noto Sans KR',
'default': 'Noto Sans'
}
}
# 系統字型(回退方案)
SYSTEM_FONTS = {
'windows': {
'body': {'zh': '宋體', 'en': 'Times New Roman'},
'heading': {'zh': '黑體', 'en': 'Arial'}
},
'macos': {
'body': {'zh': 'STSong', 'en': 'Times New Roman'},
'heading': {'zh': 'STHeiti', 'en': 'Helvetica'}
},
'linux': {
'body': {'zh': 'Noto Serif CJK SC', 'en': 'Liberation Serif'},
'heading': {'zh': 'Noto Sans CJK SC', 'en': 'Liberation Sans'}
}
}
# 優先使用開源字型
body_font = OPEN_SOURCE_FONTS['body'].get(language,
OPEN_SOURCE_FONTS['body']['default'])
heading_font = OPEN_SOURCE_FONTS['heading'].get(language,
OPEN_SOURCE_FONTS['heading']['default'])
return {
'body': body_font,
'heading': heading_font,
'fallback': SYSTEM_FONTS.get(platform, SYSTEM_FONTS['linux'])
}
def check_font_availability(font_name):
"""Check if font is available on system"""
import subprocess
import sys
platform = sys.platform
if platform == 'darwin': # macOS
result = subprocess.run(['fc-list', font_name],
capture_output=True, text=True)
return result.returncode == 0
elif platform == 'win32': # Windows
import winreg
try:
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts")
return True
except:
return False
else: # Linux
result = subprocess.run(['fc-list', f':family={font_name}'],
capture_output=True, text=True)
return font_name in result.stdout
def get_available_font(preferred, fallbacks):
"""Get first available font from list"""
for font in [preferred] + fallbacks:
if check_font_availability(font):
return font
return 'serif' # Ultimate fallback
✅ 使用標準OOXML格式
✅ 避免使用Office特有功能
✅ 圖片嵌入而非連結
✅ 字型嵌入或回退機制
✅ 表格使用標準樣式
| 格式 | 支援 | 說明 |
|---|---|---|
| .docx | ✅ | 主要格式 |
| .doc | ⚠️ | 需要LibreOffice轉換 |
| ⚠️ | 需要額外轉換 | |
| .odt | ⚠️ | 需要額外轉換 |
字型缺失 → 使用系統預設字型
圖片不存在 → 跳過圖片,新增佔位符
格式轉換失敗 → 保留docx格式
內容為空 → 新增佔位文本
| 模式 | 說明 | 適用場景 |
|---|---|---|
| 居中 | 圖片水平居中 | 單獨展示的圖片 |
| 左對齊 | 圖片靠左,文字環繞 | 圖文混排 |
| 右對齊 | 圖片靠右,文字環繞 | 圖文混排 |
| 全寬 | 圖片佔滿頁面寬度 | 大圖展示 |
| 並排 | 多張圖片並排 | 對比展示 |
IMAGE_SIZES = {
'full_width': Inches(6.0), # 全寬(A4減邊距)
'half_width': Inches(3.0), # 半寬
'third_width': Inches(2.0), # 三分之一寬
'quarter_width': Inches(1.5), # 四分之一寬
'thumbnail': Inches(1.0), # 縮圖
}
from docx.shared import Inches, Cm, Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
def add_image_centered(doc, image_path, width=None, caption=None):
"""Add centered image with optional caption"""
# 新增圖片
if width:
pic = doc.add_picture(image_path, width=width)
else:
pic = doc.add_picture(image_path)
# 居中對齊
last_paragraph = doc.paragraphs[-1]
last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 新增圖注
if caption:
caption_para = doc.add_paragraph()
caption_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
caption_run = caption_para.add_run(caption)
caption_run.font.size = Pt(10)
caption_run.font.color.rgb = RGBColor(128, 128, 128)
return pic
def add_image_with_text_wrap(doc, image_path, position='left', width=Inches(2.5)):
"""Add image with text wrapping"""
# 使用表格實現文字環繞效果
table = doc.add_table(rows=1, cols=2)
table.alignment = WD_TABLE_ALIGNMENT.CENTER
if position == 'left':
img_cell = table.cell(0, 0)
text_cell = table.cell(0, 1)
else:
img_cell = table.cell(0, 1)
text_cell = table.cell(0, 0)
# 新增圖片到單元格
img_cell.paragraphs[0].add_run().add_picture(image_path, width=width)
img_cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
# 隱藏表格邊框
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
tbl = table._tbl
tblPr = tbl.tblPr if tbl.tblPr is not None else OxmlElement('w:tblPr')
borders = OxmlElement('w:tblBorders')
for border_name in ['top', 'left', 'bottom', 'right', 'insideH', 'insideV']:
border = OxmlElement(f'w:{border_name}')
border.set(qn('w:val'), 'none')
border.set(qn('w:sz'), '0')
border.set(qn('w:space'), '0')
border.set(qn('w:color'), 'auto')
borders.append(border)
tblPr.append(borders)
return table, text_cell
def add_images_side_by_side(doc, image_paths, width=Inches(2.8)):
"""Add multiple images side by side"""
# 建立表格並排顯示圖片
table = doc.add_table(rows=1, cols=len(image_paths))
table.alignment = WD_TABLE_ALIGNMENT.CENTER
for i, img_path in enumerate(image_paths):
cell = table.cell(0, i)
cell.paragraphs[0].add_run().add_picture(img_path, width=width)
cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
# 隱藏表格邊框
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
tbl = table._tbl
tblPr = tbl.tblPr if tbl.tblPr is not None else OxmlElement('w:tblPr')
borders = OxmlElement('w:tblBorders')
for border_name in ['top', 'left', 'bottom', 'right', 'insideH', 'insideV']:
border = OxmlElement(f'w:{border_name}')
border.set(qn('w:val'), 'none')
border.set(qn('w:sz'), '0')
border.set(qn('w:space'), '0')
border.set(qn('w:color'), 'auto')
borders.append(border)
tblPr.append(borders)
return table
def add_image_full_width(doc, image_path):
"""Add image that spans full page width"""
# 獲取頁面寬度
section = doc.sections[0]
page_width = section.page_width
left_margin = section.left_margin
right_margin = section.right_margin
# 計算可用寬度
available_width = page_width - left_margin - right_margin
# 新增圖片
pic = doc.add_picture(image_path, width=available_width)
# 居中對齊
last_paragraph = doc.paragraphs[-1]
last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
return pic
def add_figure_caption(doc, figure_number, caption_text, position='below'):
"""Add formatted figure caption"""
caption = f"圖 {figure_number} {caption_text}"
para = doc.add_paragraph()
para.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = para.add_run(caption)
run.font.size = Pt(10)
run.font.name = '宋體'
return para
User: "幫我寫一份2026年第一季度工作總結"
Agent:
1. 收集使用者工作內容
2. 搜尋相關資料
3. 使用工作模板生成結構
4. 呼叫word-studio生成文件
5. 輸出專業Word檔案
User: "幫我寫一篇關於AI發展趨勢的論文"
Agent:
1. 搜尋最新研究資料
2. 整理論文結構
3. 生成符合學術規範的格式
4. 插入圖表和參考文獻
5. 輸出可提交的論文
這是一款質量較高的Word文件生成技能,功能全面(支援20多種文件型別),排版規範專業(字型、格式、頁首頁尾等細節完備),程式碼模板實用。優點是模板分類清晰、多語言支援好、相容性強。不足之處是對技術新手不太友好,缺少直觀的示例展示,模板內容較為概略。總體而言是一款實用且專業的文件生成工具,適合需要製作各類正式文件的使用者。