wx-agent/utils/pdf_generator.py
2026-07-02 10:29:14 +08:00

281 lines
8.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import base64
import subprocess
import tempfile
from datetime import datetime
class PDFGenerator:
"""PDF 生成器类Pandoc 版)"""
def __init__(self, main_font: str = "Noto Serif CJK SC"):
"""
初始化 PDF 生成器
Args:
main_font: Pandoc / XeLaTeX 使用的中文字体名
"""
self.main_font = main_font
def generate_pdf_from_text(
self,
text_content: str,
output_path: str = None,
title: str = "维修报告",
return_base64: bool = True
) -> dict:
"""
将 Markdown 文本内容生成 PDF 文件
Args:
text_content: Markdown 文本内容
output_path: PDF 输出路径(可选)
title: PDF 标题
return_base64: 是否返回 base64 编码内容
"""
try:
# 输出路径
if output_path is None:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_path = f"temp_report_{timestamp}.pdf"
# 生成临时 Markdown 文件
with tempfile.NamedTemporaryFile(
mode="w",
suffix=".md",
delete=False,
encoding="utf-8"
) as md_file:
md_path = md_file.name
# 写入标题 + 内容
if title:
md_file.write(f"# {title}\n\n")
md_file.write(text_content.strip())
# Pandoc 命令:使用自定义 LaTeX 模板解决排版问题
cmd = [
"pandoc",
md_path,
"--pdf-engine=xelatex",
"-V", f"mainfont={self.main_font}",
"-V", "geometry:margin=2cm", # 增加页边距
"-V", "fontsize=10pt", # 字体大小
"-V", "lineskip=1.5", # 行距
"--template=template.tex", # 使用自定义模板
"-o", output_path
]
# 执行转换
subprocess.run(
cmd,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
result = {
"success": True,
"file_path": output_path
}
# 返回 base64
if return_base64:
with open(output_path, "rb") as f:
result["base64_content"] = base64.b64encode(
f.read()
).decode("utf-8")
return result
except subprocess.CalledProcessError as e:
return {
"success": False,
"error": e.stderr.decode("utf-8")
}
except Exception as e:
return {
"success": False,
"error": str(e)
}
finally:
# 清理临时 md 文件
if "md_path" in locals() and os.path.exists(md_path):
os.remove(md_path)
# 创建自定义 LaTeX 模板文件 template.tex
def create_latex_template():
"""创建一个用于中文排版的 LaTeX 模板Pandoc 正确版)"""
template = r"""
\documentclass[10pt]{article}
\usepackage[UTF8]{ctex}
\usepackage{geometry}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{array}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{setspace}
\usepackage{fancyhdr}
\usepackage{titlesec}
\usepackage{tabularx}
\usepackage{makecell}
\usepackage{adjustbox}
\usepackage{hyperref}
% 页面设置
\geometry{margin=2cm}
\setlength{\parskip}{1em}
\setlength{\parindent}{0em}
% 字体
\setCJKmainfont{Noto Serif CJK SC}
% 标题样式
\title{\Large \textbf{$title$}}
\author{}
\date{}
% 章节标题样式
\titleformat{\section}{\large\bfseries\raggedright}{\thesection}{1em}{}
\titleformat{\subsection}{\normalsize\bfseries\raggedright}{\thesubsection}{1em}{}
% ===== Pandoc compatibility =====
\usepackage{hyperref}
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\begin{document}
\maketitle
$body$
\end{document}
"""
with open("template.tex", "w", encoding="utf-8") as f:
f.write(template)
# 生成报告函数不变,但调用前先创建模板
def generate_report_pdf(
report_content: str,
device_name: str = "未知设备",
output_dir: str = None
) -> dict:
"""
生成维修报告 PDF
"""
# 先创建模板文件
create_latex_template()
generator = PDFGenerator()
# 文件名规则不变
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
safe_device_name = device_name.replace(" ", "_").replace("/", "_")
file_name = f"{safe_device_name}_维修报告_{timestamp}.pdf"
if output_dir:
os.makedirs(output_dir, exist_ok=True)
output_path = os.path.join(output_dir, file_name)
else:
output_path = file_name
result = generator.generate_pdf_from_text(
text_content=report_content,
output_path=output_path,
title="设备维修报告",
return_base64=True
)
if result.get("success"):
result["file_name"] = file_name
return result
# 测试代码
if __name__ == "__main__":
test_md = """
三、根本原因判断
根据设备当前状态、维修方案参考和知识库检索结果,最可能的根本原因如下:
**根本原因**:缸盖密封环老化或失效
**次级原因**:启动阀卡滞或内部泄漏
---
四、原因分析说明
1. **缸盖密封环老化或失效**
- 缸盖密封环是气缸密封的关键部件,其老化或损坏会导致气缸压缩气体泄漏,压缩压力下降。
- 启动时,压缩压力不足会导致点火困难,主机启动延迟或失败。
- 此类问题在长期运行或未定期保养的设备中较为常见。
2. **启动阀卡滞或内部泄漏**
- 启动阀的功能是控制启动气进入气缸,若其卡滞或内部泄漏,将导致启动气供应不足或不及时,影响启动成功率。
- 内部泄漏还会造成启动气浪费,进一步降低启动成功率。
- 启动阀若未定期维护,容易因灰尘、杂质或润滑不良而卡滞。
3. **气缸套磨损**
- 气缸套磨损会导致气缸密封性下降,压缩气体泄漏,压缩压力不足。
- 该问题通常发生在长期运行、润滑不良或未及时更换气缸套的设备中。
4. **活塞环磨损或断裂**
- 活塞环磨损或断裂会导致气缸密封性下降,压缩气体泄漏,从而影响压缩压力。
- 该问题通常与长期运行、润滑不良或材料疲劳有关。
5. **调速系统响应异常**
- 调速系统异常可能导致主机启动时转速控制不稳,但其对压缩压力的影响相对较小,通常不是导致压缩压力不足的主要原因。
---
五、预防建议
1. 定期更换缸盖密封环
- 根据设备运行时间和使用情况,制定合理的密封环更换计划,避免因老化导致密封性能下降。
- 建议每运行 5000 小时进行一次检查,必要时更换。
2. 加强启动阀维护
- 定期清理启动阀内部积碳和杂质,保持润滑良好。
- 每 1000 小时进行一次功能测试。
3. 监控气缸套和活塞环状态
- 通过内窥镜或压力测试定期检测气缸套与活塞环磨损情况。
- 发现异常及时更换。
4. 优化润滑系统
- 使用符合标准的润滑油,确保润滑充分。
- 定期更换滤芯,防止杂质进入关键部件。
5. 定期校准调速系统
- 每季度进行一次调速系统校准,确保响应灵敏。
- 记录历史数据,建立趋势分析模型。
"""
result = generate_report_pdf(
test_md,
device_name="压缩机设备"
)
if result["success"]:
print(f"✓ PDF 生成成功:{result['file_name']}")
print(f"✓ 文件路径:{result['file_path']}")
print(f"✓ Base64 长度:{len(result['base64_content'])}")
else:
print(f"✗ PDF 生成失败:{result['error']}")