导出功能

pull/123/head
Maziang 5 months ago
parent 860e21e95e
commit 5aa73c54e2

@ -1086,8 +1086,107 @@ class MarkTextMainWindow(QMainWindow):
self.switch_to_learning_mode(file_path)
def export_file(self):
"""导出文件"""
QMessageBox.information(self, "提示", "导出功能开发中...")
"""导出文件 - 支持多种格式"""
try:
editor = self.get_current_editor()
if not editor:
QMessageBox.warning(self, "提示", "请先打开一个文档")
return
content = editor.get_content()
if not content.strip():
QMessageBox.warning(self, "提示", "文档内容为空,无法导出")
return
# 创建导出格式选择对话框
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QDialogButtonBox
dialog = QDialog(self)
dialog.setWindowTitle("选择导出格式")
dialog.setModal(True)
dialog.resize(400, 300)
# 设置对话框样式
dialog.setStyleSheet("""
QDialog {
background-color: #161b22;
color: #c9d1d9;
}
QLabel {
color: #c9d1d9;
font-size: 14px;
padding: 10px;
}
QPushButton {
background-color: #238636;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
font-size: 13px;
margin: 5px;
min-width: 120px;
}
QPushButton:hover {
background-color: #2ea043;
}
QPushButton:pressed {
background-color: #1a5d29;
}
""")
layout = QVBoxLayout()
# 标题
title_label = QLabel("选择要导出的文件格式:")
title_label.setStyleSheet("font-size: 16px; font-weight: bold; padding: 15px;")
layout.addWidget(title_label)
# 格式按钮布局
format_layout = QVBoxLayout()
# HTML格式
html_btn = QPushButton("🌐 导出为 HTML")
html_btn.clicked.connect(lambda: self.export_as_format(editor, "html", dialog))
format_layout.addWidget(html_btn)
# PDF格式
pdf_btn = QPushButton("📄 导出为 PDF")
pdf_btn.clicked.connect(lambda: self.export_as_format(editor, "pdf", dialog))
format_layout.addWidget(pdf_btn)
# TXT格式
txt_btn = QPushButton("📝 导出为 TXT")
txt_btn.clicked.connect(lambda: self.export_as_format(editor, "txt", dialog))
format_layout.addWidget(txt_btn)
# Markdown格式
md_btn = QPushButton("📚 导出为 Markdown")
md_btn.clicked.connect(lambda: self.export_as_format(editor, "md", dialog))
format_layout.addWidget(md_btn)
layout.addLayout(format_layout)
# 取消按钮
cancel_btn = QPushButton("❌ 取消")
cancel_btn.setStyleSheet("""
QPushButton {
background-color: #21262d;
color: #c9d1d9;
}
QPushButton:hover {
background-color: #30363d;
}
""")
cancel_btn.clicked.connect(dialog.reject)
layout.addWidget(cancel_btn)
layout.addStretch()
dialog.setLayout(layout)
dialog.exec_()
except Exception as e:
QMessageBox.critical(self, "错误", f"导出功能出错: {str(e)}")
def switch_mode(self, mode: str):
"""切换模式"""
@ -1286,6 +1385,315 @@ class MarkTextMainWindow(QMainWindow):
QMessageBox.warning(self, "提示", "无法刷新天气信息")
except Exception as e:
QMessageBox.critical(self, "错误", f"刷新天气信息失败: {str(e)}")
def export_as_format(self, editor, format_type: str, dialog):
"""导出为指定格式"""
try:
content = editor.get_content()
# 根据格式设置文件扩展名和过滤器
if format_type == "html":
ext = "html"
filter_str = "HTML文件 (*.html);;所有文件 (*.*)"
default_name = "document.html"
elif format_type == "pdf":
ext = "pdf"
filter_str = "PDF文件 (*.pdf);;所有文件 (*.*)"
default_name = "document.pdf"
elif format_type == "txt":
ext = "txt"
filter_str = "文本文档 (*.txt);;所有文件 (*.*)"
default_name = "document.txt"
elif format_type == "md":
ext = "md"
filter_str = "Markdown文件 (*.md);;所有文件 (*.*)"
default_name = "document.md"
else:
QMessageBox.warning(self, "提示", "不支持的导出格式")
return
# 获取保存路径
file_path, _ = QFileDialog.getSaveFileName(
self, f"导出为{format_type.upper()}", default_name, filter_str
)
if not file_path:
return
dialog.accept() # 关闭选择对话框
# 根据格式导出
if format_type == "html":
self.export_as_html(content, file_path)
elif format_type == "pdf":
self.export_as_pdf(content, file_path)
elif format_type == "txt":
self.export_as_txt(content, file_path)
elif format_type == "md":
self.export_as_markdown(content, file_path)
except Exception as e:
QMessageBox.critical(self, "错误", f"导出失败: {str(e)}")
def export_as_html(self, content: str, file_path: str):
"""导出为HTML格式"""
try:
from datetime import datetime
# 创建HTML内容
html_content = f"""<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MagicWord文档</title>
<style>
* {{
margin: 0;
padding: 0;
box-sizing: border-box;
}}
body {{
font-family: 'Segoe UI', 'Microsoft YaHei', '微软雅黑', sans-serif;
font-size: 14px;
line-height: 1.6;
background-color: #fafafa;
color: #333;
padding: 20px;
}}
.container {{
max-width: 800px;
margin: 0 auto;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
padding: 40px;
}}
h1 {{
color: #2c3e50;
border-bottom: 3px solid #3498db;
padding-bottom: 15px;
margin-bottom: 30px;
font-size: 24px;
font-weight: 300;
}}
p {{
margin: 15px 0;
white-space: pre-wrap;
text-align: justify;
}}
.document-info {{
margin-top: 40px;
padding: 20px;
background-color: #f8f9fa;
border-left: 4px solid #3498db;
border-radius: 0 5px 5px 0;
}}
.document-info h3 {{
color: #495057;
margin-bottom: 10px;
font-size: 16px;
}}
.document-info p {{
margin: 5px 0;
font-size: 12px;
color: #6c757d;
}}
br {{
margin: 10px 0;
}}
@media (max-width: 600px) {{
body {{
padding: 10px;
}}
.container {{
padding: 20px;
}}
h1 {{
font-size: 20px;
}}
}}
</style>
</head>
<body>
<div class="container">
"""
# 获取文件名作为标题
base_name = os.path.splitext(os.path.basename(file_path))[0]
html_content += f'<h1>{base_name}</h1>\n\n'
# 处理内容
lines = content.split('\n')
for line in lines:
if line.strip():
# 转义HTML特殊字符
escaped_line = line.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
html_content += f'<p>{escaped_line}</p>\n'
else:
html_content += '<br>\n'
# 添加文档信息
html_content += f'<div class="document-info">\n'
html_content += f'<h3>文档信息</h3>\n'
html_content += f'<p><strong>创建时间:</strong> {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}</p>\n'
html_content += f'<p><strong>字符数:</strong> {len(content)}</p>\n'
html_content += f'<p><strong>行数:</strong> {len(lines)}</p>\n'
html_content += f'</div>\n'
html_content += """
</div>
</body>
</html>"""
# 写入文件
with open(file_path, 'w', encoding='utf-8') as f:
f.write(html_content)
self.statusBar().showMessage(f"已导出为HTML: {os.path.basename(file_path)}", 3000)
except Exception as e:
QMessageBox.critical(self, "错误", f"导出HTML失败: {str(e)}")
def export_as_pdf(self, content: str, file_path: str):
"""导出为PDF格式"""
try:
from PyQt5.QtGui import QTextDocument
from PyQt5.QtPrintSupport import QPrinter
# 创建HTML内容以便更好地处理格式
html_content = f"""
<html>
<head>
<meta charset='utf-8'>
<style>
body {{
font-family: 'Segoe UI', 'Microsoft YaHei', 微软雅黑, sans-serif;
font-size: 12pt;
line-height: 1.6;
margin: 40px;
color: #333;
}}
p {{ margin: 10px 0; white-space: pre-wrap; }}
h1 {{ color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }}
.document-info {{ margin-top: 30px; padding: 15px; background-color: #f8f9fa; border-left: 3px solid #3498db; }}
</style>
</head>
<body>
"""
# 获取文件名作为标题
base_name = os.path.splitext(os.path.basename(file_path))[0]
html_content += f'<h1>{base_name}</h1>'
# 处理内容
lines = content.split('\n')
for line in lines:
if line.strip():
# 转义HTML特殊字符
escaped_line = line.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
html_content += f'<p>{escaped_line}</p>'
else:
html_content += '<br>'
# 添加文档信息
from datetime import datetime
html_content += f'<div class="document-info">'
html_content += f'<p><strong>创建时间:</strong> {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}</p>'
html_content += f'<p><strong>字符数:</strong> {len(content)}</p>'
html_content += f'<p><strong>行数:</strong> {len(lines)}</p>'
html_content += f'</div>'
html_content += "</body></html>"
# 创建文本文档
doc = QTextDocument()
doc.setHtml(html_content)
# 创建PDF打印机
printer = QPrinter(QPrinter.HighResolution)
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName(file_path)
printer.setPageSize(QPrinter.A4)
printer.setPageMargins(20, 20, 20, 20, QPrinter.Millimeter)
# 打印文档到PDF
doc.print_(printer)
self.statusBar().showMessage(f"已导出为PDF: {os.path.basename(file_path)}", 3000)
except Exception as e:
QMessageBox.critical(self, "错误", f"导出PDF失败: {str(e)}")
def export_as_txt(self, content: str, file_path: str):
"""导出为TXT格式"""
try:
from datetime import datetime
# 添加文档信息
txt_content = f"文档标题: {os.path.splitext(os.path.basename(file_path))[0]}\n"
txt_content += f"创建时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
txt_content += f"字符数: {len(content)}\n"
txt_content += f"行数: {len(content.split(chr(10)))}\n"
txt_content += "=" * 50 + "\n\n"
# 添加原始内容
txt_content += content
# 写入文件
with open(file_path, 'w', encoding='utf-8') as f:
f.write(txt_content)
self.statusBar().showMessage(f"已导出为TXT: {os.path.basename(file_path)}", 3000)
except Exception as e:
QMessageBox.critical(self, "错误", f"导出TXT失败: {str(e)}")
def export_as_markdown(self, content: str, file_path: str):
"""导出为Markdown格式"""
try:
from datetime import datetime
# 创建Markdown内容
base_name = os.path.splitext(os.path.basename(file_path))[0]
md_content = f"# {base_name}\n\n"
# 添加文档信息
md_content += f"**创建时间:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} \n"
md_content += f"**字符数:** {len(content)} \n"
md_content += f"**行数:** {len(content.split(chr(10)))} \n\n"
md_content += "---\n\n"
# 处理内容将普通文本转换为Markdown格式
lines = content.split('\n')
for line in lines:
if line.strip():
# 简单的Markdown处理
md_content += f"{line}\n\n"
else:
md_content += "\n"
# 写入文件
with open(file_path, 'w', encoding='utf-8') as f:
f.write(md_content)
self.statusBar().showMessage(f"已导出为Markdown: {os.path.basename(file_path)}", 3000)
except Exception as e:
QMessageBox.critical(self, "错误", f"导出Markdown失败: {str(e)}")
def refresh_quote_info(self):
"""刷新每日名言 - 获取新的名言"""

Loading…
Cancel
Save