怎样实现巡检报表生成脚本

wen 实用脚本 26

本文目录导读:

怎样实现巡检报表生成脚本

  1. 基础框架方案
  2. 完整示例使用
  3. 安装依赖

我来提供几种在Python中实现巡检报表生成脚本的完整方案,涵盖Excel、PDF和HTML格式。

基础框架方案

1 Excel报表生成

import pandas as pd
from datetime import datetime
import numpy as np
class InspectionReportGenerator:
    def __init__(self, report_name="巡检报表"):
        self.report_name = report_name
        self.generated_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    def generate_excel_report(self, data, output_path):
        """
        生成Excel巡检报表
        Args:
            data: 包含巡检数据的列表或DataFrame
            output_path: 输出文件路径
        """
        # 创建DataFrame
        df = pd.DataFrame(data)
        # 创建Excel写入器
        with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
            # 写入数据表
            df.to_excel(writer, sheet_name='巡检数据', index=False)
            # 创建汇总表
            summary = self._create_summary(df)
            summary.to_excel(writer, sheet_name='汇总统计', index=True)
            # 设置格式
            workbook = writer.book
            # 获取工作表
            ws_data = writer.sheets['巡检数据']
            ws_summary = writer.sheets['汇总统计']
            # 调整列宽
            for ws in [ws_data, ws_summary]:
                for column in ws.columns:
                    max_length = 0
                    column_letter = column[0].column_letter
                    for cell in column:
                        try:
                            if len(str(cell.value)) > max_length:
                                max_length = len(str(cell.value))
                        except:
                            pass
                    adjusted_width = min(max_length + 2, 50)
                    ws.column_dimensions[column_letter].width = adjusted_width
            # 添加标题
            from openpyxl.styles import Font, Alignment
            ws_data.merge_cells('A1:H1')
            ws_data.cell(row=1, column=1, value=f'{self.report_name}')
            ws_data.cell(row=1, column=1).font = Font(bold=True, size=14)
            ws_data.cell(row=1, column=1).alignment = Alignment(horizontal='center')
        print(f"Excel报表已生成: {output_path}")
        return output_path
    def _create_summary(self, df):
        """创建汇总统计数据"""
        summary = pd.DataFrame()
        # 统计基本信息
        summary['总记录数'] = [len(df)]
        summary['正常数量'] = [len(df[df['状态'] == '正常'])] if '状态' in df.columns else [0]
        summary['异常数量'] = [len(df[df['状态'] == '异常'])] if '状态' in df.columns else [0]
        # 添加时间信息
        summary['生成时间'] = [self.generated_time]
        return summary

2 PDF报表生成

from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
class PDFReportGenerator:
    def __init__(self, title="巡检报表"):
        self.title = title
        self.styles = getSampleStyleSheet()
    def generate_pdf_report(self, data, output_path):
        """
        生成PDF巡检报表
        """
        # 创建文档
        doc = SimpleDocTemplate(
            output_path,
            pagesize=A4,
            rightMargin=2*cm,
            leftMargin=2*cm,
            topMargin=2*cm,
            bottomMargin=2*cm
        )
        # 文档内容
        story = []
        # 添加标题
        title_style = self.styles['Title']
        story.append(Paragraph(f"<b>{self.title}</b>", title_style))
        story.append(Spacer(1, 12))
        # 添加时间
        from datetime import datetime
        time_style = self.styles['Normal']
        story.append(Paragraph(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", time_style))
        story.append(Spacer(1, 12))
        # 创建表格数据
        if data:
            # 表头
            headers = list(data[0].keys())
            table_data = [headers]
            # 添加数据行
            for item in data:
                row = [str(item.get(key, '')) for key in headers]
                table_data.append(row)
            # 创建表格
            table = Table(table_data)
            # 表格样式
            style = TableStyle([
                ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
                ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
                ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
                ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
                ('FONTSIZE', (0, 0), (-1, 0), 12),
                ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
                ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
                ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ])
            # 根据状态设置颜色
            if '状态' in headers:
                status_col = headers.index('状态')
                for i in range(1, len(table_data)):
                    if table_data[i][status_col] == '异常':
                        style.add('BACKGROUND', (status_col, i), (status_col, i), colors.red)
                        style.add('TEXTCOLOR', (status_col, i), (status_col, i), colors.white)
                    elif table_data[i][status_col] == '正常':
                        style.add('BACKGROUND', (status_col, i), (status_col, i), colors.green)
                        style.add('TEXTCOLOR', (status_col, i), (status_col, i), colors.white)
            table.setStyle(style)
            story.append(table)
        # 添加页脚
        story.append(Spacer(1, 20))
        footer_style = ParagraphStyle('Footer', parent=self.styles['Normal'], fontSize=8)
        story.append(Paragraph("报告自动生成,仅供参考", footer_style))
        # 生成PDF
        doc.build(story)
        print(f"PDF报表已生成: {output_path}")
        return output_path

3 HTML报表生成

class HTMLReportGenerator:
    def __init__(self, title="巡检报表"):
        self.title = title
    def generate_html_report(self, data, output_path):
        """
        生成HTML格式的巡检报表
        """
        # 创建HTML内容
        html_content = f"""
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">
            <title>{self.title}</title>
            <style>
                body {{
                    font-family: 'Microsoft YaHei', Arial, sans-serif;
                    margin: 20px;
                    background-color: #f5f5f5;
                }}
                .report-container {{
                    max-width: 1200px;
                    margin: 0 auto;
                    background-color: white;
                    padding: 20px;
                    border-radius: 10px;
                    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                }}
                .report-header {{
                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                    color: white;
                    padding: 20px;
                    border-radius: 8px;
                    margin-bottom: 20px;
                }}
                .report-title {{
                    font-size: 24px;
                    font-weight: bold;
                    margin: 0;
                }}
                .report-time {{
                    font-size: 12px;
                    margin-top: 10px;
                    opacity: 0.8;
                }}
                table {{
                    width: 100%;
                    border-collapse: collapse;
                    margin-top: 20px;
                }}
                th {{
                    background-color: #4CAF50;
                    color: white;
                    padding: 12px;
                    text-align: left;
                }}
                td {{
                    padding: 10px;
                    border-bottom: 1px solid #ddd;
                }}
                tr:hover {{
                    background-color: #f5f5f5;
                }}
                .status-normal {{
                    color: green;
                    font-weight: bold;
                }}
                .status-abnormal {{
                    color: red;
                    font-weight: bold;
                }}
                .summary-card {{
                    background-color: #e7f3fe;
                    border-left: 6px solid #2196F3;
                    margin: 20px 0;
                    padding: 15px;
                }}
                .footer {{
                    text-align: center;
                    margin-top: 30px;
                    padding: 10px;
                    color: #666;
                    font-size: 12px;
                }}
            </style>
        </head>
        <body>
            <div class="report-container">
                <div class="report-header">
                    <h1 class="report-title">{self.title}</h1>
                    <p class="report-time">生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
                </div>
        """
        # 添加统计信息
        if data:
            normal_count = sum(1 for item in data if item.get('状态') == '正常')
            abnormal_count = sum(1 for item in data if item.get('状态') == '异常')
            total_count = len(data)
            html_content += f"""
                <div class="summary-card">
                    <h3>统计概览</h3>
                    <p>总记录数: <strong>{total_count}</strong></p>
                    <p>正常: <strong style="color: green;">{normal_count}</strong></p>
                    <p>异常: <strong style="color: red;">{abnormal_count}</strong></p>
                </div>
            """
            # 添加表格
            html_content += """
                <table>
                    <thead>
                        <tr>
            """
            # 表头
            headers = list(data[0].keys())
            for header in headers:
                html_content += f"<th>{header}</th>"
            html_content += "</tr></thead><tbody>"
            # 数据
            for item in data:
                html_content += "<tr>"
                for key in headers:
                    value = item.get(key, '')
                    if key == '状态':
                        if value == '正常':
                            html_content += f'<td><span class="status-normal">✓ {value}</span></td>'
                        elif value == '异常':
                            html_content += f'<td><span class="status-abnormal">✗ {value}</span></td>'
                        else:
                            html_content += f"<td>{value}</td>"
                    else:
                        html_content += f"<td>{value}</td>"
                html_content += "</tr>"
            html_content += "</tbody></table>"
        # 添加页脚
        html_content += """
                <div class="footer">
                    <p>© 2024 巡检系统 - 自动生成报表</p>
                </div>
            </div>
        </body>
        </html>
        """
        # 写入文件
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(html_content)
        print(f"HTML报表已生成: {output_path}")
        return output_path

完整示例使用

# 示例数据
sample_data = [
    {
        '设备ID': 'EQ001',
        '设备名称': '服务器A',
        '位置': '机房1号',
        '状态': '正常',
        '温度': 25.3,
        '湿度': 45,
        '巡检时间': '2024-01-15 10:30:00',
        '巡检人员': '张三'
    },
    {
        '设备ID': 'EQ002',
        '设备名称': '服务器B',
        '位置': '机房2号',
        '状态': '异常',
        '温度': 35.8,
        '湿度': 60,
        '巡检时间': '2024-01-15 10:35:00',
        '巡检人员': '李四'
    },
    {
        '设备ID': 'EQ003',
        '设备名称': '交换机A',
        '位置': '机房1号',
        '状态': '正常',
        '温度': 22.1,
        '湿度': 40,
        '巡检时间': '2024-01-15 10:40:00',
        '巡检人员': '张三'
    }
]
def main():
    # 创建报表生成器
    excel_generator = InspectionReportGenerator("数据中心巡检报表")
    pdf_generator = PDFReportGenerator("数据中心巡检报表")
    html_generator = HTMLReportGenerator("数据中心巡检报表")
    # 生成不同格式的报表
    excel_generator.generate_excel_report(sample_data, "巡检报表.xlsx")
    # pdf_generator.generate_pdf_report(sample_data, "巡检报表.pdf")  # 需要安装reportlab
    html_generator.generate_html_report(sample_data, "巡检报表.html")
    print("所有报表生成完成!")
if __name__ == "__main__":
    main()

安装依赖

# 安装基础依赖
pip install pandas openpyxl numpy
# 安装PDF支持(可选)
pip install reportlab
# 安装HTML额外功能(可选)
pip install weasyprint jinja2

这个方案提供了完整的巡检报表生成框架,支持Excel、PDF和HTML三种格式,包含数据统计、状态标记和自定义样式等功能,你可以根据实际需求调整数据结构和样式。

抱歉,评论功能暂时关闭!