通义千问等大模型生成的回答多数是markdown类型的,需要将他们转为word文件
一 pypandoc 介绍
1. 项目介绍
pypandoc 是一个用于 pandoc 的轻量级 python 包装器。pandoc 是一个通用的文档转换工具,支持多种格式的文档转换,如 markdown、html、latex、docbook 等。pypandoc 通过提供一个简单的 python 接口,使得在 python 脚本中调用 pandoc 变得更加方便。
2. 安装
使用pip安装
pip install pypandoc_binary
自动下载 pandoc并安装
注意:pypandoc 提供了两个包:
pypandoc:需要用户自行安装 pandoc软件才能使用。
pypandoc_binary:包含了预编译的 pandoc 二进制文件,方便用户快速上手。
手动安装
可以手动安装pandoc再安装pypandoc库
pip install pypandoc
也可以先安装pypandoc然后再在pyhon中运行 pypandoc.download_pandoc()函数自动下载并安装 pandoc,将其存放在 pypandoc 可以访问的目录中。
二、使用python 将markdown转word
本脚本实现了三类功能
1、将markdown文件转为word文件
2、将 markdown中段落开头的“-“转为回车,避免渲染成黑点或者空心圆等word中不常见的符号
3、自定义了模板,格式化输出。
import pypandoc
import time
import re
# 定义路径
path1 = r"md.md"
path2 = r".docx"
template_path = r"d:\atools\ytemplates\templates_s.docx"
# 读取原始markdown文件内容
with open(path1, 'r', encoding='utf-8') as file:
content = file.read()
# 使用正则表达式将以'- '开头的部分替换为换行符
processed_content = re.sub(r'- ', '\n', content)
# 记录开始时间
t1 = time.time()
# 将处理后的内容转换为word文档
pypandoc.convert_text(
processed_content,
'docx',
format='md',
outputfile=path2,
extra_args=['--reference-doc', template_path]
)
# 打印耗时
print(time.time() - t1)
print("转换完成!")
三、直接指定word格式
直接读取文件(可以为txt或者md)转为指定格式的word。
这里格式是:
1、将 markdown中段落开头的“-“转为回车,避免渲染成黑点或者空心圆等word中不常见的符号
2、将原来加粗部分继续加粗和左对齐
3、字体为黑色gb2312
注意:代码用正则替换####这些时需要先从4级标题开始替换否则会有逻辑错误,导致奇数个#无法替换。
设置中文字体不能用run.font.name = '仿宋_gb2312’而是用style._element.rpr.rfonts.set(qn(‘w:eastasia’), ‘仿宋_gb2312’) 设置中文字体。
import re
from docx import document
from docx.shared import pt, rgbcolor
from docx.enum.text import wd_align_paragraph
from docx.oxml.ns import qn
def set_font_color(run):
run.font.name = 'times new roman'
run._element.rpr.rfonts.set(qn('w:eastasia'), '仿宋_gb2312')
run.font.size = pt(12)
run.font.color.rgb = rgbcolor(0, 0, 0)
run.italic = false
def process_content(line, paragraph):
"""通用内容处理函数"""
bold_pattern = re.compile(r'\*\*(.*?)\*\*')
matches = list(bold_pattern.finditer(line))
if not matches:
run = paragraph.add_run(line)
set_font_color(run)
else:
start = 0
for match in matches:
if match.start() > start:
run = paragraph.add_run(line[start:match.start()])
set_font_color(run)
run = paragraph.add_run(match.group(1))
run.bold = true
set_font_color(run)
start = match.end()
if start < len(line):
run = paragraph.add_run(line[start:])
set_font_color(run)
def mdtxt2word(txt_path, docx_path):
with open(txt_path, 'r', encoding='utf-8') as file:
content = re.sub(r'- ', '\n', file.read())
doc = document()
style = doc.styles['normal']
style.font.name = 'times new roman'
style._element.rpr.rfonts.set(qn('w:eastasia'), '仿宋_gb2312')
style.font.size = pt(12)
style.font.color.rgb = rgbcolor(0, 0, 0)
# 合并标题正则表达式
heading_pattern = re.compile(
r'^\s*(#{1,4})\s*(.*?)\s*$' # 匹配1-4个#开头的标题
)
for line in content.split('\n'):
# 处理所有标题类型
heading_match = heading_pattern.match(line)
if heading_match:
level = len(heading_match.group(1)) # 根据#数量确定级别
title_text = heading_match.group(2).strip()
if not title_text:
continue # 跳过空标题
# 创建对应级别的标题
heading = doc.add_heading(level=min(level, 4)) # 限制最大4级
heading.alignment = wd_align_paragraph.left
# 处理标题内容中的加粗标记
process_content(title_text, heading)
continue
# 处理普通段落
paragraph = doc.add_paragraph()
paragraph.alignment = wd_align_paragraph.left
process_content(line, paragraph)
doc.save(docx_path)
print("转换完成!")
if __name__ == "__main__":
txt_path = r"c:\users\xueshifeng\desktop\11.txt"
docx_path = r"c:\users\xueshifeng\desktop\11.docx"
mdtxt2word(txt_path, docx_path)
四、将latex公式转为word
将 latex_content字符串$ $ 中间的位置替换为公式,或者直接复制代码到gpt,让gpt修改代码
import pypandoc
# 定义包含特定公式的latex字符串
#$ $ 中间的位置替换为公式,或者直接复制代码到gpt,让gpt生成最终代码
latex_content = r"""
\documentclass{article}
\usepackage{amsmath} % 确保包含用于数学排版的包
\begin{document}
$ l(y_i, f(x_i)) = \max(0, 1 - y_if(x_i)) $
\end{document}
"""
# 将latex内容转换为word文档
output_file = r"xx14.docx"
output = pypandoc.convert_text(
latex_content, # 输入的字符串
'docx', # 输出格式
format='latex', # 输入格式(latex)
outputfile=output_file, # 输出文件路径
extra_args=['--mathml'] # 额外参数,确保公式渲染为mathml格式
)
# 检查转换是否成功
if output != '':
print(f"转换过程中出现错误: {output}")
else:
print(f"word 文档已生成: {output_file}")
四、将latex公式转为word,追加写入word
难点在于如何管理文件句柄,没有找到好方法,采用对已打开的文档,先关闭再打开的方法。
import os
import pypandoc
from docx import document
import tempfile
import time
import pythoncom
from win32com.client import dispatch # 需要安装pywin32库
def is_file_locked(filepath):
try:
with open(filepath, 'a'):
return false
except permissionerror:
return true
except filenotfounderror:
return false
def close_word_document(filepath):
try:
word = dispatch("word.application")
for doc in word.documents:
if doc.fullname.lower() == os.path.abspath(filepath).lower():
doc.save()
doc.close()
print("已保存并关闭word文档")
return true
word.quit()
except exception as e:
print(f"关闭word文档失败:{str(e)}")
return false
def generate_latex_content(formula):
"""生成完整的latex文档内容"""
return fr"""
\documentclass{{article}}
\usepackage{{amsmath}}
\begin{{document}}
开始:
${formula}$
结束。
\end{{document}}
"""
def doc_creat(user_formula, output_file):
# 检查文件是否存在
if not os.path.exists(output_file):
# 创建新文档对象
doc = document()
# 保存文档
doc.save(output_file)
print(f"文件已创建:{output_file}")
document = document(output_file)
else:
print("文件已打开")
retry_count = 3
for _ in range(retry_count):
if is_file_locked(output_file):
print("检测到文件被占用,尝试关闭word文档...")
if close_word_document(output_file):
time.sleep(0.5) # 等待系统释放文件
continue
else:
print("错误:文件被其他程序占用,请手动关闭后重试!")
break
try:
with tempfile.namedtemporaryfile(delete=false, suffix=".tex") as temp_tex_file:
latex_content = generate_latex_content(user_formula)
temp_tex_file.write(latex_content.encode('utf-8'))
temp_tex_file_name = temp_tex_file.name
with tempfile.namedtemporaryfile(delete=false, suffix=".docx") as temp_docx_file:
temp_docx_file_name = temp_docx_file.name
# 转换latex到word
pypandoc.convert_file(
temp_tex_file_name, 'docx',
outputfile=temp_docx_file_name, extra_args=['--mathjax']
)
# 创建或打开目标文档
target_doc = document(output_file) if os.path.exists(output_file) else document()
temp_doc = document(temp_docx_file_name)
# 复制所有元素
for element in temp_doc.element.body:
target_doc.element.body.append(element)
# 保存目标文档
target_doc.save(output_file)
print(f"内容已成功追加至:{output_file}")
# 自动用word打开文档
os.startfile(output_file)
break
except permissionerror:
print("文件权限错误,请检查文件是否被其他程序占用")
break
except exception as e:
print(f"操作失败:{str(e)}")
break
finally:
if 'temp_tex_file_name' in locals() and os.path.exists(temp_tex_file_name):
os.unlink(temp_tex_file_name)
if 'temp_docx_file_name' in locals() and os.path.exists(temp_docx_file_name):
os.unlink(temp_docx_file_name)
else:
print("重试次数已达上限,请检查文件状态")
if __name__ == '__main__':
# 用户输入公式(示例)
user_formula = r"\frac{\sqrt{x^2 + y^2}}{z}"
# 输出文件路径
output_file = r"c:\users\xueshifeng\desktop\18.docx"
doc_creat(user_formula, output_file)
以上就是python使用pypandoc将markdown文件和latex公式转为word的详细内容,更多关于python pypandoc格式转换的资料请关注代码网其它相关文章!
发表评论