feat(notes): add export to Word functionality

Add a menu item in the Notes page to export the current note to a Word document.
The feature leverages the existing ExportService which converts markdown to docx format.

Changes:
- Add "Export to Word" menu item in MenuConfig.tsx
- Add handleExportToWord handler in HeaderNavbar.tsx
- Add i18n translations for all supported languages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
suyao 2026-01-09 15:55:33 +08:00
parent 29d8c4a7ed
commit 40db1ffcc1
No known key found for this signature in database
13 changed files with 73 additions and 4 deletions

View File

@ -2226,14 +2226,18 @@
"drop_markdown_hint": "Drop .md files or folders here to import",
"empty": "No notes available yet",
"expand": "unfold",
"exportToWord": "Export to Word",
"export_failed": "Failed to export to knowledge base",
"export_knowledge": "Export notes to knowledge base",
"export_success": "Successfully exported to the knowledge base",
"export_to_word_failed": "Failed to export to Word",
"folder": "folder",
"new_folder": "New Folder",
"new_note": "Create a new note",
"no_content_to_copy": "No content to copy",
"no_content_to_export": "No content to export",
"no_file_selected": "Please select the file to upload",
"no_note_selected": "Please select a note first",
"no_valid_files": "No valid file was uploaded",
"open_folder": "Open an external folder",
"open_outside": "Open from external",

View File

@ -2226,14 +2226,18 @@
"drop_markdown_hint": "拖拽 .md 文件或目录到此处导入",
"empty": "暂无笔记",
"expand": "展开",
"exportToWord": "导出为 Word",
"export_failed": "导出到知识库失败",
"export_knowledge": "导出笔记到知识库",
"export_success": "成功导出到知识库",
"export_to_word_failed": "导出为 Word 失败",
"folder": "文件夹",
"new_folder": "新建文件夹",
"new_note": "新建笔记",
"no_content_to_copy": "没有内容可复制",
"no_content_to_export": "没有内容可导出",
"no_file_selected": "请选择要上传的文件",
"no_note_selected": "请先选择一个笔记",
"no_valid_files": "没有上传有效的文件",
"open_folder": "打开外部文件夹",
"open_outside": "从外部打开",

View File

@ -2226,14 +2226,18 @@
"drop_markdown_hint": "拖曳 .md 檔案或資料夾到此處匯入",
"empty": "暫無筆記",
"expand": "展開",
"exportToWord": "匯出為 Word",
"export_failed": "匯出至知識庫失敗",
"export_knowledge": "匯出筆記至知識庫",
"export_success": "成功匯出至知識庫",
"export_to_word_failed": "匯出為 Word 失敗",
"folder": "資料夾",
"new_folder": "新增資料夾",
"new_note": "新增筆記",
"no_content_to_copy": "沒有內容可複製",
"no_content_to_export": "沒有內容可匯出",
"no_file_selected": "請選擇要上傳的檔案",
"no_note_selected": "請先選擇一個筆記",
"no_valid_files": "沒有上傳有效的檔案",
"open_folder": "開啟外部資料夾",
"open_outside": "從外部開啟",

View File

@ -2226,14 +2226,18 @@
"drop_markdown_hint": ".md-Datei oder Verzeichnis hierher ziehen zum Importieren",
"empty": "Keine Notizen vorhanden",
"expand": "Ausklappen",
"exportToWord": "[to be translated]:Export to Word",
"export_failed": "Export in Wissensdatenbank fehlgeschlagen",
"export_knowledge": "Notiz in Wissensdatenbank exportieren",
"export_success": "Erfolgreich in Wissensdatenbank exportiert",
"export_to_word_failed": "[to be translated]:Failed to export to Word",
"folder": "Ordner",
"new_folder": "Neuer Ordner",
"new_note": "Neue Notiz",
"no_content_to_copy": "Kein Inhalt zum Kopieren",
"no_content_to_export": "[to be translated]:No content to export",
"no_file_selected": "Bitte Datei zum Hochladen auswählen",
"no_note_selected": "[to be translated]:Please select a note first",
"no_valid_files": "Keine gültigen Dateien hochgeladen",
"open_folder": "Externen Ordner öffnen",
"open_outside": "Extern öffnen",

View File

@ -2226,14 +2226,18 @@
"drop_markdown_hint": "Σύρετε και αποθέστε αρχεία ή φακέλους .md εδώ για εισαγωγή",
"empty": "δεν υπάρχει σημείωση για τώρα",
"expand": "να ανοίξει",
"exportToWord": "[to be translated]:Export to Word",
"export_failed": "Εξαγωγή στη βάση γνώσης απέτυχε",
"export_knowledge": "εξαγωγή σημειώσεων στη βάση γνώσης",
"export_success": "Επιτυχής εξαγωγή στην βάση γνώσης",
"export_to_word_failed": "[to be translated]:Failed to export to Word",
"folder": "φάκελος",
"new_folder": "Νέος φάκελος",
"new_note": "Δημιουργία νέας σημείωσης",
"no_content_to_copy": "Δεν υπάρχει περιεχόμενο προς αντιγραφή",
"no_content_to_export": "[to be translated]:No content to export",
"no_file_selected": "Επιλέξτε το αρχείο για μεταφόρτωση",
"no_note_selected": "[to be translated]:Please select a note first",
"no_valid_files": "Δεν ανέβηκε έγκυρο αρχείο",
"open_folder": "Άνοιγμα εξωτερικού φακέλου",
"open_outside": "Από το εξωτερικό",

View File

@ -2226,14 +2226,18 @@
"drop_markdown_hint": "Arrastre y suelte archivos o carpetas de .md aquí para importar",
"empty": "Sin notas por el momento",
"expand": "expandir",
"exportToWord": "[to be translated]:Export to Word",
"export_failed": "Exportación a la base de conocimientos fallida",
"export_knowledge": "exportar notas a la base de conocimientos",
"export_success": "Exportado con éxito a la base de conocimientos",
"export_to_word_failed": "[to be translated]:Failed to export to Word",
"folder": "carpeta",
"new_folder": "Nueva carpeta",
"new_note": "Crear nota nueva",
"no_content_to_copy": "No hay contenido para copiar",
"no_content_to_export": "[to be translated]:No content to export",
"no_file_selected": "Por favor, seleccione el archivo a subir",
"no_note_selected": "[to be translated]:Please select a note first",
"no_valid_files": "No se ha cargado un archivo válido",
"open_folder": "abrir carpeta externa",
"open_outside": "Abrir desde el exterior",

View File

@ -2226,14 +2226,18 @@
"drop_markdown_hint": "Déposez ici des fichiers ou dossiers .md pour les importer",
"empty": "Aucune note pour le moment",
"expand": "développer",
"exportToWord": "[to be translated]:Export to Word",
"export_failed": "Échec de l'exportation vers la base de connaissances",
"export_knowledge": "exporter la note vers la base de connaissances",
"export_success": "Exporté avec succès vers la base de connaissances",
"export_to_word_failed": "[to be translated]:Failed to export to Word",
"folder": "dossier",
"new_folder": "Nouveau dossier",
"new_note": "Nouvelle note",
"no_content_to_copy": "Aucun contenu à copier",
"no_content_to_export": "[to be translated]:No content to export",
"no_file_selected": "Veuillez sélectionner le fichier à télécharger",
"no_note_selected": "[to be translated]:Please select a note first",
"no_valid_files": "Aucun fichier valide na été téléversé",
"open_folder": "ouvrir le dossier externe",
"open_outside": "Ouvrir depuis l'extérieur",

View File

@ -2226,14 +2226,18 @@
"drop_markdown_hint": ".md ファイルまたはディレクトリをここにドラッグ&ドロップしてインポートしてください",
"empty": "暫無ノート",
"expand": "展開",
"exportToWord": "[to be translated]:Export to Word",
"export_failed": "知識ベースへのエクスポートに失敗しました",
"export_knowledge": "ノートをナレッジベースにエクスポートする",
"export_success": "知識ベースへのエクスポートが成功しました",
"export_to_word_failed": "[to be translated]:Failed to export to Word",
"folder": "フォルダー",
"new_folder": "新しいフォルダーを作成する",
"new_note": "新規ノート作成",
"no_content_to_copy": "コピーするコンテンツはありません",
"no_content_to_export": "[to be translated]:No content to export",
"no_file_selected": "アップロードするファイルを選択してください",
"no_note_selected": "[to be translated]:Please select a note first",
"no_valid_files": "有効なファイルがアップロードされていません",
"open_folder": "外部フォルダーを開きます",
"open_outside": "外部から開く",

View File

@ -2226,14 +2226,18 @@
"drop_markdown_hint": "Arraste e solte arquivos ou pastas .md aqui para importar",
"empty": "Ainda não existem notas",
"expand": "expandir",
"exportToWord": "[to be translated]:Export to Word",
"export_failed": "Falha ao exportar para a base de conhecimento",
"export_knowledge": "exportar anotações para a base de conhecimento",
"export_success": "exportado com sucesso para a base de conhecimento",
"export_to_word_failed": "[to be translated]:Failed to export to Word",
"folder": "pasta",
"new_folder": "Nova pasta",
"new_note": "Nova nota",
"no_content_to_copy": "Não há conteúdo para copiar",
"no_content_to_export": "[to be translated]:No content to export",
"no_file_selected": "Selecione o arquivo a ser enviado",
"no_note_selected": "[to be translated]:Please select a note first",
"no_valid_files": "Nenhum arquivo válido foi carregado",
"open_folder": "Abrir pasta externa",
"open_outside": "Abrir externamente",

View File

@ -2226,14 +2226,18 @@
"drop_markdown_hint": "Trage fișiere sau dosare .md aici pentru a importa",
"empty": "Încă nu există notițe disponibile",
"expand": "desfășoară",
"exportToWord": "[to be translated]:Export to Word",
"export_failed": "Exportul în baza de cunoștințe a eșuat",
"export_knowledge": "Exportă notițele în baza de cunoștințe",
"export_success": "Exportat cu succes în baza de cunoștințe",
"export_to_word_failed": "[to be translated]:Failed to export to Word",
"folder": "dosar",
"new_folder": "Dosar nou",
"new_note": "Creează o notiță nouă",
"no_content_to_copy": "Niciun conținut de copiat",
"no_content_to_export": "[to be translated]:No content to export",
"no_file_selected": "Te rugăm să selectezi fișierul de încărcat",
"no_note_selected": "[to be translated]:Please select a note first",
"no_valid_files": "Nu a fost încărcat niciun fișier valid",
"open_folder": "Deschide un dosar extern",
"open_outside": "Deschide din exterior",

View File

@ -1311,7 +1311,6 @@
"backup": {
"file_format": "Ошибка формата файла резервной копии"
},
"base64DataTruncated": "[to be translated]:Base64 image data truncated, size",
"base64DataTruncated": "Данные изображения в формате Base64 усечены, размер",
"boundary": {
"default": {
@ -1393,9 +1392,7 @@
"text": "текст",
"toolInput": "ввод инструмента",
"toolName": "имя инструмента",
"truncated": "[to be translated]:Data truncated, original size",
"truncated": "Данные усечены, исходный размер",
"truncatedBadge": "[to be translated]:Truncated",
"truncatedBadge": "Усечённый",
"unknown": "Неизвестная ошибка",
"usage": "Дозировка",
@ -2229,14 +2226,18 @@
"drop_markdown_hint": "Перетащите сюда файлы или папки .md для импорта",
"empty": "заметок пока нет",
"expand": "развернуть",
"exportToWord": "[to be translated]:Export to Word",
"export_failed": "Экспорт в базу знаний не выполнен",
"export_knowledge": "Экспортировать заметки в базу знаний",
"export_success": "Успешно экспортировано в базу знаний",
"export_to_word_failed": "[to be translated]:Failed to export to Word",
"folder": "папка",
"new_folder": "Новая папка",
"new_note": "Создать заметку",
"no_content_to_copy": "Нет контента для копирования",
"no_content_to_export": "[to be translated]:No content to export",
"no_file_selected": "Пожалуйста, выберите файл для загрузки",
"no_note_selected": "[to be translated]:Please select a note first",
"no_valid_files": "Не загружен действительный файл",
"open_folder": "Откройте внешнюю папку",
"open_outside": "открыть снаружи",

View File

@ -53,6 +53,25 @@ const HeaderNavbar = ({ notesTree, getCurrentNoteContent, onToggleStar, onExpand
}
}, [getCurrentNoteContent])
const handleExportToWord = useCallback(async () => {
try {
const content = getCurrentNoteContent?.()
if (!content) {
window.toast.warning(t('notes.no_content_to_export'))
return
}
if (!activeNode) {
window.toast.warning(t('notes.no_note_selected'))
return
}
const fileName = activeNode.name.replace('.md', '')
await window.api.export.toWord(content, fileName)
} catch (error) {
logger.error('Failed to export to Word:', error as Error)
window.toast.error(t('notes.export_to_word_failed'))
}
}, [getCurrentNoteContent, activeNode])
const handleShowSettings = useCallback(() => {
GeneralPopup.show({
title: t('notes.settings.title'),
@ -142,6 +161,8 @@ const HeaderNavbar = ({ notesTree, getCurrentNoteContent, onToggleStar, onExpand
onClick: () => {
if (item.copyAction) {
handleCopyContent()
} else if (item.exportToWordAction) {
handleExportToWord()
} else if (item.showSettingsPopup) {
handleShowSettings()
} else if (item.action) {

View File

@ -1,5 +1,5 @@
import type { NotesSettings } from '@renderer/store/note'
import { Copy, MonitorSpeaker, Settings, Type } from 'lucide-react'
import { Copy, FileText, MonitorSpeaker, Settings, Type } from 'lucide-react'
import type { ReactNode } from 'react'
export interface MenuItem {
@ -12,6 +12,7 @@ export interface MenuItem {
isActive?: (settings: NotesSettings) => boolean
component?: (settings: NotesSettings, updateSettings: (newSettings: Partial<NotesSettings>) => void) => ReactNode
copyAction?: boolean
exportToWordAction?: boolean
showSettingsPopup?: boolean
}
@ -22,6 +23,12 @@ export const menuItems: MenuItem[] = [
icon: Copy,
copyAction: true
},
{
key: 'export-to-word',
labelKey: 'notes.exportToWord',
icon: FileText,
exportToWordAction: true
},
{
key: 'divider0',
type: 'divider',