Newer
Older
safe-algo-pro / apis / data_gas.py
from io import BytesIO
from typing import Optional

import pandas as pd
from fastapi import APIRouter, Query, Depends
from sqlalchemy.ext.asyncio import AsyncSession

from starlette.responses import StreamingResponse

from apis.base import StandardResponse, PageResponse, convert_page_param, standard_response
from db.database import get_db
from entity.base import parse_datetime
from entity.data_gas import DataGas, DataGasInfo
from services.data_gas_service import DataGasService

router = APIRouter()


@router.get("/page", response_model=StandardResponse[PageResponse[DataGasInfo]])
async def get_gas_page(
        device_code: Optional[str] = None,
        start_time: Optional[str] = None,
        end_time: Optional[str] = None,
        offset: int = Query(0, ge=1),  # 从第几页开始

        limit: int = Query(10, ge=1),  # 每页显示多少条记录
        db: AsyncSession = Depends(get_db)):

    service = DataGasService(db)

    offset, limit = convert_page_param(offset, limit)
    data, total = await service.get_data_gas_page(device_code, parse_datetime(start_time), parse_datetime(end_time),
                                                  offset, limit)

    return standard_response(
        data=PageResponse(total=total, items=data)
    )


@router.get("/export")
async def export_data_gas(device_code: Optional[str] = None,
                          start_time: Optional[str] = None,
                          end_time: Optional[str] = None,
                          db: AsyncSession = Depends(get_db)):
    async with db:
        service = DataGasService(db)
        data = await  service.get_data_gas_list(device_code, start_time, end_time)

        # 将查询结果转换为 DataFrame
        data = [
            {"设备名称": item.device_name, "设备编号": item.device_code, "燃气浓度(ppm.m)": item.gas_value, "时间": item.ts}
            for item in data]
        df = pd.DataFrame(data)

        # 使用 BytesIO 生成内存中的 Excel 文件
        output = BytesIO()
        with pd.ExcelWriter(output, engine="openpyxl") as writer:
            df.to_excel(writer, index=False)

            # 获取工作表
            worksheet = writer.sheets["Sheet1"]

            # 设置固定的列宽,例如宽度为 20
            fixed_width = 30
            for col in worksheet.columns:
                col_letter = col[0].column_letter  # 获取列字母
                worksheet.column_dimensions[col_letter].width = fixed_width

        output.seek(0)

        # 返回内存中的 Excel 文件作为响应
        return StreamingResponse(
            output,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={"Content-Disposition": "attachment; filename=gas.xlsx"}
        )